We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Getting Started with Tests and Type Checks step 11 of 13
Placement 4/6: Handle a Generator You Can Read Only Once
Solve this without the hints and you can skim the generators track.
A generator produces its values one at a time, as you ask for them, and
you can read it only once. After its last value it is exhausted, and any
later loop over it gets nothing. You can loop over a list as often as you
like. Iterable[int], the type for anything a for loop can go over, accepts
both.
squares = (n * n for n in [1, 2, 3])
print(sum(squares)) # 14
print(sum(squares)) # 0, because the generator is exhausted
The starter's summarise loops over rows four times, once to count, once to
sum and twice to filter. Given a generator, only the first loop sees any
values, so both result lists come back empty.
What to write
Fix summarise(rows: Iterable[int]) -> dict[str, list[int]]. It splits the
values around their mean, the sum divided by the count.
"above"holds the values strictly greater than the mean."at_or_below"holds every other value, including any equal to the mean.- Both lists keep duplicates and the input order.
- Empty input returns
{"above": [], "at_or_below": []}.
Read rows once into a tuple or a list, and use that copy for every pass.
The copy holds every value in memory, which is fine here because the input is
small and finite.
Don't compute the mean as a float. With total as the sum and count as the
number of values, test row * count > total instead of
row > total / count. The two tests agree because count is positive.
Integer arithmetic never rounds, so a value equal to the mean always goes in
"at_or_below".
The driver
Leave solve as it is. It passes summarise a generator of squares:
def solve(values: list[int]) -> dict[str, list[int]]:
return summarise(value * value for value in values)
So don't square the values again. For values = [1, 2, 3], the rows are 1, 4
and 9, their mean is about 4.67, and the result is
{"above": [9], "at_or_below": [1, 4]}.
Edge cases
- A single value equals the mean, so it goes in
"at_or_below". - If every value is the same,
"above"is empty. - Check for empty input after you copy the values. A generator object is
always truthy, even when it has no values left, so
if not rowscannot tell you it is empty.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Python reference solution
Sign in to track your attempts toward unlocking the reference solution.