Sixteen topics behind you. Reading them is not the same as being able to write them — so this page hands you one realistic problem that can only be solved by using most of the phase at once, and then actually runs your code and grades it. Real Python, right here in the browser. No multiple choice, nowhere to hide.
A service writes one line per event. At 2 a.m. it starts misbehaving, and you have a few thousand of these lines and a question: who is generating the errors? Each line looks like this — a timestamp, the user, a level, and then a free-text message that can be any number of words:
Your job is a small triage tool. Nothing here is hard on its own — the difficulty is that each piece wants a different tool from Phase 0, and picking the wrong one makes the code either wrong or ugly:
parse_line — split a line into its four parts. The message keeps its spaces, so a plain
.split() is not enough. Malformed lines must raise ValueError.parse_all — parse a whole file, quietly dropping the garbage lines. This is where the
exception you raised gets caught.error_counts — a dict of user → error count. Users with no errors must
not appear at all.top_users — the noisiest users, most errors first, ties broken alphabetically.
That tie-break is the whole point: it forces a real sort key.stream_levels — yield levels one at a time. It must be a generator, because a
real log file doesn't fit in memory.Report — a class where len() and repr() work, because objects
should behave like Python objects."t bob ERROR card was
declined".split() gives you five pieces, not four, and the count changes line to line. The fix is
the maxsplit argument — split(maxsplit=3) — which stops splitting once it has
the fields you actually named.
The grader runs your code, then runs seven checks against it with data you can't see — so hard-coding the sample above will fail. Each check tells you exactly what it expected and what it got. Getting all seven green marks Phase 0 ready ✓ on your roadmap.
Not that you memorised syntax — that you can pick the right tool under a little pressure.
maxsplit over naive splitting, an exception as a signal rather than a crash, a dict
as an accumulator, a sort key instead of hand-rolled comparison, yield when the data
is bigger than memory, and dunder methods so your class isn't a stranger to the language. That is Phase 0
working as a toolkit instead of sixteen isolated facts.