Level 1 / Project 14 - Basic Expense Tracker¶
Home: README
Learn Your Way¶
| Read | Build | Watch | Test | Review | Visualize | Try |
|---|---|---|---|---|---|---|
| Concept | This project | — | Quiz | Flashcards | — | Browser |
Estimated time: 40 minutes
Focus¶
- simple ledger aggregation and reporting
Why this project exists¶
Parse expense records from CSV, group them by category, compute totals and averages, and find the top spenders. You will learn CSV parsing, category aggregation, and sorting with lambda functions.
Run (copy/paste)¶
Use <repo-root> as the folder containing this repository's README.md.
cd <repo-root>/projects/level-1/14-basic-expense-tracker
python project.py --input data/sample_input.txt
pytest -q
Expected terminal output¶
=== Expense Report ===
Category Total Count Average
──────────── ───────── ────── ────────
Transport $35.00 1 $35.00
Food $12.50 1 $12.50
Grand total: $47.50
Top expense: Monthly bus pass ($35.00)
8 passed
Expected artifacts¶
data/output.json- Passing tests
- Updated
notes.md
Checkpoint: Baseline code runs and all tests pass. Commit your work before continuing.
Alter it (required) — Extension¶
- Add a
--categoryfilter flag that shows only expenses in a given category. - Add a monthly breakdown showing total spending per month.
- Re-run script and tests.
Break it (required) — Core¶
- Add a CSV row with a negative amount -- does
parse_expense()reject it? - Add a row with a missing category field -- does validation catch it?
- Use a file with no data rows (just headers) -- does
overall_stats()crash on empty data?
Fix it (required) — Core¶
- Ensure
parse_expense()rejects negative amounts with a clearValueError. - Handle the empty-expenses case in
overall_stats()by returning zero stats. - Add a test for the missing-field case.
Checkpoint: All modifications done, tests still pass. Good time to review your changes.
Explain it (teach-back)¶
- Why does
parse_expense()normalise categories to lowercase with.lower()? - What does
csv.DictReaderdo differently from reading lines and splitting on commas? - Why does
top_expenses()usesorted()withkey=lambdainstead of.sort()? - Where would expense tracking appear in real software (personal finance apps, accounting systems, budget reports)?
Mastery check¶
You can move on when you can: - run baseline without docs, - explain one core function line-by-line, - break and recover in one session, - keep tests passing after your change.
Related Concepts¶
| ← Prev | Home | Next → |
|---|---|---|