Skip to main content

šŸš€ Lesson 10: Putting It All Together — Your Journey Forward

You've learned the fundamental building blocks of programming! Now let's combine everything into a real project and map out where to go next.

šŸŽÆ Learning Objectives

By the end of this lesson, you will be able to:

  • Combine variables, control flow, data structures, and functions into a complete program
  • Build a Personal Finance Tracker from scratch using milestone-driven development
  • Evaluate your own code quality using a self-assessment rubric
  • Identify next steps for continued learning

Estimated Time: 60–90 minutes

Project: Personal Finance Tracker (capstone)

In This Lesson

šŸŽ‰ Your Programming Toolkit

Congratulations! Let's take a moment to appreciate everything you can now do. Each lesson gave you a powerful tool, and together they form a complete programming toolkit.

🧰 Your Programming Toolkit šŸ“¦ Variables Store data šŸ’¬ Input/Output Interact šŸ”€ Decisions If/Else logic šŸ” Loops Repeat tasks šŸ“‹ Lists Ordered data šŸ·ļø Dictionaries Labeled data 🧩 Functions Reusable code šŸ—ļø Projects Build things! šŸš€ Capstone Project

šŸ’° Capstone: Personal Finance Tracker

Let's build something real using everything you've learned! This project combines variables, input/output, if-statements, loops, lists, dictionaries, functions, JSON, and more into one cohesive application.

šŸ“– What We're Building

A command-line finance tracker that lets you add income and expenses, view your balance, generate monthly reports with percentage breakdowns, and save/load data to JSON files.

šŸ—ŗļø Project Milestones

We'll build this step by step. Each milestone adds a working layer to the project.

graph TD A["🧱 Milestone 1: Core Data Structure"] --> B["āš™ļø Milestone 2: Basic Operations"] B --> C["šŸ–„ļø Milestone 3: User Interface"] C --> D["šŸ’¾ Milestone 4: Data Persistence"] D --> E["šŸ“Š Milestone 5: Analysis & Reports"] E --> F["āœ… Milestone 6: Polish & Testing"] F --> G["šŸ† Complete Project!"]

Milestone 1 — Core Data Structure

Set up the data containers and categories that the whole app revolves around.

import datetime
from collections import defaultdict, Counter
import json

# Global data storage
transactions = []
categories = {
    "income": ["Salary", "Freelance", "Investment", "Other Income"],
    "expense": ["Food", "Transport", "Entertainment", "Bills",
                "Shopping", "Health", "Education", "Other"]
}

# Statistics tracking
monthly_totals = defaultdict(lambda: {"income": 0, "expense": 0})
category_spending = Counter()

Milestone 2 — Basic Operations

Create functions to add transactions and track them.

def create_transaction(amount, trans_type, category, description=""):
    """Create a new transaction dictionary."""
    return {
        "id": len(transactions) + 1,
        "date": datetime.date.today().isoformat(),
        "type": trans_type,
        "amount": amount,
        "category": category,
        "description": description
    }

def add_transaction(trans_type):
    """Add a new income or expense transaction."""
    print(f"\n=== Add {trans_type.capitalize()} ===")

    # Get amount with validation
    while True:
        try:
            amount = float(input(f"Enter {trans_type} amount: $"))
            if amount <= 0:
                print("Amount must be positive!")
                continue
            break
        except ValueError:
            print("Please enter a valid number!")

    # Show categories
    print(f"\nAvailable categories for {trans_type}:")
    for i, cat in enumerate(categories[trans_type], 1):
        print(f"{i}. {cat}")

    # Get category selection
    while True:
        try:
            choice = int(input("Select category (number): "))
            if 1 <= choice <= len(categories[trans_type]):
                category = categories[trans_type][choice - 1]
                break
            print("Invalid choice!")
        except ValueError:
            print("Please enter a number!")

    description = input("Description (optional): ")

    transaction = create_transaction(amount, trans_type, category, description)
    transactions.append(transaction)

    # Update statistics
    month_key = transaction["date"][:7]
    monthly_totals[month_key][trans_type] += amount
    if trans_type == "expense":
        category_spending[category] += amount

    print(f"āœ“ {trans_type.capitalize()} added successfully!")
    return transaction

Milestone 3 — User Interface

Add the menu system and display functions.

def view_transactions(limit=10):
    """Display recent transactions."""
    if not transactions:
        print("\nšŸ“­ No transactions yet!")
        return

    print(f"\n=== Recent Transactions (Last {limit}) ===")
    print("-" * 60)

    sorted_trans = sorted(transactions,
                         key=lambda x: x["date"],
                         reverse=True)[:limit]

    for trans in sorted_trans:
        symbol = "+" if trans["type"] == "income" else "-"
        print(f"{trans['date']} | {trans['category']:<15} | "
              f"{symbol}${trans['amount']:>8.2f}")
        if trans['description']:
            print(f"    └─ {trans['description']}")
    print("-" * 60)

def view_balance():
    """Display current financial status."""
    income = sum(t["amount"] for t in transactions if t["type"] == "income")
    expenses = sum(t["amount"] for t in transactions if t["type"] == "expense")
    balance = income - expenses

    print("\n" + "=" * 50)
    print("šŸ’¼ FINANCIAL SUMMARY".center(50))
    print("=" * 50)
    print(f"šŸ“ˆ Total Income:    ${income:>10,.2f}")
    print(f"šŸ“‰ Total Expenses:  ${expenses:>10,.2f}")
    print("-" * 50)
    print(f"šŸ’° Current Balance: ${balance:>10,.2f}")

    if balance > 1000:
        print("\n🌟 Excellent! You're building wealth!")
    elif balance > 0:
        print("\nāœ… Good job! You're in the green!")
    elif balance == 0:
        print("\nāš–ļø  You're breaking even.")
    else:
        print("\nāš ļø  Warning: You're in the red. Time to budget!")
    print("=" * 50)

def display_menu():
    """Display the main menu."""
    print("\n" + "=" * 50)
    print("šŸ’° PERSONAL FINANCE TRACKER šŸ’°".center(50))
    print("=" * 50)
    print("1. šŸ“ˆ Add Income")
    print("2. šŸ“‰ Add Expense")
    print("3. šŸ“Š View Balance")
    print("4. šŸ“œ View Transactions")
    print("5. šŸ“Š Monthly Report")
    print("6. šŸ’¾ Save Data")
    print("7. šŸ“‚ Load Data")
    print("0. 🚪 Exit")
    print("-" * 50)

Milestone 4 — Data Persistence

Save and load data with JSON so nothing is lost between sessions.

def save_data(filename="finance_data.json"):
    """Save all data to JSON file."""
    try:
        data = {
            "transactions": transactions,
            "categories": categories,
            "monthly_totals": dict(monthly_totals),
            "category_spending": dict(category_spending),
            "last_saved": datetime.datetime.now().isoformat()
        }
        with open(filename, "w") as file:
            json.dump(data, file, indent=2)
        print(f"āœ“ Data saved to {filename}")
        return True
    except Exception as e:
        print(f"āŒ Error saving data: {e}")
        return False

def load_data(filename="finance_data.json"):
    """Load data from JSON file."""
    global transactions, categories, monthly_totals, category_spending
    try:
        with open(filename, "r") as file:
            data = json.load(file)
        transactions = data.get("transactions", [])
        categories = data.get("categories", categories)
        monthly_totals = defaultdict(lambda: {"income": 0, "expense": 0},
                                    data.get("monthly_totals", {}))
        category_spending = Counter(data.get("category_spending", {}))
        print(f"āœ“ Data loaded from {filename}")
        print(f"  Transactions: {len(transactions)}")
        return True
    except FileNotFoundError:
        print(f"šŸ“ No save file found. Starting fresh!")
        return False
    except Exception as e:
        print(f"āŒ Error loading data: {e}")
        return False

Milestone 5 — Analysis & Reports

Generate detailed monthly reports with category breakdowns and savings rate.

def monthly_report():
    """Generate detailed monthly report."""
    if not transactions:
        print("\nšŸ“­ No data for report!")
        return

    current_month = datetime.date.today().strftime("%Y-%m")
    month = input(f"\nEnter month (YYYY-MM) or Enter for current [{current_month}]: ")
    if not month:
        month = current_month

    month_trans = [t for t in transactions if t["date"].startswith(month)]
    if not month_trans:
        print(f"\nšŸ“­ No transactions for {month}")
        return

    print(f"\n{'=' * 60}")
    print(f"šŸ“Š MONTHLY REPORT FOR {month}".center(60))
    print(f"{'=' * 60}")

    month_income = sum(t["amount"] for t in month_trans if t["type"] == "income")
    month_expenses = sum(t["amount"] for t in month_trans if t["type"] == "expense")

    # Income breakdown
    print("\nšŸ“ˆ INCOME BREAKDOWN:")
    income_by_cat = defaultdict(float)
    for t in month_trans:
        if t["type"] == "income":
            income_by_cat[t["category"]] += t["amount"]
    for cat, amount in sorted(income_by_cat.items(), key=lambda x: x[1], reverse=True):
        pct = (amount / month_income * 100) if month_income > 0 else 0
        bar = "ā–ˆ" * int(pct / 5)
        print(f"  {cat:<15} ${amount:>8.2f} ({pct:>5.1f}%) {bar}")
    print(f"  {'TOTAL':<15} ${month_income:>8.2f}")

    # Expense breakdown
    print("\nšŸ“‰ EXPENSE BREAKDOWN:")
    expense_by_cat = defaultdict(float)
    for t in month_trans:
        if t["type"] == "expense":
            expense_by_cat[t["category"]] += t["amount"]
    for cat, amount in sorted(expense_by_cat.items(), key=lambda x: x[1], reverse=True):
        pct = (amount / month_expenses * 100) if month_expenses > 0 else 0
        bar = "ā–ˆ" * int(pct / 5)
        print(f"  {cat:<15} ${amount:>8.2f} ({pct:>5.1f}%) {bar}")
    print(f"  {'TOTAL':<15} ${month_expenses:>8.2f}")

    month_balance = month_income - month_expenses
    savings_rate = ((month_income - month_expenses) / month_income * 100) if month_income > 0 else 0
    print(f"\n{'=' * 60}")
    print(f"šŸ’° MONTHLY BALANCE: ${month_balance:>10.2f}")
    print(f"šŸ’µ SAVINGS RATE:    {savings_rate:>10.1f}%")

    print(f"\nšŸ’” INSIGHTS:")
    if savings_rate >= 20:
        print("  āœ… Excellent savings rate! Keep it up!")
    elif savings_rate >= 10:
        print("  šŸ‘ Good savings rate. Try to reach 20%!")
    elif savings_rate >= 0:
        print("  āš ļø  Low savings rate. Consider reducing expenses.")
    else:
        print("  🚨 Negative savings! Review your spending immediately.")
    print(f"{'=' * 60}")

Milestone 6 — Polish & Main Loop

Wire everything together with the main program loop and error handling.

def main():
    """Main program loop."""
    print("\n" + "🌟" * 25)
    print("Welcome to Personal Finance Tracker!")
    print("🌟" * 25)

    load_data()

    while True:
        try:
            display_menu()
            choice = input("Enter your choice (0-7): ")

            if choice == "1":
                add_transaction("income")
            elif choice == "2":
                add_transaction("expense")
            elif choice == "3":
                view_balance()
            elif choice == "4":
                limit = input("How many transactions? (default 10): ")
                limit = int(limit) if limit else 10
                view_transactions(limit)
            elif choice == "5":
                monthly_report()
            elif choice == "6":
                save_data()
            elif choice == "7":
                filename = input("Enter filename (or Enter for default): ")
                load_data(filename if filename else "finance_data.json")
            elif choice == "0":
                if transactions and input("\nšŸ’¾ Save before exit? (y/n): ").lower() == 'y':
                    save_data()
                print("\nšŸ‘‹ Thank you for using Finance Tracker!")
                print("šŸ’° Remember: Every penny saved is a penny earned!")
                break
            else:
                print("Invalid choice! Please try again.")

            if choice != "0":
                input("\nPress Enter to continue...")

        except KeyboardInterrupt:
            print("\n\nāš ļø  Program interrupted!")
            if transactions and input("Save data? (y/n): ").lower() == 'y':
                save_data()
            break
        except Exception as e:
            print(f"\nāŒ An error occurred: {e}")
            print("Please try again.")

if __name__ == "__main__":
    main()

šŸ“„ Complete Project Code

Here's the entire project in one place. You can copy this and run it, or build it milestone by milestone.

šŸ“œ View Complete Project Code
# Personal Finance Tracker — Complete Version
# Uses all concepts from Lessons 1–9

import datetime
from collections import defaultdict, Counter
import json

# Global data storage
transactions = []
categories = {
    "income": ["Salary", "Freelance", "Investment", "Other Income"],
    "expense": ["Food", "Transport", "Entertainment", "Bills",
                "Shopping", "Health", "Education", "Other"]
}
monthly_totals = defaultdict(lambda: {"income": 0, "expense": 0})
category_spending = Counter()


def create_transaction(amount, trans_type, category, description=""):
    """Create a new transaction dictionary."""
    return {
        "id": len(transactions) + 1,
        "date": datetime.date.today().isoformat(),
        "type": trans_type,
        "amount": amount,
        "category": category,
        "description": description
    }


def add_transaction(trans_type):
    """Add a new income or expense transaction."""
    print(f"\n=== Add {trans_type.capitalize()} ===")
    while True:
        try:
            amount = float(input(f"Enter {trans_type} amount: $"))
            if amount <= 0:
                print("Amount must be positive!")
                continue
            break
        except ValueError:
            print("Please enter a valid number!")

    print(f"\nAvailable categories for {trans_type}:")
    for i, cat in enumerate(categories[trans_type], 1):
        print(f"{i}. {cat}")

    while True:
        try:
            choice = int(input("Select category (number): "))
            if 1 <= choice <= len(categories[trans_type]):
                category = categories[trans_type][choice - 1]
                break
            print("Invalid choice!")
        except ValueError:
            print("Please enter a number!")

    description = input("Description (optional): ")
    transaction = create_transaction(amount, trans_type, category, description)
    transactions.append(transaction)

    month_key = transaction["date"][:7]
    monthly_totals[month_key][trans_type] += amount
    if trans_type == "expense":
        category_spending[category] += amount

    print(f"āœ“ {trans_type.capitalize()} added successfully!")
    return transaction


def view_transactions(limit=10):
    """Display recent transactions."""
    if not transactions:
        print("\nšŸ“­ No transactions yet!")
        return
    print(f"\n=== Recent Transactions (Last {limit}) ===")
    print("-" * 60)
    sorted_trans = sorted(transactions, key=lambda x: x["date"], reverse=True)[:limit]
    for trans in sorted_trans:
        symbol = "+" if trans["type"] == "income" else "-"
        print(f"{trans['date']} | {trans['category']:<15} | {symbol}${trans['amount']:>8.2f}")
        if trans['description']:
            print(f"    └─ {trans['description']}")
    print("-" * 60)


def view_balance():
    """Display current financial status."""
    income = sum(t["amount"] for t in transactions if t["type"] == "income")
    expenses = sum(t["amount"] for t in transactions if t["type"] == "expense")
    balance = income - expenses
    print("\n" + "=" * 50)
    print("šŸ’¼ FINANCIAL SUMMARY".center(50))
    print("=" * 50)
    print(f"šŸ“ˆ Total Income:    ${income:>10,.2f}")
    print(f"šŸ“‰ Total Expenses:  ${expenses:>10,.2f}")
    print("-" * 50)
    print(f"šŸ’° Current Balance: ${balance:>10,.2f}")
    if balance > 1000:
        print("\n🌟 Excellent! You're building wealth!")
    elif balance > 0:
        print("\nāœ… Good job! You're in the green!")
    elif balance == 0:
        print("\nāš–ļø  You're breaking even.")
    else:
        print("\nāš ļø  Warning: You're in the red. Time to budget!")
    print("=" * 50)


def monthly_report():
    """Generate detailed monthly report."""
    if not transactions:
        print("\nšŸ“­ No data for report!")
        return
    current_month = datetime.date.today().strftime("%Y-%m")
    month = input(f"\nEnter month (YYYY-MM) or Enter for current [{current_month}]: ")
    if not month:
        month = current_month
    month_trans = [t for t in transactions if t["date"].startswith(month)]
    if not month_trans:
        print(f"\nšŸ“­ No transactions for {month}")
        return

    print(f"\n{'=' * 60}")
    print(f"šŸ“Š MONTHLY REPORT FOR {month}".center(60))
    print(f"{'=' * 60}")
    month_income = sum(t["amount"] for t in month_trans if t["type"] == "income")
    month_expenses = sum(t["amount"] for t in month_trans if t["type"] == "expense")

    print("\nšŸ“ˆ INCOME BREAKDOWN:")
    income_by_cat = defaultdict(float)
    for t in month_trans:
        if t["type"] == "income":
            income_by_cat[t["category"]] += t["amount"]
    for cat, amount in sorted(income_by_cat.items(), key=lambda x: x[1], reverse=True):
        pct = (amount / month_income * 100) if month_income > 0 else 0
        bar = "ā–ˆ" * int(pct / 5)
        print(f"  {cat:<15} ${amount:>8.2f} ({pct:>5.1f}%) {bar}")
    print(f"  {'TOTAL':<15} ${month_income:>8.2f}")

    print("\nšŸ“‰ EXPENSE BREAKDOWN:")
    expense_by_cat = defaultdict(float)
    for t in month_trans:
        if t["type"] == "expense":
            expense_by_cat[t["category"]] += t["amount"]
    for cat, amount in sorted(expense_by_cat.items(), key=lambda x: x[1], reverse=True):
        pct = (amount / month_expenses * 100) if month_expenses > 0 else 0
        bar = "ā–ˆ" * int(pct / 5)
        print(f"  {cat:<15} ${amount:>8.2f} ({pct:>5.1f}%) {bar}")
    print(f"  {'TOTAL':<15} ${month_expenses:>8.2f}")

    month_balance = month_income - month_expenses
    savings_rate = ((month_income - month_expenses) / month_income * 100) if month_income > 0 else 0
    print(f"\n{'=' * 60}")
    print(f"šŸ’° MONTHLY BALANCE: ${month_balance:>10.2f}")
    print(f"šŸ’µ SAVINGS RATE:    {savings_rate:>10.1f}%")
    print(f"\nšŸ’” INSIGHTS:")
    if savings_rate >= 20:
        print("  āœ… Excellent savings rate! Keep it up!")
    elif savings_rate >= 10:
        print("  šŸ‘ Good savings rate. Try to reach 20%!")
    elif savings_rate >= 0:
        print("  āš ļø  Low savings rate. Consider reducing expenses.")
    else:
        print("  🚨 Negative savings! Review your spending immediately.")
    print(f"{'=' * 60}")


def save_data(filename="finance_data.json"):
    """Save all data to JSON file."""
    try:
        data = {
            "transactions": transactions,
            "categories": categories,
            "monthly_totals": dict(monthly_totals),
            "category_spending": dict(category_spending),
            "last_saved": datetime.datetime.now().isoformat()
        }
        with open(filename, "w") as file:
            json.dump(data, file, indent=2)
        print(f"āœ“ Data saved to {filename}")
        return True
    except Exception as e:
        print(f"āŒ Error saving data: {e}")
        return False


def load_data(filename="finance_data.json"):
    """Load data from JSON file."""
    global transactions, categories, monthly_totals, category_spending
    try:
        with open(filename, "r") as file:
            data = json.load(file)
        transactions = data.get("transactions", [])
        categories = data.get("categories", categories)
        monthly_totals = defaultdict(lambda: {"income": 0, "expense": 0},
                                    data.get("monthly_totals", {}))
        category_spending = Counter(data.get("category_spending", {}))
        print(f"āœ“ Data loaded from {filename}")
        print(f"  Transactions: {len(transactions)}")
        return True
    except FileNotFoundError:
        print("šŸ“ No save file found. Starting fresh!")
        return False
    except Exception as e:
        print(f"āŒ Error loading data: {e}")
        return False


def display_menu():
    """Display the main menu."""
    print("\n" + "=" * 50)
    print("šŸ’° PERSONAL FINANCE TRACKER šŸ’°".center(50))
    print("=" * 50)
    print("1. šŸ“ˆ Add Income")
    print("2. šŸ“‰ Add Expense")
    print("3. šŸ“Š View Balance")
    print("4. šŸ“œ View Transactions")
    print("5. šŸ“Š Monthly Report")
    print("6. šŸ’¾ Save Data")
    print("7. šŸ“‚ Load Data")
    print("0. 🚪 Exit")
    print("-" * 50)


def main():
    """Main program loop."""
    print("\n" + "🌟" * 25)
    print("Welcome to Personal Finance Tracker!")
    print("🌟" * 25)
    load_data()
    while True:
        try:
            display_menu()
            choice = input("Enter your choice (0-7): ")
            if choice == "1":
                add_transaction("income")
            elif choice == "2":
                add_transaction("expense")
            elif choice == "3":
                view_balance()
            elif choice == "4":
                limit = input("How many transactions? (default 10): ")
                limit = int(limit) if limit else 10
                view_transactions(limit)
            elif choice == "5":
                monthly_report()
            elif choice == "6":
                save_data()
            elif choice == "7":
                filename = input("Enter filename (or Enter for default): ")
                load_data(filename if filename else "finance_data.json")
            elif choice == "0":
                if transactions and input("\nšŸ’¾ Save before exit? (y/n): ").lower() == 'y':
                    save_data()
                print("\nšŸ‘‹ Thank you for using Finance Tracker!")
                print("šŸ’° Remember: Every penny saved is a penny earned!")
                break
            else:
                print("Invalid choice! Please try again.")
            if choice != "0":
                input("\nPress Enter to continue...")
        except KeyboardInterrupt:
            print("\n\nāš ļø  Program interrupted!")
            if transactions and input("Save data? (y/n): ").lower() == 'y':
                save_data()
            break
        except Exception as e:
            print(f"\nāŒ An error occurred: {e}")
            print("Please try again.")


if __name__ == "__main__":
    main()

šŸ“‹ Self-Assessment Rubric

Use this rubric to evaluate your own project. Be honest — it's how you grow!

Criteria Excellent (4) Good (3) Satisfactory (2) Needs Work (1)
Functionality All features work, handles edge cases Most features work, minor bugs Basic features work, some bugs Many bugs, features incomplete
Code Organization Well-structured functions, clear separation Good structure, minor issues Some organization present Poor organization, hard to follow
Documentation Comprehensive docstrings and comments Good documentation, mostly clear Basic comments present Little to no documentation
User Experience Intuitive, handles errors gracefully Easy to use, some error handling Usable but could be improved Confusing or frustrating
Data Handling Robust save/load, validation Works well, minor issues Basic functionality works Data loss or corruption possible
Testing Thoroughly tested all features Tested main features Basic testing done Minimal testing

šŸ“Š Score Guide

20–24 points: Excellent! Ready for advanced projects.

15–19 points: Good work! Minor improvements needed.

10–14 points: Satisfactory — practice key concepts.

Below 10: Keep learning and practicing!

āœ… Code Review Checklist

Functionality

All menu options work correctly. Can add income and expenses. Balance calculation is accurate. Data saves and loads properly. Reports display correctly. Program handles invalid input gracefully.

Code Quality

Functions have clear, single purposes. Variable names are descriptive. No repeated code (DRY principle). Proper indentation throughout. Comments explain complex logic. Docstrings for all functions.

Error Handling

Try/except blocks for risky operations. Input validation prevents crashes. Clear error messages for users. Graceful handling of missing files.

User Experience

Clear menu and navigation. Helpful prompts and instructions. Confirmation for destructive actions. Visual feedback with emojis and formatting. Option to exit cleanly.

šŸ‹ļø Practice Exercises

šŸ‹ļø Exercise 1: Add a "Delete Transaction" Feature

Objective: Extend the finance tracker with a function that lets the user delete a transaction by ID. Update the statistics after deletion.

šŸ’” Hint

Use a list comprehension or loop to find the transaction by id. Before deleting, subtract its amount from monthly_totals and category_spending. Ask the user for confirmation before deleting.

āœ… Solution
def delete_transaction():
    """Delete a transaction by ID."""
    if not transactions:
        print("\nšŸ“­ No transactions to delete!")
        return

    view_transactions(5)
    try:
        tid = int(input("\nEnter transaction ID to delete: "))
    except ValueError:
        print("Please enter a valid number!")
        return

    target = None
    for t in transactions:
        if t["id"] == tid:
            target = t
            break

    if not target:
        print(f"āŒ Transaction #{tid} not found.")
        return

    symbol = "+" if target["type"] == "income" else "-"
    print(f"\nDelete: {target['date']} | {target['category']} | "
          f"{symbol}${target['amount']:.2f}?")
    confirm = input("Type 'yes' to confirm: ")

    if confirm.lower() == "yes":
        transactions.remove(target)
        month_key = target["date"][:7]
        monthly_totals[month_key][target["type"]] -= target["amount"]
        if target["type"] == "expense":
            category_spending[target["category"]] -= target["amount"]
        print("āœ“ Transaction deleted.")
    else:
        print("Cancelled.")

šŸ‹ļø Exercise 2: Add a "Search Transactions" Feature

Objective: Create a function that searches transactions by keyword (matching description or category) and displays results.

šŸ’” Hint

Use str.lower() for case-insensitive matching. Check if the keyword appears in the category or description fields. Use a list comprehension to filter results.

āœ… Solution
def search_transactions():
    """Search transactions by keyword."""
    if not transactions:
        print("\nšŸ“­ No transactions to search!")
        return

    keyword = input("\nSearch keyword: ").strip().lower()
    if not keyword:
        print("Please enter a search term.")
        return

    results = [
        t for t in transactions
        if keyword in t["category"].lower()
        or keyword in t.get("description", "").lower()
    ]

    if not results:
        print(f"šŸ“­ No transactions matching '{keyword}'")
        return

    print(f"\n=== Search Results for '{keyword}' ({len(results)} found) ===")
    print("-" * 60)
    for t in results:
        symbol = "+" if t["type"] == "income" else "-"
        print(f"{t['date']} | {t['category']:<15} | "
              f"{symbol}${t['amount']:>8.2f}")
        if t["description"]:
            print(f"    └─ {t['description']}")
    print("-" * 60)

šŸ‹ļø Exercise 3: Add a "Budget Limit" Feature

Objective: Let the user set monthly spending limits per category. When adding an expense, warn if the limit is about to be exceeded.

šŸ’” Hint

Store budgets in a dictionary like {"Food": 500, "Entertainment": 200}. In add_transaction, after selecting a category, sum that category's expenses for the current month and compare against the budget.

āœ… Solution
# Add to global data
budgets = {}

def set_budget():
    """Set a monthly budget for an expense category."""
    print("\n=== Set Budget ===")
    print("Expense categories:")
    for i, cat in enumerate(categories["expense"], 1):
        current = budgets.get(cat, "No limit")
        print(f"  {i}. {cat} — {current}")

    try:
        choice = int(input("Select category (number): "))
        if 1 <= choice <= len(categories["expense"]):
            cat = categories["expense"][choice - 1]
            amount = float(input(f"Monthly limit for {cat}: $"))
            budgets[cat] = amount
            print(f"āœ“ Budget set: {cat} = ${amount:.2f}/month")
        else:
            print("Invalid choice!")
    except ValueError:
        print("Please enter valid numbers!")

def check_budget(category, new_amount):
    """Check if adding an expense would exceed budget."""
    if category not in budgets:
        return
    current_month = datetime.date.today().strftime("%Y-%m")
    spent = sum(
        t["amount"] for t in transactions
        if t["type"] == "expense"
        and t["category"] == category
        and t["date"].startswith(current_month)
    )
    limit = budgets[category]
    if spent + new_amount > limit:
        remaining = limit - spent
        print(f"\nāš ļø  Budget Warning: {category}")
        print(f"  Limit: ${limit:.2f} | Spent: ${spent:.2f} "
              f"| Remaining: ${remaining:.2f}")
        print(f"  This expense (${new_amount:.2f}) exceeds your budget!")

šŸŽÆ Quick Quiz

Question 1: In the finance tracker, why do we use defaultdict instead of a regular dict for monthly_totals?

Question 2: What Python concept allows add_transaction to handle both income and expenses with a single function?

Question 3: Why does load_data use the global keyword?

šŸ—ŗļø Next Steps: Learning Paths

You've built a solid foundation. Now it's time to choose your adventure! Here are six popular directions you can take from here.

graph TD A["šŸ Python Fundamentals
(You Are Here!)"] --> B["🌐 Web Development"] A --> C["šŸ“Š Data Science"] A --> D["šŸŽ® Game Development"] A --> E["šŸ¤– Automation"] A --> F["šŸ”’ Cybersecurity"] A --> G["šŸ“± Mobile Development"]

🌐 Web Development

Build interactive websites and web apps. Start with HTML & CSS, then JavaScript, then Python web frameworks like Flask or Django. Add databases (PostgreSQL, MongoDB), learn APIs, and pick up a frontend framework like React or Vue.js.

Project ideas: Personal blog, e-commerce site, social platform.

šŸ“Š Data Science

Analyze data and build machine learning models. Learn NumPy for numerical computing, Pandas for data manipulation, Matplotlib/Seaborn for visualization, then move into Scikit-learn for ML and TensorFlow/PyTorch for deep learning.

Project ideas: Stock predictor, sentiment analysis, image classifier.

šŸŽ® Game Development

Create games and interactive experiences. Start with Pygame for 2D games, learn game design mechanics, then move into sprites, animation, physics, AI behavior, and eventually 3D with Unity.

Project ideas: Platformer, puzzle game, RPG.

šŸ¤– Automation

Automate tasks and build bots. Learn web scraping (BeautifulSoup, Scrapy), browser automation (Selenium), working with APIs, task scheduling, and bot development for Discord or Telegram.

Project ideas: Price tracker, social media bot, file organizer.

šŸ”’ Cybersecurity

Learn security and ethical hacking. Study networking (TCP/IP), master Linux, explore cryptography, study web security (OWASP Top 10), then use Python security tools like Scapy and move into penetration testing.

Project ideas: Port scanner, password manager, security audit tool.

šŸ“± Mobile Development

Build mobile applications. Try Kivy for Python mobile apps, or use Python as a backend for React Native or Flutter frontends. Learn UI/UX principles and eventually publish to app stores.

Project ideas: Todo app, weather app, fitness tracker.

šŸ“š Resources for Continued Learning

Online Platforms

Codecademy (interactive courses), LeetCode (coding challenges), HackerRank (competitions), Coursera and edX (university-level courses), and Kaggle (data science).

Communities

r/learnpython on Reddit, Python Discord for real-time help, Stack Overflow for Q&A, Dev.to for articles, and GitHub for sharing and collaborating on projects.

Recommended Books

Automate the Boring Stuff by Al Sweigart, Python Crash Course by Eric Matthes, Clean Code by Robert C. Martin, and The Pragmatic Programmer by David Thomas.

Recommended Next Courses

Course What You'll Learn Duration
Object-Oriented Programming Classes, inheritance, design patterns 4 weeks
Data Structures & Algorithms Essential CS concepts, problem-solving 8 weeks
Database Fundamentals SQL, database design, data modeling 3 weeks
Git & Version Control Collaborate and manage code professionally 1 week
API Development Build and consume RESTful APIs 4 weeks
Testing & Debugging Write tests and debug like a pro 2 weeks

šŸŽŠ Your Journey Continues

šŸŽ‰ You Did It!

You've completed Introduction to Programming with Python. This is not the end — it's just the beginning of your coding journey!

Remember

šŸ’Ŗ Practice daily — even 15 minutes makes a difference. šŸ—ļø Build projects — apply what you learn. šŸ¤ Help others — teaching reinforces learning. šŸ” Stay curious — technology always evolves. šŸŽÆ Set goals — work toward specific objectives. šŸš€ Never stop learning — every expert was once a beginner.

šŸ† Certificate of Completion šŸ†

This certifies that you have completed

Introduction to Programming with Python

You've mastered: Variables • Functions • Loops • Data Structures • and more!

You're now ready to build amazing things.

Welcome to the world of programming!

šŸ“– Final Words of Wisdom

Programming is not just about writing code — it's about solving problems, creating solutions, and bringing ideas to life. You now have the foundation to do all of this and more. Be patient with yourself, celebrate small victories, and remember that every line of code you write is a step forward in your journey.

Happy Coding! šŸš€