Skip to content

Commit acdad94

Browse files
Create expense_tracker.py
1 parent 4c8527d commit acdad94

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

expense_tracker.py

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import tkinter as tk
2+
from tkinter import ttk, messagebox, simpledialog
3+
import csv
4+
import matplotlib.pyplot as plt
5+
6+
class ExpenseTrackerApp(tk.Tk):
7+
def __init__(self):
8+
super().__init__()
9+
self.title("Expense Tracker")
10+
self.geometry("1300x600")
11+
self.expenses = []
12+
self.categories = [
13+
"Food",
14+
"Transportation",
15+
"Utilities",
16+
"Entertainment",
17+
"Other",
18+
]
19+
self.category_var = tk.StringVar(self)
20+
self.category_var.set(self.categories[0])
21+
self.currencies = ["USD", "EUR", "GBP", "JPY", "INR"]
22+
self.create_widgets()
23+
24+
def create_widgets(self):
25+
self.label = tk.Label(
26+
self, text="Expense Tracker", font=("Helvetica", 20, "bold")
27+
)
28+
self.label.pack(pady=10)
29+
self.frame_input = tk.Frame(self)
30+
self.frame_input.pack(pady=10)
31+
self.expense_label = tk.Label(
32+
self.frame_input, text="Expense Amount:", font=("Helvetica", 12)
33+
)
34+
self.expense_label.grid(row=0, column=0, padx=5)
35+
self.expense_entry = tk.Entry(
36+
self.frame_input, font=("Helvetica", 12), width=15
37+
)
38+
self.expense_entry.grid(row=0, column=1, padx=5)
39+
self.item_label = tk.Label(
40+
self.frame_input, text="Item Description:", font=("Helvetica", 12)
41+
)
42+
self.item_label.grid(row=0, column=2, padx=5)
43+
self.item_entry = tk.Entry(self.frame_input, font=("Helvetica", 12), width=20)
44+
self.item_entry.grid(row=0, column=3, padx=5)
45+
self.category_label = tk.Label(
46+
self.frame_input, text="Category:", font=("Helvetica", 12)
47+
)
48+
self.category_label.grid(row=0, column=4, padx=5)
49+
self.category_dropdown = ttk.Combobox(
50+
self.frame_input,
51+
textvariable=self.category_var,
52+
values=self.categories,
53+
font=("Helvetica", 12),
54+
width=15,
55+
)
56+
self.category_dropdown.grid(row=0, column=5, padx=5)
57+
self.date_label = tk.Label(
58+
self.frame_input, text="Date (YYYY-MM-DD):", font=("Helvetica", 12)
59+
)
60+
self.date_label.grid(row=0, column=6, padx=5)
61+
self.date_entry = tk.Entry(self.frame_input, font=("Helvetica", 12), width=15)
62+
self.date_entry.grid(row=0, column=7, padx=5)
63+
self.add_button = tk.Button(self, text="Add Expense", command=self.add_expense)
64+
self.add_button.pack(pady=5)
65+
self.frame_list = tk.Frame(self)
66+
self.frame_list.pack(pady=10)
67+
self.scrollbar = tk.Scrollbar(self.frame_list)
68+
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
69+
self.expense_listbox = tk.Listbox(
70+
self.frame_list,
71+
font=("Helvetica", 12),
72+
width=70,
73+
yscrollcommand=self.scrollbar.set,
74+
)
75+
self.expense_listbox.pack(pady=5)
76+
self.scrollbar.config(command=self.expense_listbox.yview)
77+
self.edit_button = tk.Button(
78+
self, text="Edit Expense", command=self.edit_expense
79+
)
80+
self.edit_button.pack(pady=5)
81+
self.delete_button = tk.Button(
82+
self, text="Delete Expense", command=self.delete_expense
83+
)
84+
self.delete_button.pack(pady=5)
85+
self.save_button = tk.Button(
86+
self, text="Save Expenses", command=self.save_expenses
87+
)
88+
self.save_button.pack(pady=5)
89+
self.total_label = tk.Label(
90+
self, text="Total Expenses:", font=("Helvetica", 12)
91+
)
92+
self.total_label.pack(pady=5)
93+
self.show_chart_button = tk.Button(
94+
self, text="Show Expenses Chart", command=self.show_expenses_chart
95+
)
96+
self.show_chart_button.pack(pady=5)
97+
self.update_total_label()
98+
99+
def add_expense(self):
100+
expense = self.expense_entry.get()
101+
item = self.item_entry.get()
102+
category = self.category_var.get()
103+
date = self.date_entry.get()
104+
if expense and date:
105+
self.expenses.append((expense, item, category, date))
106+
self.expense_listbox.insert(
107+
tk.END, f"{expense} - {item} - {category} ({date})"
108+
)
109+
self.expense_entry.delete(0, tk.END)
110+
self.item_entry.delete(0, tk.END)
111+
self.date_entry.delete(0, tk.END)
112+
else:
113+
messagebox.showwarning("Warning", "Expense and Date cannot be empty.")
114+
self.update_total_label()
115+
116+
def edit_expense(self):
117+
selected_index = self.expense_listbox.curselection()
118+
if selected_index:
119+
selected_index = selected_index[0]
120+
selected_expense = self.expenses[selected_index]
121+
new_expense = simpledialog.askstring(
122+
"Edit Expense", "Enter new expense:", initialvalue=selected_expense[0]
123+
)
124+
if new_expense:
125+
self.expenses[selected_index] = (
126+
new_expense,
127+
selected_expense[1],
128+
selected_expense[2],
129+
selected_expense[3],
130+
)
131+
self.refresh_list()
132+
self.update_total_label()
133+
134+
def delete_expense(self):
135+
selected_index = self.expense_listbox.curselection()
136+
if selected_index:
137+
selected_index = selected_index[0]
138+
del self.expenses[selected_index]
139+
self.expense_listbox.delete(selected_index)
140+
self.update_total_label()
141+
142+
def refresh_list(self):
143+
self.expense_listbox.delete(0, tk.END)
144+
for expense, item, category, date in self.expenses:
145+
self.expense_listbox.insert(
146+
tk.END, f"{expense} - {item} - {category} ({date})"
147+
)
148+
149+
def update_total_label(self):
150+
total_expenses = sum(float(expense[0]) for expense in self.expenses)
151+
self.total_label.config(text=f"Total Expenses: USD {total_expenses:.2f}")
152+
153+
def save_expenses(self):
154+
with open("expenses.csv", "w", newline="") as csvfile:
155+
writer = csv.writer(csvfile)
156+
for expense, item, category, date in self.expenses:
157+
writer.writerow([expense, item, category, date])
158+
159+
def show_expenses_chart(self):
160+
category_totals = {}
161+
for expense, _, category, _ in self.expenses:
162+
try:
163+
amount = float(expense)
164+
except ValueError:
165+
continue
166+
category_totals[category] = category_totals.get(category, 0) + amount
167+
categories = list(category_totals.keys())
168+
expenses = list(category_totals.values())
169+
plt.figure(figsize=(8, 6))
170+
plt.pie(
171+
expenses, labels=categories, autopct="%1.1f%%", startangle=140, shadow=True
172+
)
173+
plt.axis("equal")
174+
plt.title(f"Expense Categories Distribution (USD)")
175+
plt.show()
176+
177+
if __name__ == "__main__":
178+
app = ExpenseTrackerApp()
179+
app.mainloop()

0 commit comments

Comments
 (0)