Back to Projects

Side Project · Personal Finance · Python

Personal Budget Optimizer

PythonStreamlitpandasPlotly
01

Motivation

Halfway through junior year, I realized I had genuinely no idea where my money was going. I had a part-time campus job, some freelance tutoring income, and a vague sense that I was “doing fine” financially. Then my checking account hit $47 two days before rent was due.

I tried Mint and YNAB but they felt overengineered for my situation. I wanted something dead simple: import my bank CSV, categorize spending, and tell me where I’m bleeding money. So I built it myself over a weekend with Streamlit.

The core idea is the 50/30/20 rule— 50% of after-tax income to needs, 30% to wants, 20% to savings. Not revolutionary, but actually seeing your numbers mapped against that target is surprisingly motivating.

02

Approach

The app is intentionally minimal. You upload a CSV bank statement (Chase, BofA, and Discover formats supported), and it auto-categorizes transactions using keyword matching on merchant names. Not fancy ML — just a dictionary of patterns like “DOORDASH” → Food Delivery, “SPOTIFY” → Subscription.

From there it calculates your actual 50/30/20 split, flags the biggest deltas between target and actual, and shows month-over-month trends. The whole thing is about 400 lines of Python.

Key features:

  • Auto-categorization with manual override for misclassified transactions
  • Monthly spending breakdown with Plotly sunburst and bar charts
  • Savings rate tracker with goal-setting (I set mine to 20%)
  • Subscription detector that flags recurring charges you might have forgotten about
03

Key Findings

After three months of tracking, the numbers told a pretty clear story.

CategoryBeforeAfterChangeNote
Rent & Utilities$1,080$1,080--Fixed cost
Food Delivery$420$140-67%Switched to meal prep
Subscriptions$185$45-76%Cancelled 9 unused services
Groceries$220$310+41%Cooking more at home
Transportation$95$85-11%More walking/biking
Shopping$280$150-46%30-day rule for non-essentials
Savings$190$520+174%Automated transfers

The biggest surprise was food delivery. I knew I was ordering a lot, but $420/month was genuinely shocking. That’s more than I was spending on groceries. I also found 9 subscriptions I’d completely forgotten about — including a language learning app I signed up for in freshman year and never opened again.

50/30/20 Allocation (After Optimization, $2,380/mo Income)

Needs (50%)
Target: $1,190Actual: $1,515Over by $325
Wants (30%)
Target: $714Actual: $375Under by $339
Savings (20%)
Target: $476Actual: $520On track
04

Limitations

Let me be upfront about what’s hacky here.

  • Categorization is keyword-based, not ML. It works for chains (Uber Eats, Target) but struggles with small local businesses or vague merchant names like “SQ *JOHN’S”. About 15% of transactions need manual reclassification.
  • No bank API integration. You have to manually download and upload CSV statements each month. I looked into Plaid but the cost didn’t make sense for a personal tool.
  • The 50/30/20 rule is a rough heuristic. It doesn’t account for student loan payments, irregular income, or living in a high-cost area. For a student in the Bay Area, 50% on “needs” is pretty tight.
  • Single-user, local only. No authentication, no cloud storage. Your data stays in a local SQLite file, which is a privacy feature but also means no access from your phone.
05

What I Learned

This was my first time building something purely for myself, and it taught me that the best data projects start with a real problem you actually have. I didn’t need a sophisticated model — I needed visibility.

On the technical side, Streamlit is incredible for prototyping. I went from zero to a working dashboard in about 6 hours. The tradeoff is that it’s hard to make it look polished — it always looks like a Streamlit app. But for a personal tool, that’s totally fine.

The biggest personal takeaway: tracking changes behavior. Just the act of seeing my food delivery spending in a bar chart next to my savings was enough to shift my habits. I didn’t need an algorithm to tell me to stop ordering DoorDash three times a week — I just needed to see the number.