Five lessons — f-strings, sales tax, multi-field rows, transaction dicts, and safe lookups. Which one clicked hardest for you?
The dict on Day 6. Once I saw three loose variables turn into one labeled object, it felt like the whole track got easier.
That shape — a dict with category, amount, date — is the atom the rest of the track builds on. Every loop, every filter, every report reads those three keys. Let's check what stuck.
Six questions?
Six. All drawn straight from this week's code. If something trips you up, the explainer below has the recap.
format_expense — f"{cat}: ${amount:.2f}" — :.2f always renders two decimalsapply_sales_tax — round(amount * (1 + rate), 2) — arithmetic first, round() at the boundaryformat_expense_row — one f-string with three placeholders; literal [ and ] stay as typedbuild_transaction — {"category": ..., "amount": ..., "date": ...} — the canonical dict shapeget_category_total — totals.get(cat, 0.0) — safe lookup with a sensible defaultFive shapes, one tracker.
Five lessons — f-strings, sales tax, multi-field rows, transaction dicts, and safe lookups. Which one clicked hardest for you?
The dict on Day 6. Once I saw three loose variables turn into one labeled object, it felt like the whole track got easier.
That shape — a dict with category, amount, date — is the atom the rest of the track builds on. Every loop, every filter, every report reads those three keys. Let's check what stuck.
Six questions?
Six. All drawn straight from this week's code. If something trips you up, the explainer below has the recap.
format_expense — f"{cat}: ${amount:.2f}" — :.2f always renders two decimalsapply_sales_tax — round(amount * (1 + rate), 2) — arithmetic first, round() at the boundaryformat_expense_row — one f-string with three placeholders; literal [ and ] stay as typedbuild_transaction — {"category": ..., "amount": ..., "date": ...} — the canonical dict shapeget_category_total — totals.get(cat, 0.0) — safe lookup with a sensible defaultFive shapes, one tracker.