Expense Tracker Project · Exercises
Projects

Expense Tracker Project Exercises

4 exercises that build on the Python Expense Tracker Project lesson, from easy to hard. Each one is checked in your browser when you press Check. Stuck? Use the hint before peeking at the solution.

What this lesson covers: An expense tracker stores each purchase as a dictionary inside a list, adds new entries, totals the spending per category and saves everything to a file so the data survives between runs. By the end you can model records as a list of dictionaries, write functions to add and summarise expenses, save and load them with JSON, and print a tidy text report. You will practise: Predict the category totals; Validate new expenses; Fix the CSV loader; Report categories over budget.

0 / 4 completed

Expense Tracker Project practice exercises

1. Predict the category totals

Predict the output Easy

Read the code and type exactly what it prints.

Read this code
expenses = [
    {"category": "food", "amount": 4.5},
    {"category": "books", "amount": 12.0},
    {"category": "food", "amount": 3.0},
]
totals = {}
for e in expenses:
    totals[e["category"]] = totals.get(e["category"], 0) + e["amount"]
print(totals)
print(len(expenses), "expenses")
print(f"food: {totals['food']:.2f}")

2. Validate new expenses

Write code Medium

Make add_expense() safer. It should:

  • raise ValueError if amount is 0 or negative;
  • raise ValueError if category is empty or only spaces;
  • otherwise store the category stripped and in lower case (so " Food " is saved as "food") and append the expense.

Invalid expenses must not be added to the list.

Your code
def add_expense(expenses, date, category, amount):
    expenses.append({"date": date, "category": category, "amount": amount})

expenses = []
add_expense(expenses, "2024-05-01", " Food ", 12.5)
print(expenses)

3. Fix the CSV loader

Fix the bug Medium

The tracker can now save to CSV, but after loading, total_spent() crashes with TypeError: unsupported operand type(s) for +: 'int' and 'str'. CSV files store every value as text. Fix load_csv() so each loaded expense has its amount as a float again — total_spent() should not need to change.

Your code
import csv

def save_csv(expenses, path):
    with open(path, "w", newline="") as file:
        writer = csv.DictWriter(file, fieldnames=["date", "category", "amount"])
        writer.writeheader()
        writer.writerows(expenses)

def load_csv(path):
    with open(path, newline="") as file:
        return list(csv.DictReader(file))

def total_spent(expenses):
    return sum(row["amount"] for row in expenses)

expenses = [
    {"date": "2024-05-01", "category": "food", "amount": 12.5},
    {"date": "2024-05-02", "category": "fun", "amount": 15.0},
]
save_csv(expenses, "expenses.csv")
loaded = load_csv("expenses.csv")
print(total_spent(loaded))

4. Report categories over budget

Write code Hard

Add a budget report. Write over_budget(expenses, budgets), where budgets is a dict such as {"food": 50, "fun": 20}. Return a dict mapping each category whose total spending is more than its budget to how much it is over, rounded to 2 decimals. Ignore categories that have no budget.

Then print one line per category over budget, in the format fun: 5.50 over budget. You can use the provided totals_by_category().

Your code
def totals_by_category(expenses):
    totals = {}
    for row in expenses:
        totals[row["category"]] = totals.get(row["category"], 0) + row["amount"]
    return totals

def over_budget(expenses, budgets):
    # return {category: amount_over} for categories above their budget
    pass

expenses = [
    {"date": "2024-05-01", "category": "food", "amount": 32.40},
    {"date": "2024-05-03", "category": "fun", "amount": 18.00},
    {"date": "2024-05-06", "category": "food", "amount": 21.15},
    {"date": "2024-05-09", "category": "fun", "amount": 7.50},
    {"date": "2024-05-12", "category": "gifts", "amount": 40.00},
]
budgets = {"food": 50, "fun": 20, "transport": 30}

# print a warning line for each category that is over budget

More Python Expense Tracker Project examples · All Python exercises