Skip to content

Commit e446e4a

Browse files
committed
Add "bad idea" variant to parameter-modification
Courtesy of [this conversation in issue 4227][#4227 (comment)]
1 parent f2c4318 commit e446e4a

1 file changed

Lines changed: 41 additions & 0 deletions

File tree

  • exercises/practice/eliuds-eggs/.approaches/parameter-modification

exercises/practice/eliuds-eggs/.approaches/parameter-modification/content.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,9 +115,50 @@ As `display_value` is updated in the multiple assignment expression, we don't ne
115115
Just like the previous variations, the loop will continue until `display_value` reaches 0, and then we return `eggs`.
116116

117117

118+
## Variation #5: Overcomplicated One-Liner
119+
120+
~~~~exercism/caution
121+
This approach is not idiomatic and can be quite confusing.
122+
It is only provided here to show how one could apply various advanced techniques to turn this approach into a one-liner.
123+
~~~~
124+
125+
```python
126+
def egg_count(display_value):
127+
return sum(
128+
(value % 2, display_value := value // 2)[0]
129+
for value in iter(lambda: display_value, 0)
130+
)
131+
```
132+
133+
This variation uses [the `sum()` built-in][sum-built-in], a [generator expression][generator-expression], a [`lambda` expression][lambda-expression], and a [walrus operator (`:=`)][walrus-operator] to reduce the solution to a one-liner.
134+
The line is only broken up here for readability.
135+
136+
Here, the `while-loop` is converted into a generator expression, with `sum()` adding up the result of each iteration.
137+
As the `while` keyword is not allowed in generator expressions, instead we iterate over an iterable with `for`.
138+
This iterable is constructed from a `lambda` that returns `display_value`, with the [sentinel value][sentinel-value] set to `0`.
139+
This means that [`iter()`][iter-built-in] returns an iterable that calls the `lambda` until the returned `display_value` equals `0`.
140+
141+
For each iteration of the generator expression, we assign `value` to the return value of the `lambda`.
142+
Then we construct a `tuple` with two elements, using `[0]` to get its first element and feed it to `sum()`.
143+
That element is the least significant bit of `value`, which can be calculated via `value % 2` or `value & 1`, as shown in the previous variations.
144+
145+
The second element is more complicated.
146+
Here, we update `display_value`, cutting off the least significant bit (via `// 2` or `>> 1`) by using the walrus operator (`:=`).
147+
The walrus operator acts like a simple assignment statement, except that it returns the right-hand value and it can be used anywhere that an expression can be used.
148+
(See the [Python docs][assignment-expression-docs] for more details.)
149+
Thus we can use walrus operator here to update `display_value` in the generator expression, then simply ignore the return value by only feeding the first element of the `tuple` to `sum()`.
150+
151+
152+
[assignment-expression-docs]: https://docs.python.org/3/reference/expressions.html#assignment-expressions
118153
[bitwise-operators]: https://www.w3schools.com/programming/prog_operators_bitwise.php
119154
[concept-tuples]: https://exercism.org/tracks/python/concepts/tuples
120155
[concept-unpacking-and-multiple-assignment]: https://exercism.org/tracks/python/concepts/unpacking-and-multiple-assignment
121156
[divmod-built-in]: https://docs.python.org/3/library/functions.html#divmod
157+
[generator-expression]: https://dbader.org/blog/python-generator-expressions
158+
[iter-built-in]: https://docs.python.org/3/library/functions.html#iter
159+
[lambda-expression]: https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions
122160
[right-shift-operator]: https://www.geeksforgeeks.org/software-engineering/right-shift-operator-in-programming/
161+
[sentinel-value]: https://python-patterns.guide/python/sentinel-object/
123162
[sequence-count]: https://docs.python.org/3/library/stdtypes.html#sequence.count
163+
[sum-built-in]: https://docs.python.org/3/library/functions.html#sum
164+
[walrus-operator]: https://mathspp.com/blog/pydonts/assignment-expressions-and-the-walrus-operator

0 commit comments

Comments
 (0)