The project: CLI expense tracker
Build a command-line expense tracker in Python. This is deliberately a domain you understand well โ adding, viewing, and categorising expenses โ so your brain isn't split between "what am I building?" and "how do I code this?" All your mental energy goes into the engineering quality.
Requirements
- Add an expense:
tracker add --amount 12.50 --description "coffee" --category food - List expenses:
tracker list(all) ortracker list --category food - Summary:
tracker summaryโ total spent, breakdown by category - Delete:
tracker delete <id> - Persistence: data stored to a JSON file (no database needed yet)
Engineering requirements โ these are graded
- โ Type hints everywhere โ every function, every return type, every parameter
- โ
A
CategoryEnum โ no magic strings for categories - โ
Custom exceptions โ at least
ExpenseNotFoundErrorandValidationError - โ
A proper
Expenseclass with__repr__ - โ No bare excepts โ all error handling is explicit and logged
- โ Context managers for all file I/O
- โ Input validation โ amount must be positive, description can't be empty, category must be valid
- โ No hardcoded strings for categories or status values
- โ Pytest tests โ at least 10 test cases, including edge cases (empty list, invalid input, not-found)
- โ Git history โ at least 10 meaningful commits with good messages
- โ GitHub PR โ push to GitHub, open a PR from a feature branch
- โ
.gitignore โ no
__pycache__, no.venv, no.env
How to approach this week
Day 1: Design first. Write the data model (the Expense class, the Category Enum, the exceptions) on paper or in pseudocode. Map out the five commands and what each one does. Don't open a code editor yet.
Day 2โ3: Build the core โ the Expense class, storage (read/write JSON), and the add and list commands. Commit after each working piece.
Day 4: Add summary and delete. Write tests as you go โ before or alongside the implementation, not after.
Day 5: Clean up. Read through your own code with the A4 flaw checklist. Fix anything you find. Push to GitHub, open the PR, and say /learn A5 review in Cody.
What Cody will review
When you say /learn A5 review and share your GitHub repo link, Cody will review your PR as an adversarial reviewer โ playing the role of a senior engineer who is looking for problems, not looking to be nice. The review will cover:
- Every item in the engineering requirements checklist
- Any bugs found by reading the code (not running it)
- Code smells and design issues
- Test quality โ are the right things being tested? Are edge cases covered?
- Commit history quality
The goal isn't to make you feel bad โ it's to simulate what a real code review looks like. Once you've seen your own code reviewed at this standard, you'll know what to look for in others' code.
Grading yourself
After the review, assess yourself honestly:
- All engineering requirements met + <3 bugs found by Cody โ Phase A complete. Move to Phase B.
- Most requirements met + 3โ6 bugs โ Fix the bugs Cody found, understand each one, then move to Phase B.
- Major gaps in requirements โ Spend another week on the weak area (usually testing or error handling), then redo the capstone.
The capstone is not about the expense tracker being impressive. It's about whether you can write clean, safe, tested Python that you'd be willing to show in a job interview. That's the bar. If you can, you're genuinely ready for Phase B.