Personal Expense Tracker Project
Project Report
Mini Project Report
Personal Expense Tracker using Python
1. Title: Personal Expense Tracker
2. Objective:
To design and implement a Python-based console application that allows the user to
record daily expenses, categorize them, and generate useful summaries of spending
over time using file handling and basic data analysis.
3. Problem Statement:
Managing daily expenses manually in a notebook or on paper is time-consuming and
error-prone. Users find it difficult to remember how much they spent in each
category such as food, transport, and entertainment. There is a need for a simple
computer-based solution to store, update, and summarize expense records.
4. Proposed System:
The proposed system is a command-line Personal Expense Tracker written in Python.
It allows the user to add expenses with amount, category, and date, view all
expenses, and view summaries such as total spending, total by category, and
daily/monthly summaries. All data is stored in a JSON file so that the information
is not lost when the program is closed.
5. Software and Hardware Requirements:
• Software: Python 3.x, any text editor or IDE (IDLE / VS Code / PyCharm)
• Hardware: Standard PC or laptop with basic configuration
6. Modules:
• File Handling Module – load_expenses(), save_expenses()
• Input Validation Module – get_valid_amount(), get_valid_date()
• Core Logic Module – add_expense(), view_all_expenses()
• Summary Module – total_overall_spending(), total_by_category(),
daily_summary(), monthly_summary()
• Optional Management Module – edit_expense(), delete_expense()
• User Interface Module – main() with a menu-driven interface
7. Algorithm (High Level):
Step 1: Start the program and load existing expenses from [Link]
Step 2: Display the main menu with options:
1) Add Expense
2) View All Expenses
3) View Summaries
4) Edit Expense
5) Delete Expense
6) Exit
Step 3: Read the user choice.
Step 4: If choice is Add Expense, get amount, category, and date from user,
store them in a dictionary, append to the list, and save to file.
Step 5: If choice is View All Expenses, display all records with index, date,
category, and amount.
Step 6: If choice is View Summaries, show a sub-menu for overall total, total by
category, daily summary, and monthly summary and process accordingly.
Step 7: If choice is Edit or Delete Expense, ask for the serial number, update or
remove the selected record, and save the file.
Step 8: If choice is Exit, stop the program.
Step 9: Repeat steps 2–8 until the user chooses Exit.
8. Sample Output (Description):
• On starting the program, previous expense records are loaded and displayed.
• The user can enter an amount such as 150, category "Food", and date.
• The program confirms that the expense is added successfully.
• On choosing View Summaries, the program prints total overall spending and
the total spent in each category, and shows per-day or per-month totals.
9. Advantages:
• Simple to use and understand
• Data is safely stored in a file (JSON)
• Easy to modify and extend (e.g., adding graphs using matplotlib)
• Helps users track spending habits and control unnecessary expenses
10. Conclusion:
The Personal Expense Tracker mini project successfully demonstrates Python
programming concepts such as functions, lists and dictionaries, file handling,
and basic data analysis. The application provides a useful and user-friendly
way for users to record and monitor their daily expenses.
11. Future Enhancements:
• Add graphical charts using matplotlib to visualize spending by category
• Provide a graphical user interface (GUI) using Tkinter or a web framework
• Add user authentication for multiple users
• Export reports to CSV or Excel format
Python Source Code
Mini Project: Personal Expense Tracker
import json
import os
from datetime import datetime
DATA_FILE = "[Link]"
# ---------------------- File Handling Functions ---------------------- #
def load_expenses():
"""Load expense data from JSON file. Return a list of expenses."""
if not [Link](DATA_FILE):
return []
try:
with open(DATA_FILE, "r") as f:
data = [Link](f)
# Ensure it's a list
if isinstance(data, list):
return data
else:
return []
except ([Link], IOError):
print("Error reading data file. Starting with an empty list.")
return []
def save_expenses(expenses):
"""Save the list of expenses to JSON file."""
try:
with open(DATA_FILE, "w") as f:
[Link](expenses, f, indent=4)
except IOError:
print("Error saving data.")
# ---------------------- Utility Functions ---------------------- #
def get_valid_amount():
"""Ask the user for a valid float amount."""
while True:
amount_str = input("Enter amount: ")
try:
amount = float(amount_str)
if amount < 0:
print("Amount cannot be negative. Try again.")
continue
return amount
except ValueError:
print("Invalid amount. Please enter a number.")
def get_valid_date():
"""
Ask the user for a date in YYYY-MM-DD format.
If left blank, use today's date.
"""
date_str = input("Enter date (YYYY-MM-DD) or press Enter for today: ").strip()
if date_str == "":
return [Link]().strftime("%Y-%m-%d")
try:
# Validate date format
date_obj = [Link](date_str, "%Y-%m-%d")
return date_obj.strftime("%Y-%m-%d")
except ValueError:
print("Invalid date format. Using today's date.")
return [Link]().strftime("%Y-%m-%d")
# ---------------------- Core Features ---------------------- #
def add_expense(expenses):
"""Add a new expense to the list."""
print("\n--- Add New Expense ---")
amount = get_valid_amount()
category = input("Enter category (e.g., Food, Transport, Entertainment): ").strip()
if category == "":
category = "Other"
date = get_valid_date()
expense = {
"amount": amount,
"category": [Link](),
"date": date
}
[Link](expense)
✅
save_expenses(expenses)
print(" Expense added successfully!\n")
def view_all_expenses(expenses):
"""Display all expense records."""
print("\n--- All Expenses ---")
if not expenses:
print("No expenses recorded yet.\n")
return
for i, exp in enumerate(expenses, start=1):
print(f"{i}. Date: {exp['date']} | Category: {exp['category']} | Amount: {exp['amount']}")
print()
def total_overall_spending(expenses):
"""Calculate and display total overall spending."""
total = sum(exp["amount"] for exp in expenses)
print(f"\nTotal Overall Spending: {total}\n")
def total_by_category(expenses):
"""Calculate total spending for a specific category."""
if not expenses:
print("\nNo expenses recorded yet.\n")
return
category = input("Enter category to view total spending: ").strip().capitalize()
total = sum(exp["amount"] for exp in expenses if exp["category"] == category)
print(f"\nTotal spending for category '{category}': {total}\n")
def daily_summary(expenses):
"""Show total spending per day."""
if not expenses:
print("\nNo expenses recorded yet.\n")
return
print("\n--- Daily Summary ---")
daily_totals = {}
for exp in expenses:
date = exp["date"]
daily_totals[date] = daily_totals.get(date, 0) + exp["amount"]
for date, total in sorted(daily_totals.items()):
print(f"Date: {date} | Total: {total}")
print()
def monthly_summary(expenses):
"""Show total spending per month (YYYY-MM)."""
if not expenses:
print("\nNo expenses recorded yet.\n")
return
print("\n--- Monthly Summary ---")
monthly_totals = {}
for exp in expenses:
# Extract YYYY-MM from date
month = exp["date"][:7]
monthly_totals[month] = monthly_totals.get(month, 0) + exp["amount"]
for month, total in sorted(monthly_totals.items()):
print(f"Month: {month} | Total: {total}")
print()
def view_summary_menu(expenses):
"""Menu to view different types of summaries."""
while True:
print("\n--- View Summary ---")
print("1. Total Overall Spending")
print("2. Total Spending by Category")
print("3. Daily Summary")
print("4. Monthly Summary")
print("5. Back to Main Menu")
choice = input("Enter your choice: ").strip()
if choice == "1":
total_overall_spending(expenses)
elif choice == "2":
total_by_category(expenses)
elif choice == "3":
daily_summary(expenses)
elif choice == "4":
monthly_summary(expenses)
elif choice == "5":
break
else:
print("Invalid choice. Please try again.")
# ---------------------- Optional: Edit/Delete Expense ---------------------- #
def delete_expense(expenses):
"""Optional: Delete an expense record by index."""
if not expenses:
print("\nNo expenses to delete.\n")
return
view_all_expenses(expenses)
try:
idx = int(input("Enter the serial number of the expense to delete: "))
if 1 <= idx <= len(expenses):
removed = [Link](idx - 1)
save_expenses(expenses)
print(f"Deleted expense: {removed}")
else:
print("Invalid serial number.")
except ValueError:
print("Invalid input. Please enter a number.")
def edit_expense(expenses):
"""Optional: Edit an existing expense."""
if not expenses:
print("\nNo expenses to edit.\n")
return
view_all_expenses(expenses)
try:
idx = int(input("Enter the serial number of the expense to edit: "))
if 1 <= idx <= len(expenses):
exp = expenses[idx - 1]
print(f"Editing: {exp}")
# New values (press enter to keep old)
new_amount_str = input(f"New amount (current: {exp['amount']}) or press Enter to
keep: ")
if new_amount_str.strip() != "":
try:
exp["amount"] = float(new_amount_str)
except ValueError:
print("Invalid amount. Keeping old value.")
new_cat = input(f"New category (current: {exp['category']}) or press Enter to keep:
").strip()
if new_cat != "":
exp["category"] = new_cat.capitalize()
new_date = input(f"New date YYYY-MM-DD (current: {exp['date']}) or press Enter to
keep: ").strip()
if new_date != "":
try:
[Link](new_date, "%Y-%m-%d")
exp["date"] = new_date
except ValueError:
print("Invalid date. Keeping old value.")
save_expenses(expenses)
print("Expense updated successfully!")
else:
print("Invalid serial number.")
except ValueError:
print("Invalid input. Please enter a number.")
# ---------------------- Main Menu ---------------------- #
def main():
print("====================================")
print(" PERSONAL EXPENSE TRACKER ")
print("====================================")
expenses = load_expenses()
# Display previous records on start (optional but as per requirements)
if expenses:
print("\nPrevious expense records loaded successfully.")
view_all_expenses(expenses)
else:
print("\nNo previous records found. Starting fresh.\n")
while True:
print("----- Main Menu -----")
print("1. Add Expense")
print("2. View All Expenses")
print("3. View Summaries")
print("4. Edit an Expense (Optional)")
print("5. Delete an Expense (Optional)")
print("6. Exit")
choice = input("Enter your choice: ").strip()
if choice == "1":
add_expense(expenses)
elif choice == "2":
view_all_expenses(expenses)
elif choice == "3":
view_summary_menu(expenses)
elif choice == "4":
edit_expense(expenses)
elif choice == "5":
delete_expense(expenses)
elif choice == "6":
print("Exiting... Goodbye!")
break
else:
print("Invalid choice. Please try again.\n")
if __name__ == "__main__":
main()
JSON Expense Data
[
{
"amount": 150.0,
"category": "Food",
"date": "2025-11-15"
},
{
"amount": 60.0,
"category": "Transport",
"date": "2025-11-15"
},
{
"amount": 200.0,
"category": "Shopping",
"date": "2025-11-16"
},
{
"amount": 90.0,
"category": "Food",
"date": "2025-11-17"
}
]
Program Output
Program Output
---------------
====================================
PERSONAL EXPENSE TRACKER
====================================
No previous records found. Starting fresh.
----- Main Menu -----
1. Add Expense
2. View All Expenses
3. View Summaries
4. Edit an Expense (Optional)
5. Delete an Expense (Optional)
6. Exit
Enter your choice: 1
--- Add New Expense ---
Enter amount: 150
Enter category (e.g., Food, Transport, Entertainment): Food
✅
Enter date (YYYY-MM-DD) or press Enter for today: 2025-11-18
Expense added successfully!
----- Main Menu -----
1. Add Expense
2. View All Expenses
3. View Summaries
4. Edit an Expense (Optional)
5. Delete an Expense (Optional)
6. Exit
Enter your choice: 2
--- All Expenses ---
1. Date: 2025-11-18 | Category: Food | Amount: 150.0