import json
import threading
import uuid
import time
from datetime import datetime
class ExpenseError(Exception):
pass
class Expense:
def __init__(self, amount, category):
if amount <= 0:
raise ExpenseError("Amount must be positive")
self.id = str(uuid.uuid4())
self.amount = amount
self.category = category
self.date =
datetime.now().strftime("%Y-%m-%d %H:%M:%S")
def to_dict(self):
return self.__dict__
class ExpenseManager:
def __init__(self, filename="expenses.json"):
self.filename = filename
self.expenses = []
self.lock = threading.Lock()
self.load()
def add(self, amount, category):
expense = Expense(amount, category)
with self.lock:
self.expenses.append(expense)
print("Added:",
expense.id)
def total(self, category):
return sum(e.amount for e in self.expenses if e.category == category)
def save(self):
with open(self.filename, "w") as f:
json.dump([
e.to_dict() for e in self.expenses], f, indent=4)
def load(self):
try:
with open(self.filename, "r") as f:
data = json.load(f)
for item in data:
e = Expense(item["amount"], item["category"])
e.id = item["id"]
e.date = item["date"]
self.expenses.append(e)
except FileNotFoundError:
pass
def auto_save(manager):
while True:
time.sleep(15)
manager.save()
if __name__ == "__main__":
manager = ExpenseManager()
threading.Thread(target=auto_save, args=(manager,), daemon=True).start()
while True:
print("\n1.Add
2.Total 3.Exit")
choice = input("Choose: ")
try:
if choice == "1":
amt = float(input("Amount: "))
cat = input("Category: ")
manager.add(amt, cat)
elif choice == "2":
cat = input("Category: ")
print("Total:",
manager.total(cat))
elif choice == "3":
manager.save()
break
else:
print("Invalid choice")
except Exception as e:
print("Error:", e)