import json
import tkinter as tk
from tkinter import messagebox
import [Link] as plt
from [Link].backend_tkagg import FigureCanvasTkAgg # To embed the graph in tkinter
class Expense:
def __init__(self, category, amount, spender):
[Link] = category
[Link] = amount
[Link] = spender # New attribute to track who spent the money
class MonthlyBudget:
def __init__(self, salary):
[Link] = salary
[Link] = []
[Link] = salary # Initial balance is the salary
def add_expense(self, category, amount, spender):
""" Add an expense and deduct from the house balance """
if amount > 0:
if amount <= [Link]:
[Link](Expense(category, amount, spender))
[Link] -= amount # Deduct expense from balance
return f"Added expense: {category} - {amount} by {spender}. Remaining balance:
{[Link]}."
else:
return "Not enough balance for this expense."
else:
return "Expense amount must be positive."
def display_expenses(self):
""" Display a summary of all expenses and balance """
summary = "--- Expense Summary ---\n"
total_expense = 0
for expense in [Link]:
summary += f"{[Link]} spent on {[Link]}: {[Link]}\n"
total_expense += [Link]
summary += f"\nTotal expenses: {total_expense}\n"
summary += f"Remaining balance: {[Link]}"
return summary
def plot_expenses(self, root):
""" Plot expenses using a pie chart """
if not [Link]:
[Link]("Visualization", "No expenses to display. Add some expenses first.")
return
categories = [[Link] for expense in [Link]]
amounts = [[Link] for expense in [Link]]
# Create a new figure and plot
fig, ax = [Link](figsize=(8, 6))
[Link](amounts, labels=categories, autopct='%1.1f%%', startangle=140)
ax.set_title("Expense Distribution")
[Link]('equal') # Equal aspect ratio ensures the pie chart is circular
# Embed the plot into the tkinter window
canvas = FigureCanvasTkAgg(fig, master=root) # A Tkinter canvas to display the plot
[Link]()
canvas.get_tk_widget().grid(row=4, column=0, columnspan=2) # Place the canvas in grid layout
def save_data(self, filename="monthly_budget.json"):
""" Save data to a file """
data = {
"salary": [Link],
"expenses": [{"category": [Link], "amount": [Link], "spender": [Link]} for exp
in [Link]],
"balance": [Link]
with open(filename, "w") as f:
[Link](data, f, indent=4)
[Link]("Save Data", "Budget data saved successfully.")
def load_data(self, filename="monthly_budget.json"):
""" Load data from a file """
try:
with open(filename, "r") as f:
data = [Link](f)
[Link] = data["salary"]
[Link] = data["balance"]
[Link] = [Expense(exp["category"], exp["amount"], exp["spender"]) for exp in
data["expenses"]]
except FileNotFoundError:
[Link] = 0
[Link] = []
[Link] = 0
def add_balance(self, amount):
""" Allow user to add money to the balance """
if amount > 0:
[Link] += amount
return f"Balance updated. New balance: {[Link]}"
else:
return "Amount must be positive to add to the balance."
def create_gui():
""" Create the GUI for the expense tracker """
# Initialize budget
budget = MonthlyBudget(0)
budget.load_data()
if [Link] == 0:
salary = float(input("Enter your monthly salary: "))
[Link] = salary
[Link] = salary # Set the house balance to salary initially
def add_expense():
""" Add an expense """
category = category_var.get()
spender = spender_entry.get() # Get the spender's name from the input field
try:
amount = float(amount_entry.get())
if not spender:
[Link]("Input Error", "Please enter the spender's name.")
return
result = budget.add_expense(category, amount, spender)
[Link]("Add Expense", result)
amount_entry.delete(0, [Link])
spender_entry.delete(0, [Link])
update_balance_label() # Update balance label after adding an expense
except ValueError:
[Link]("Input Error", "Please enter a valid amount.")
def show_expenses():
""" Show all expenses """
summary = budget.display_expenses()
[Link]("Expense Summary", summary)
def visualize_expenses():
""" Show expenses graphically """
# Clear any previous plot before showing new one
for widget in root.grid_slaves():
if isinstance(widget, [Link]):
widget.grid_forget()
# Show updated graph
budget.plot_expenses(root)
def save_and_exit():
""" Save data and exit """
budget.save_data()
[Link]()
def add_balance():
""" Add money to the balance """
try:
amount = float(balance_entry.get())
result = budget.add_balance(amount)
[Link]("Add Balance", result)
balance_entry.delete(0, [Link])
update_balance_label() # Update balance label after adding money
except ValueError:
[Link]("Input Error", "Please enter a valid amount.")
def update_balance_label():
""" Update the balance display label """
balance_label.config(text=f"Current Balance: {[Link]}")
# Create main window
root = [Link]()
[Link]("Expense Tracker")
# Labels and Inputs
[Link](root, text="Expense Category:").grid(row=0, column=0, padx=10, pady=10)
category_var = [Link](root)
category_var.set("Groceries") # Default category
categories = ["Tax", "Groceries", "Children's School Fees", "Rent", "Utilities", "Entertainment",
"Savings"]
category_menu = [Link](root, category_var, *categories)
category_menu.grid(row=0, column=1, padx=10, pady=10)
[Link](root, text="Amount:").grid(row=1, column=0, padx=10, pady=10)
amount_entry = [Link](root)
amount_entry.grid(row=1, column=1, padx=10, pady=10)
[Link](root, text="Spender's Name:").grid(row=2, column=0, padx=10, pady=10)
spender_entry = [Link](root)
spender_entry.grid(row=2, column=1, padx=10, pady=10)
# Display Current Balance
balance_label = [Link](root, text=f"Current Balance: {[Link]}")
balance_label.grid(row=5, column=0, columnspan=2, pady=10)
[Link](root, text="Add Balance:").grid(row=6, column=0, padx=10, pady=10)
balance_entry = [Link](root)
balance_entry.grid(row=6, column=1, padx=10, pady=10)
# Buttons
[Link](root, text="Add Expense", command=add_expense).grid(row=3, column=0, padx=10,
pady=10)
[Link](root, text="Show Expenses", command=show_expenses).grid(row=3, column=1, padx=10,
pady=10)
[Link](root, text="Visualize Expenses", command=visualize_expenses).grid(row=4, column=0,
padx=10, pady=10)
[Link](root, text="Save and Exit", command=save_and_exit).grid(row=4, column=1, padx=10,
pady=10)
[Link](root, text="Add Balance", command=add_balance).grid(row=7, column=0, columnspan=2,
pady=10)
[Link]()
if __name__ == "__main__":
create_gui()