Expense Tracker Project (code) in Python

← Back to Projects

Expense Tracker in Python.

About the project:This is the project for an Expense Tracker in Python

This program will allow you to record expenses with a description, amount, and category. It will save all the expense data to a file, so your records are persistent.

  • This Python script is a complete and interactive Expense Tracker application.
  • It provides a menu-driven interface for logging and reviewing your spending.
  • All your recorded expenses are saved to a expenses.json file, so they'll be preserved between sessions.

How to use this program:

You can run this script, and it will guide you through adding expenses and viewing summaries of your spending.


Project Level: Intermediate

You can directly copy the below snippet code with the help of green copy button, paste it and run it in any Python editor you have.

Steps: Follow these steps

Step 1: Copy below code using green 'copy' button.

Step 2: Paste the code on your chosen editor.

Step 3: Save the code with filename and .py extention.

Step 4: Run (Press F5 if using python IDLE)




# expense_tracker.py

import json
import os
from datetime import datetime

# Filename for storing expenses
EXPENSES_FILE = "expenses.json"

def load_expenses():
    """
    Loads expenses from a JSON file. Returns a dictionary of expenses.
    If the file doesn't exist, it returns a new dictionary.
    """
    if os.path.exists(EXPENSES_FILE) and os.stat(EXPENSES_FILE).st_size > 0:
        try:
            with open(EXPENSES_FILE, 'r') as f:
                return json.load(f)
        except json.JSONDecodeError:
            print("Warning: Expenses file is corrupted or empty. Starting with a new tracker.")
            return {}
    return {}

def save_expenses(expenses):
    """
    Saves the expenses dictionary to a JSON file.
    """
    with open(EXPENSES_FILE, 'w') as f:
        json.dump(expenses, f, indent=4)
    print("Expenses saved successfully.")

def add_expense(expenses):
    """
    Prompts the user for a new expense and adds it to the expenses dictionary.
    """
    description = input("Enter description: ").strip()
    if not description:
        print("Description cannot be empty. Expense not added.")
        return

    try:
        amount = float(input("Enter amount: ").strip())
        category = input("Enter category (e.g., Food, Transport, Bills): ").strip()
        timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

        # Create a unique ID for each expense
        expense_id = str(len(expenses) + 1)

        expenses[expense_id] = {
            "description": description,
            "amount": amount,
            "category": category,
            "timestamp": timestamp
        }
        print(f"Expense '{description}' added with ID: {expense_id}")
    except ValueError:
        print("Invalid amount. Please enter a number.")

def view_expenses(expenses):
    """
    Displays all recorded expenses in a clean, readable format.
    """
    if not expenses:
        print("\nNo expenses recorded yet.")
        return

    print("\n--- All Expenses ---")
    for expense_id, details in expenses.items():
        print(f"ID: {expense_id}")
        print(f"  Description: {details.get('description', 'N/A')}")
        print(f"  Amount: ${details.get('amount', 0):.2f}")
        print(f"  Category: {details.get('category', 'N/A')}")
        print(f"  Date: {details.get('timestamp', 'N/A')}")
        print("-" * 20)
    print("--------------------")

def summarize_expenses(expenses):
    """
    Calculates and displays a summary of spending by category and the total amount.
    """
    if not expenses:
        print("\nNo expenses recorded to summarize.")
        return

    total_expenses = 0.0
    category_summary = {}

    for details in expenses.values():
        amount = details.get('amount', 0)
        category = details.get('category', 'Other')
        
        total_expenses += amount
        
        # Add to the category summary
        category_summary[category] = category_summary.get(category, 0) + amount

    print("\n--- Expense Summary ---")
    print(f"Total Expenses: ${total_expenses:.2f}")
    print("\nSpending by Category:")
    for category, amount in category_summary.items():
        print(f"  {category}: ${amount:.2f}")
    print("-----------------------")

def main():
    """
    Main function to run the Expense Tracker app with a menu.
    """
    expenses = load_expenses()

    print("--- Python Expense Tracker ---")

    while True:
        print("\nMenu:")
        print("1. Add a new expense")
        print("2. View all expenses")
        print("3. View spending summary")
        print("4. Quit and Save")

        choice = input("Enter your choice (1-4): ").strip()

        if choice == '1':
            add_expense(expenses)
        elif choice == '2':
            view_expenses(expenses)
        elif choice == '3':
            summarize_expenses(expenses)
        elif choice == '4':
            save_expenses(expenses)
            print("Exiting Expense Tracker. Goodbye!")
            break
        else:
            print("Invalid choice. Please enter a number between 1 and 4.")

# This ensures that main() is called only when the script is executed directly.
if __name__ == "__main__":
    main()