John: Week 4: Catch Up and Start Your Budget App
You want to build a serious budget tracker for Demo Day (April 29th). Right now your repo mostly has favs.py from Week 1. That is a normal starting point -- we just need project documentation for instructors, then a first Flask version of your app.
Important: A full budget product could include accounts, forecasting, and history. Your first Flask build is an MVP: add expenses and see a summary. It will look simpler than a fancy website on purpose. You are learning routes, forms, and Python lists. This guide uses Tailwind CSS via CDN so the UI still looks intentional. See Tailwind CSS.
Check In: What Are You Working On?
Create TODO.md if you need it. Write one rough sentence -- for example: "Document my budget app idea and build a first Flask MVP." You will replace this with a sharper goal at the end.
Part 1: Essential Project Catch-up
Add v0-prompt.md
Create v0-prompt.md and describe your budget app in plain language (no leftover brackets). Example structure:
You are my MVP build coach.
I am a high school student and a beginner programmer.
Use plain language. Define technical words in one sentence.
Project idea:
[Track spending, see totals, and eventually help me stay under a budget]
Target user:
[Me -- and anyone who wants a simple budget view]
Build me the smallest working MVP with only 3-5 must-have features.
Features:
1. [Add an expense with amount and category]
2. [See a list of expenses and a total]
Do not add extra features yet.
Add vibe-code-report.md
Use this outline (you do not have a v0 link yet -- that is OK):
# Vibe Code Report
## Prototype Link
**No v0 link yet** -- I am building my first version in Flask.
## What I Plan to Build First
- Project idea (1-2 sentences):
- Platform: Flask first
- MVP features (3-5 bullets):
## Reflection
- How do you feel about the direction so far?
- What would you change with more time?
- What would you keep the same?
## Known limitations
- [What is not built yet]
Commit Part 1
- Save all files
- Source Control -- message:
add v0 prompt and vibe code report for budget app - Commit, then Sync Changes
Optional (not required): Update favs.py to use f-strings with {artist} and {song} instead of hardcoded text in the prints -- good practice, but not required for your budget MVP. Optional: add warmup.py with a budget-themed formula.
Part 2: Build Budget Buddy in Flask
Flask connects URLs to Python functions. This MVP stores expenses in a Python list in memory (they reset when the server restarts -- that is fine for Week 4). Styling uses Tailwind. See Flask.
Step 1: Install Flask
Terminal (View > Terminal):
pip install flask
Use pip3 if needed.
Step 2: Create app.py
Create app.py and paste:
from flask import Flask, request
app = Flask(__name__)
expenses = []
@app.route("/")
def home():
return """
<html>
<head>
<meta charset="utf-8">
<title>Budget Buddy</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-slate-950 text-slate-100">
<div class="mx-auto max-w-2xl px-6 py-12">
<h1 class="text-3xl font-bold text-emerald-400">Budget Buddy</h1>
<p class="mt-3 text-slate-300">Track your spending. Know where your money goes.</p>
<div class="mt-8 flex flex-wrap gap-3">
<a class="rounded-lg bg-emerald-500 px-5 py-2 font-semibold text-slate-950 hover:bg-emerald-400" href="/add">Add Expense</a>
<a class="rounded-lg border border-emerald-500 px-5 py-2 font-semibold text-emerald-300 hover:bg-emerald-500/10" href="/summary">View Summary</a>
</div>
</div>
</body>
</html>
"""
@app.route("/add", methods=["GET", "POST"])
def add():
message = ""
if request.method == "POST":
description = request.form["description"]
amount = float(request.form["amount"])
category = request.form["category"]
expenses.append({
"description": description,
"amount": amount,
"category": category,
})
message = f'<p class="mb-4 rounded-lg bg-emerald-500/20 px-4 py-2 font-semibold text-emerald-300">Added: {description} (${amount:.2f})</p>'
return f"""
<html>
<head>
<meta charset="utf-8">
<title>Add Expense - Budget Buddy</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-slate-950 text-slate-100">
<div class="mx-auto max-w-2xl px-6 py-12">
<h1 class="text-2xl font-bold text-emerald-400">Add Expense</h1>
{message}
<form method="POST" class="mt-6 space-y-4 rounded-xl border border-slate-700 bg-slate-900/80 p-6">
<div>
<label class="block text-sm font-medium text-sky-300" for="description">What did you spend on?</label>
<input class="mt-1 w-full rounded-lg border border-slate-600 bg-slate-900 px-3 py-2 text-white placeholder-slate-500 focus:border-emerald-500 focus:outline-none" type="text" id="description" name="description" placeholder="e.g. Chipotle, gas, Netflix" required>
</div>
<div>
<label class="block text-sm font-medium text-sky-300" for="amount">How much? ($)</label>
<input class="mt-1 w-full rounded-lg border border-slate-600 bg-slate-900 px-3 py-2 text-white focus:border-emerald-500 focus:outline-none" type="number" id="amount" name="amount" step="0.01" min="0" placeholder="0.00" required>
</div>
<div>
<label class="block text-sm font-medium text-sky-300" for="category">Category</label>
<select class="mt-1 w-full rounded-lg border border-slate-600 bg-slate-900 px-3 py-2 text-white focus:border-emerald-500 focus:outline-none" id="category" name="category">
<option value="food">Food</option>
<option value="transport">Transport</option>
<option value="entertainment">Entertainment</option>
<option value="other">Other</option>
</select>
</div>
<button class="w-full rounded-lg bg-emerald-500 py-3 font-semibold text-slate-950 hover:bg-emerald-400" type="submit">Add Expense</button>
</form>
<p class="mt-8 text-sky-300"><a class="underline hover:text-white" href="/">Home</a> · <a class="underline hover:text-white" href="/summary">View Summary</a></p>
</div>
</body>
</html>
"""
@app.route("/summary")
def summary():
total = 0
rows = ""
for expense in expenses:
total = total + expense["amount"]
rows += f"""
<tr class="border-b border-slate-700">
<td class="px-4 py-3">{expense["description"]}</td>
<td class="px-4 py-3">${expense["amount"]:.2f}</td>
<td class="px-4 py-3 capitalize">{expense["category"]}</td>
</tr>
"""
if len(expenses) == 0:
rows = '<tr><td colspan="3" class="px-4 py-6 text-center text-slate-400">No expenses yet. <a class="text-sky-400 underline" href="/add">Add one.</a></td></tr>'
return f"""
<html>
<head>
<meta charset="utf-8">
<title>Summary - Budget Buddy</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="min-h-screen bg-slate-950 text-slate-100">
<div class="mx-auto max-w-3xl px-6 py-12">
<h1 class="text-2xl font-bold text-emerald-400">Spending Summary</h1>
<div class="mt-6 overflow-hidden rounded-xl border border-slate-700">
<table class="w-full border-collapse text-left text-sm">
<thead class="bg-slate-900 text-sky-300">
<tr>
<th class="px-4 py-3">Description</th>
<th class="px-4 py-3">Amount</th>
<th class="px-4 py-3">Category</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-700">
{rows}
</tbody>
</table>
</div>
<p class="mt-6 text-xl font-bold text-emerald-400">Total: ${total:.2f}</p>
<p class="mt-8 text-sky-300"><a class="underline hover:text-white" href="/add">Add Expense</a> · <a class="underline hover:text-white" href="/">Home</a></p>
</div>
</body>
</html>
"""
if __name__ == "__main__":
app.run(debug=True, host="0.0.0.0", port=5000)
Notes:
-
expensesis a list of dictionaries -- your app's memory for now. -
/addneedsmethods=["GET", "POST"]so the form can submit. -
Tailwind -- keep the script tag in every page
<head>.
Step 3: Run and test
- Save
app.py, click the play button - Open
http://localhost:5000(Codespaces: Ports tab)
Add a few expenses, then open View Summary.
Stop: terminal focus, Ctrl+C.
Step 4 (optional): Budget limit
Add a variable like budget_limit = 500 near expenses = [] and show remaining budget on the summary page using the total you already calculate.
Set Your Goal for Next Week
Open TODO.md and replace your rough line with one specific next step. Examples:
-
"Show remaining budget against a set limit on the summary page."
-
"Add a simple breakdown by category."
-
"Save expenses to a file so they survive a server restart."
Troubleshooting
"No module named flask"
pip install flask or pip3 install flask.
Form submits but summary is empty
Check expenses = [] is at the top of the file (not inside a function). Check /add includes methods=["GET", "POST"].
Page looks unstyled
Missing Tailwind <script> in <head>, or need to restart Flask and refresh.
"Address already in use"
Ctrl+C in the terminal, then run again.
Get Help From Your AI Agent
I'm building a budget tracker Flask app for Demo Day. This week I'm working on: [e.g. first run / form POST / summary total / Tailwind].
Here's my code:
[paste app.py or one function]Problem: [describe. Paste terminal errors].
Do not rewrite my whole project. Tell me what to check first, then small edits. Define new terms in one sentence.