Skip to content

Repository files navigation

JSON Expense Ledger

Time-box: 75–90 minutes
Milestone: add and summarise validated expense records, then round-trip them through a UTF-8 JSON file without hiding missing or malformed data.

Companion learning path: Python From First Principles. If Python or Git is not ready yet, use the free installation guide.

Start your own copy

On GitHub, select Use this templateCreate a new repository, then clone your new repository and work in that copy. The starting red checks are intentional; your goal is to turn them green and complete the two human-review gates in MASTERY.md.

Each expense has this shape:

{"description": "Bus fare", "amount_cents": 18_500, "category": "transport"}

The amount is whole cents. add_expense returns a new list so the caller controls when new state replaces old state.

Start here

python3 -B -I tests/run_tests.py

The untouched starter has exactly four intentional test_todo_... failures. Missing files, invalid JSON, wrong JSON shapes, and bad new values are already checked. Finish load_expenses, save_expenses, add_expense, and totals_by_category in expense_ledger.py.

The tests use temporary directories and will not touch a real ledger. Your manual checks use a path you choose.

Behaviour contract

  • A missing file loads as an empty ledger.
  • Malformed JSON, invalid UTF-8, and a non-list JSON root raise LedgerError with distinct messages.
  • Every loaded or saved record is validated.
  • Saving rejects unsupported record fields, serialises before touching the destination, then replaces it with a complete indented UTF-8 file ending in a newline.
  • New descriptions are stripped; new categories are stripped and case-folded.
  • Amounts must be positive whole cents; booleans are rejected.
  • Category totals are returned in a dictionary.
  • No function catches a broad Exception or silently replaces malformed data.

Finish with MASTERY.md.

Get your automatic project grade

  1. Create your own copy from this template.

  2. Read MASTERY.md, then create an attempt branch:

    git switch -c attempt/my-project
  3. Build the project and run the same check GitHub uses:

    python3 -B -I tests/run_tests.py
  4. Commit and push the attempt branch:

    git add .
    git commit -m "Complete project attempt"
    git push -u origin attempt/my-project

GitHub Actions grades every pushed attempt automatically. PASS — NAILED IT means every required check passed. REVISE — KEEP BUILDING means the run shows what to fix before you push again. You do not need the KODE Ń VIBE owner to review or start anything; the template's main branch stays quiet on purpose.

The free grading guide explains the result and its limits.

About

Build and verify a safe JSON expense ledger with beginner Python.

Topics

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages