← All posts

Building a Budget Tracker to Learn Where Simple Systems Get Interesting

2024Python · CLI

Money tracking sounds simple until you try to make even a basic system feel consistent. Inputs break. Data disappears if you do not persist it. Categories drift unless you constrain them. That tension made a budgeting CLI worth building.

This was an early project. I was not trying to build a serious finance product. I wanted to understand how a terminal application could hold state across sessions and whether a small tool could still feel structured.

Keeping the Core Small

The whole project lives in a small Python codebase, which forced decisions early. I used a BudgetTracker class to manage interaction and a Transaction model to keep the data simple. That separation mattered more than I expected.

One decision I liked was using positive values for income and negative values for expenses instead of separate fields. It reduced complexity and made net balance calculations almost trivial.

None of that is advanced, but each piece made the program feel less like an exercise and more like software.

Small Technical Details That Taught Me Something

One of the more interesting parts was serialization. Turning objects into dictionaries, writing them to disk, then reconstructing them on startup made persistence feel concrete. It stopped being abstract file I O and became application state.

I also started appreciating constraints. Predefined categories felt limiting, but they prevented messy user input. That tradeoff showed up everywhere. Flexibility often means more edge cases.

What Did Not Work Well

A lot is intentionally basic. Categories are hardcoded. Transactions cannot be edited or deleted. Dates are stored as strings, which would become a problem the second I wanted filtering or trend analysis.

If I rebuilt it, I would change the data model first. Proper date handling, custom categories, and transaction editing would matter more than adding more reports. I would probably also protect against JSON corruption instead of assuming the file is always valid.

At the time, I underestimated how quickly simple CRUD tools run into data integrity problems.

What This Project Represented

This was less about budgeting and more about learning how software holds together. Input validation, persistence, object design, and edge cases all showed up in 132 lines.

That was the real value. It was one of the first projects where code stopped feeling like isolated functions and started feeling like a system.

Small projects are where architecture starts.

View all projects →View on GitHub ↗