import json
from datetime import datetime, timedelta
from collections import defaultdict
class BudgetApp:
def __init__(self):
self.expenses = []
self.load_expenses()
def load_expenses(self):
try:
with open('expenses.json', 'r') as f:
self.expenses = json.load(f)
except FileNotFoundError:
self.expenses = []
def save_expenses(self):
with open('expenses.json', 'w') as f:
json.dump(self.expenses, f, indent=2)
def add_expense(self):
print("\n--- Add Expense ---")
amount = float(input("Amount: $"))
category = input("Category (e.g., Food, Transport, Entertainment): ").strip()
description = input("Description (optional): ").strip()
date = input("Date (YYYY-MM-DD, press Enter for today): ").strip()
if not date:
date = datetime.now().strftime('%Y-%m-%d')
expense = {
'amount': amount,
'category': category,
'description': description,
'date': date
}
self.expenses.append(expense)
self.save_expenses()
print(f"✓ Expense added: ${amount:.2f} in {category}")
def view_all_expenses(self):
if not self.expenses:
print("\nNo expenses recorded yet.")
return
print("\n--- All Expenses ---")
for i, exp in enumerate(self.expenses, 1):
print(f"{i}. {exp['date']} | ${exp['amount']:.2f} | {exp['category']}")
if exp['description']:
print(f" Description: {exp['description']}")
def weekly_summary(self):
if not self.expenses:
print("\nNo expenses to summarize.")
return
today = datetime.now()
week_ago = today - timedelta(days=7)
weekly_expenses = [
exp for exp in self.expenses
if datetime.strptime(exp['date'], '%Y-%m-%d') >= week_ago
]
if not weekly_expenses:
print("\nNo expenses in the last 7 days.")
return
print("\n--- Weekly Summary (Last 7 Days) ---")
# Total
total = sum(exp['amount'] for exp in weekly_expenses)
print(f"Total Spent: ${total:.2f}")
# By category
by_category = defaultdict(float)
for exp in weekly_expenses:
by_category[exp['category']] += exp['amount']
print("\nBy Category:")
for cat, amt in sorted(by_category.items(), key=lambda x: x[1], reverse=True):
percentage = (amt / total) * 100
print(f" {cat}: ${amt:.2f} ({percentage:.1f}%)")
print(f"\nNumber of transactions: {len(weekly_expenses)}")
def delete_expense(self):
self.view_all_expenses()
if not self.expenses:
return
try:
idx = int(input("\nEnter expense number to delete (0 to cancel): ")) - 1
if idx == -1:
return
if 0 <= idx < len(self.expenses):
deleted = self.expenses.pop(idx)
self.save_expenses()
print(f"✓ Deleted: ${deleted['amount']:.2f} from {deleted['category']}")
else:
print("Invalid expense number.")
except ValueError:
print("Invalid input.")
def run(self):
while True:
print("\n" + "="*40)
print(" BUDGET TRACKER")
print("="*40)
print("1. Add Expense")
print("2. View All Expenses")
print("3. Weekly Summary")
print("4. Delete Expense")
print("5. Exit")
print("="*40)
choice = input("Choose an option (1-5): ").strip()
if choice == '1':
self.add_expense()
elif choice == '2':
self.view_all_expenses()
elif choice == '3':
self.weekly_summary()
elif choice == '4':
self.delete_expense()
elif choice == '5':
print("\nGoodbye! Your expenses have been saved.")
break
else:
print("Invalid option. Please choose 1-5.")
if __name__ == "__main__":
app = BudgetApp()
app.run()