Exercises — Week 0 — Strong Python for AI Engineers¶
What you are building¶
A plan-level churn report with the standard library, a dataclass that round-trips to a JSON payload, a fit / predict class, and a fixed mutable-default foot-gun.
Predict before you run¶
- Which plan will have the highest churn rate, and why (lock-in, not morality)?
- Will
MeanBaseline().predict(1)return zeros or raise if you forgotfit? - After two
add_tagcalls with a mutable default, does the second user inherit the first tag?
Task¶
Work in starter.py. Run from the repo root:
1. Plan report. Using only csv + Counter, print churn rate per plan_type from subscriptions.csv.
2. Dataclass round-trip. Build a CustomerFeatures from a subscription row. Write to_payload(self) -> dict that a JSON API could accept.
3. MeanBaseline tests. assert that fit([2, 4, 6]).predict(2) returns [4.0, 4.0]. assert that predict before fit raises.
4. Foot-gun hunt. Deliberately write the mutable-default version of add_tag and show the second call is dirty. Then fix it.
Success criteria¶
- One churn rate per plan, denominators visible.
to_payload()is a dict of JSON-safe types.- Both MeanBaseline asserts pass.
- Buggy
add_tagis dirty; the fix is not.
Debugging clues¶
is_churnedin the CSV is"0"/"1"strings.predictbeforefitmust raise, not return[0].- If the second
add_tagalready containsvip, the default list is shared.
After you run¶
Python is glue. The dataclass is next week's row and Week 15's /predict body. A model that answers before fit is a handler that 200s an empty payload.