Capstone Project 1: The Personal Finance Tracker

"The best time to start tracking your money was when you got your first paycheck. The second best time is now — and unlike the average budgeting app, you'll actually understand how yours works."

Project Overview

You've spent 27 chapters learning to think computationally, write clean Python, design objects, handle errors, test your code, and organize projects like a professional. Now it's time to put all of it together into a single application that does something genuinely useful: tracking your money.

The Personal Finance Tracker is a command-line application that lets users record income and expenses, assign transactions to categories, set monthly budgets, generate statistical reports, and export their data. It's the kind of tool that a working adult would actually use — and the kind of project that belongs in a portfolio.

This isn't a toy. You'll design a class hierarchy, persist data to disk between sessions, validate every piece of user input, write automated tests, and organize your code into modules. If you've been following the TaskFlow progressive project, you've already practiced each of these skills individually. The challenge here is combining them into a cohesive, polished application.

Why Personal Finance?

There's a pedagogical reason and a practical one.

The pedagogical reason: financial data is naturally structured. Every transaction has a date, an amount, a category, and a description. That maps directly to object attributes (Chapter 14). Transactions belong to months, months belong to years — that's composition (Chapter 16). You need to search, filter, sort, and aggregate — that's algorithms and data structures (Chapters 8, 9, 17, 19). You need to save and load — that's file I/O (Chapter 10). You need to handle malformed input — that's error handling (Chapter 11). The domain fits the curriculum like a glove.

The practical reason: understanding your money is a life skill, and building the tool that helps you do it teaches you something about both software and yourself.


Required Features

Your application must support the following features at minimum. Each feature maps to concepts from specific chapters — these aren't arbitrary requirements.

1. Transaction Management

  • Add transactions with the following fields: date, amount, category, description, and type (income or expense). (Chapters 3, 4, 14)
  • Edit existing transactions by selecting them from a list and modifying any field. (Chapters 5, 8)
  • Delete transactions with a confirmation prompt. (Chapters 4, 5)
  • View transactions filtered by date range, category, or type. Display them in a clean, formatted table. (Chapters 7, 8, 9)

2. Category System

  • Support predefined categories (e.g., Housing, Food, Transportation, Entertainment, Utilities, Healthcare, Savings, Income) stored in a configuration structure. (Chapter 9 — dictionaries)
  • Allow users to create custom categories at runtime. (Chapters 4, 9)
  • Categorize every transaction — reject uncategorized entries with a helpful error message. (Chapter 11)

3. Budget Tracking

  • Allow users to set monthly budgets per category (e.g., "Food: $400/month"). (Chapters 9, 14)
  • Track spending against budgets and display remaining amounts. (Chapters 5, 6)
  • Alert the user when spending in a category exceeds 80% of the budget and again when it exceeds 100%. (Chapter 4)

4. Monthly Reports with Statistics

  • Generate a monthly summary report showing:
  • Total income and total expenses for the month
  • Net savings (income minus expenses)
  • Spending breakdown by category (amount and percentage of total)
  • Highest single expense and highest single income transaction
  • Daily average spending
  • Calculate and display basic statistics: mean transaction amount, median transaction amount, and standard deviation of expenses. (Chapters 5, 6, 17 — you'll implement these calculations yourself, not use a library)
  • Display a text-based bar chart showing spending by category using characters like # or =. (Chapter 7 — string formatting)

5. Data Persistence (JSON)

  • Save all data (transactions, categories, budgets) to a JSON file automatically when the user exits. (Chapter 10)
  • Load data from the JSON file on startup, so the application remembers everything between sessions. (Chapter 10)
  • Handle the first-run case gracefully — if no data file exists, start with an empty state and inform the user. (Chapter 11)
  • Use pathlib.Path for all file path operations. (Chapter 10)

6. CSV Export

  • Export transactions to CSV for use in spreadsheet applications. (Chapter 10)
  • Allow the user to export all transactions or filtered subsets (by date range or category). (Chapters 5, 6)
  • Include a header row and properly escape any commas in description fields. (Chapter 7)

7. Input Validation and Error Handling

  • Validate all user input: dates must be real dates, amounts must be positive numbers, categories must exist. (Chapters 4, 11)
  • Use try/except blocks with specific exception types — never use bare except:. (Chapter 11)
  • Apply the EAFP principle where appropriate. (Chapter 11)
  • The application must never crash from user input. Every error should produce a helpful message and let the user try again. (Chapter 11)

8. Automated Testing

  • Write at least 15 unit tests using pytest covering:
  • Transaction creation and validation
  • Budget calculations (under budget, at threshold, over budget)
  • Report statistics (mean, median, standard deviation)
  • File I/O (save and load round-trip)
  • Edge cases (empty month, single transaction, negative amounts rejected)
  • Separate test files from source files. (Chapter 13)
  • Use fixtures for common test data. (Chapter 13)

Technical Requirements

These requirements ensure you're exercising the full range of skills from the course.

Requirement Relevant Chapters Details
Variables and expressions Ch 3 Amounts, dates, running totals
Conditionals Ch 4 Input validation, budget alerts, menu routing
Loops Ch 5 Menu loop, iteration over transactions, report generation
Functions Ch 6 At least 15 well-named functions with docstrings
Strings Ch 7 Formatted output, CSV escaping, report formatting
Lists and tuples Ch 8 Transaction collections, sorted results
Dictionaries Ch 9 Categories, budgets, monthly groupings
File I/O Ch 10 JSON persistence, CSV export, pathlib
Error handling Ch 11 Try/except throughout, custom exceptions
Modules Ch 12 Code split across at least 4 modules
Testing Ch 13 pytest suite with 15+ tests and fixtures
OOP Ch 14-16 Class hierarchy (see architecture below)

Suggested Architecture

You're free to design your own architecture, but here's a recommended structure that applies the principles from Chapters 12, 14, 15, and 16.

Module and Class Structure

finance_tracker/
    __init__.py
    models.py          # Transaction, Budget, Category classes
    storage.py          # DataStore class (JSON read/write)
    reports.py          # ReportGenerator class
    cli.py              # CommandLineInterface class (menus, input)
    validators.py       # Input validation functions
    main.py             # Entry point
tests/
    test_models.py
    test_storage.py
    test_reports.py
    test_validators.py
    conftest.py         # Shared fixtures

Core Classes

Transaction (Chapter 14) - Attributes: date (datetime.date), amount (float), category (str), description (str), transaction_type (str: "income" or "expense") - Methods: to_dict(), from_dict() (class method), __str__(), __repr__(), __eq__() - Validation in __init__: amount must be positive, type must be "income" or "expense"

Budget (Chapter 14) - Attributes: category (str), monthly_limit (float), spent (float) - Methods: remaining(), percentage_used(), is_over_budget(), is_near_limit(threshold=0.8), __str__() - Property: status returns "under", "warning", or "over"

ReportGenerator (Chapters 6, 14) - Methods: monthly_summary(transactions, month, year), category_breakdown(transactions), statistics(amounts), text_bar_chart(data), export_csv(transactions, filepath) - The statistics() method should calculate mean, median, and standard deviation manually (don't import statistics — implement the algorithms from Chapter 17)

DataStore (Chapters 10, 14) - Attributes: filepath (Path), transactions (list), budgets (dict), categories (list) - Methods: save(), load(), add_transaction(), delete_transaction(), get_transactions(filters), set_budget(), add_category() - Handles the first-run case: if the file doesn't exist, initialize with defaults

CommandLineInterface (Chapters 5, 6, 11) - The main menu loop and all user-facing I/O - Methods for each menu action: run(), menu_add_transaction(), menu_view_transactions(), menu_reports(), menu_budgets(), menu_export(), menu_settings() - All input validation happens here or delegates to validators.py

Design Principles (Chapter 16)

  • Separation of concerns: The CLI should never do calculations. The models should never print to the screen. The storage layer should never validate input.
  • Single Responsibility Principle: Each class has one job.
  • Encapsulation: Use @property for computed values like Budget.status.
  • Loose coupling: ReportGenerator receives transaction data as arguments — it doesn't reach into DataStore directly.

Development Milestones

Break this project into phases. Don't try to build everything at once — that's how projects stall. Each milestone produces a working (if incomplete) application.

Phase 1: Foundation (Days 1-3)

Goal: Add transactions and display them.

  • Create the Transaction class with __init__, __str__, and to_dict()
  • Write a simple menu loop (while loop with if/elif) that supports "add" and "view"
  • Store transactions in a list in memory (no file I/O yet)
  • Add basic input validation for amounts (must be a positive number)
  • Test: Write 3-4 tests for Transaction creation and validation

Checkpoint: You can add transactions and see them listed. The program forgets everything when you quit. That's fine for now.

Phase 2: Persistence and Categories (Days 4-6)

Goal: Save data to disk and organize transactions by category.

  • Create the DataStore class with save() and load() methods
  • Implement JSON serialization using Transaction.to_dict() and Transaction.from_dict()
  • Add the category system (predefined list + custom categories)
  • Add the Budget class
  • Handle the first-run case (no existing data file)
  • Test: Write tests for save/load round-trip, category validation, budget calculations

Checkpoint: You can quit the program, restart it, and your transactions are still there. This is the persistence threshold from Chapter 10 — it changes everything.

Phase 3: Reports and Statistics (Days 7-10)

Goal: Generate useful financial reports.

  • Create the ReportGenerator class
  • Implement monthly summary with all required statistics
  • Implement the text-based bar chart for category spending
  • Implement CSV export with proper formatting
  • Add date-range filtering to transaction views
  • Test: Write tests for statistics calculations (known inputs, known outputs), CSV formatting, edge cases (empty month)

Checkpoint: Your application now does something a spreadsheet can't do as easily: generate formatted, readable reports from the command line with a single command.

Phase 4: Polish and Robustness (Days 11-14)

Goal: Make it bulletproof and professional.

  • Audit every user input path for error handling — try to break your own program
  • Add budget alerts (80% warning, 100% exceeded)
  • Split code into modules if you haven't already (Chapter 12 principles)
  • Add docstrings to every class and public method
  • Expand test suite to 15+ tests including edge cases
  • Add a help command that explains available actions
  • Clean up display formatting — align columns, add separators, use color if you want

Checkpoint: Hand your program to a friend. If they can use it without reading your code and can't crash it no matter what they type, you're done.

Phase 5: Documentation and Submission (Days 15-16)

  • Write a README.md with installation instructions, usage examples, and architecture overview
  • Run your full test suite and fix any failures
  • Review your code against the rubric (see capstone-rubric.md)
  • Add comments where the logic is non-obvious (but don't over-comment — Chapter 6's guidance applies)

Stretch Goals

If you finish the required features and want to push further, here are extensions that exercise additional skills.

Matplotlib Charts (Extends Chapter 21)

Replace or supplement your text-based charts with actual matplotlib visualizations. Generate pie charts for category breakdowns, line graphs showing spending trends over time, and bar charts comparing budget vs. actual spending. Save charts as PNG files.

Multi-Currency Support (Extends Chapters 9, 14)

Add support for transactions in different currencies. Store an exchange rate table (dictionary) and convert all amounts to a base currency for reports. Allow the user to update exchange rates. This exercises dictionary design, floating-point arithmetic awareness (Chapter 3), and class design.

Budget Alerts with Trend Analysis (Extends Chapter 17)

Instead of just alerting when spending exceeds a threshold, analyze spending velocity. If the user has spent 60% of their food budget in the first 10 days of the month, project that they'll exceed it and warn them early. This exercises algorithmic thinking and introduces simple linear extrapolation.

Recurring Transactions (Extends Chapter 15)

Create a RecurringTransaction subclass that automatically generates transactions on a schedule (rent on the 1st, salary on the 15th). This exercises inheritance and the template method pattern from Chapter 15.

Command-Line Arguments (New skill)

Use Python's argparse module to support command-line usage like python main.py report --month 2026-03 or python main.py export --category Food. This is a professional skill that goes slightly beyond the course material.

Data Backup and Recovery (Extends Chapter 10)

Before every save, copy the existing data file to a backup with a timestamp. Implement a restore command that lets the user roll back to a previous backup. This exercises file operations and gives you a safety net during development.


What This Project Demonstrates

When you complete this capstone, you'll have demonstrated mastery of:

  • Computational thinking (Chapter 1): You decomposed a complex application into modules, classes, and functions
  • Core Python (Chapters 2-5): Variables, control flow, loops — the foundation of every feature
  • Functions as abstractions (Chapter 6): Your codebase is organized into small, testable, reusable functions
  • Data structures (Chapters 8-9): Lists of transactions, dictionaries for budgets and categories, tuples for immutable records
  • File I/O (Chapter 10): JSON persistence and CSV export — your program outlives its execution
  • Error handling (Chapter 11): Robust input validation using EAFP, specific exception types, and helpful error messages
  • Modules (Chapter 12): Code organized into logical files with clear responsibilities
  • Testing (Chapter 13): An automated test suite that catches regressions
  • OOP (Chapters 14-16): A class hierarchy with encapsulation, properties, and separation of concerns
  • Algorithm design (Chapter 17): Statistics calculations, filtering, and sorting implemented from scratch

This is a portfolio-quality project. It tells a potential employer or admissions committee: "I can design, build, test, and document a complete application." That's the whole point.


Getting Started

Don't stare at the full spec and feel overwhelmed — that's the decomposition lesson from Chapter 1 talking. Start with Phase 1. Write the Transaction class. Write one test. Make the test pass. Add a menu. Add another feature. Iterate.

If you get stuck:

  1. Re-read the relevant chapter. The section numbers are referenced throughout this spec.
  2. Look at your TaskFlow code. You've already solved many of these problems in a different context.
  3. Write a smaller version first. If the full report is intimidating, start by just printing total income and total expenses. Add statistics later.
  4. Test early, test often. A failing test tells you exactly where the bug is. A program that "doesn't work" tells you nothing.

Remember what Elena Vasquez learned in Chapter 13: the tests aren't extra work. They're the work that saves you from spending three hours debugging at 11 PM the night before the deadline.

Good luck. You're ready for this.


Assessment: See capstone-rubric.md for detailed grading criteria.