Personal Expense Tracker CLI
Project Overview & Use Case
Managing daily expenses manually can lead to lost receipts and forgotten spending.
The Use Case: This project is a Command-Line Interface (CLI) application that allows users to log their daily expenses, categorize them, and instantly view a summary of their spending habits.
The Output: It saves all data permanently into a .csv (Comma Separated Values) file, which can later be opened in Microsoft Excel or Google Sheets for further analysis.
System Workflow (How It Works)
Initialization: When the script runs, it checks if a file named expenses.csv exists. If it does not, the script creates it and adds the header row (Date, Category, Amount, Description).
Main Menu: The user is presented with a text-based menu offering three options:
-
Add a new expense.
-
View an expense summary.
-
Exit the program.
Data Entry: If the user adds an expense, the script automatically captures the current date, asks for the category, amount, and description, and appends this data to the CSV file.
Data Aggregation: If the user views the summary, the script reads the CSV file, groups the spending by category using a Python dictionary, and calculates the total amount spent per category.
Source Code
Save the following code in a file named expense_tracker.py.
import csv
import os
from datetime import datetime
# Define the file name where data will be saved
FILE_NAME = "expenses.csv"
def initialize_file():
"""Creates the CSV file with headers if it doesn't already exist."""
if not os.path.exists(FILE_NAME):
with open(FILE_NAME, mode='w', newline='') as file:
writer = csv.writer(file)
writer.writerow(["Date", "Category", "Amount", "Description"])
def add_expense():
"""Prompts the user for expense details and saves them to the CSV."""
print("
--- Add a New Expense ---")
# Get current date automatically
date_today = datetime.now().strftime("%Y-%m-%d")
category = input("Enter Category (e.g., Food, Transport, Utilities): ").capitalize()
# Error handling to ensure the amount is a valid number
try:
amount = float(input("Enter Amount: $"))
except ValueError:
print("❌ Invalid input. Please enter a numerical value for the amount.")
return
description = input("Enter a brief description: ")
# Append the new record to the CSV file
with open(FILE_NAME, mode='a', newline='') as file:
writer = csv.writer(file)
writer.writerow([date_today, category, amount, description])
print(f"✅ Successfully added: $ {amount:.2f} for {category}.")
def view_summary():
"""Reads the CSV and displays total spending per category."""
print("
--- Expense Summary ---")
if not os.path.exists(FILE_NAME):
print("⚠️ No expenses recorded yet.")
return
category_totals = {}
total_spent = 0.0
# Read the file and calculate totals
with open(FILE_NAME, mode='r') as file:
reader = csv.DictReader(file)
for row in reader:
category = row["Category"]
amount = float(row["Amount"])
# Add amount to the specific category
if category in category_totals:
category_totals[category] += amount
else:
category_totals[category] = amount
total_spent += amount
# Display the aggregated data
if total_spent == 0:
print("No expenses found.")
else:
for cat, total in category_totals.items():
print(f"🔹 {cat}: $ {total:.2f}")
print("-" * 23)
print(f"💰 Total Spent: $ {total_spent:.2f}")
def main():
"""The main loop that runs the interactive menu."""
initialize_file()
while True:
print("
" + "="*25)
print(" EXPENSE TRACKER MENU")
print("="*25)
print("1. Add an Expense")
print("2. View Summary")
print("3. Exit")
choice = input("Select an option (1-3): ")
if choice == '1':
add_expense()
elif choice == '2':
view_summary()
elif choice == '3':
print("Exiting Expense Tracker. Have a great day! 👋")
break
else:
print("❌ Invalid choice. Please select 1, 2, or 3.")
if __name__ == "__main__":
main() Code Explanation (Component Breakdown)
csv Module: Python’s built-in tool for reading and writing CSV files. csv.writer is used to add data row by row, while csv.DictReader transforms each row of the file into a dictionary, allowing us to access columns by their header names (e.g., row[“Amount”]).
with open(…) as file: This is a context manager. It is best practice for file handling because it automatically closes the file when the block of code finishes, even if an error occurs.
mode=‘a’ vs mode=‘w’ vs mode=‘r’:
- ‘w’ (Write): Creates a new file or overwrites an existing one. Used in initialization.
- ‘a’ (Append): Adds new data to the bottom of the file without deleting existing data. Used when adding an expense.
- ‘r’ (Read): Opens the file strictly to view the data. Used in the summary.
Try/Except Block: When asking the user for the money amount (float(input(…))), the user might accidentally type a letter instead of a number. The try/except ValueError catches this mistake and prevents the entire program from crashing.
Execution Guide (How to Run)
Save the file: Create a new folder on your desktop called ExpenseProject. Inside it, create a file named expense_tracker.py and paste the code above.
Open Terminal/Command Prompt: Navigate to that folder.
Run the script: Type the command python expense_tracker.py and press Enter.
Interact: Follow the on-screen menu to log a few test expenses (like groceries or rent), then choose option 2 to see your calculated totals.
Verify: Open the ExpenseProject folder. You will see a newly generated expenses.csv file that you can open with Excel.