Bygg den här enkla appen för att öva på din matematikprogrammering och lära dig lite om GUI-kodning på vägen.

En utgiftsspårare är ett viktigt verktyg som hjälper individer och företag att hantera sina finansiella transaktioner. Med en utgiftsspårare kan du skapa budgetar, kategorisera utgifter och analysera utgiftsmönster.

Ta reda på hur du bygger en utgiftsspårningsapp, med ett gränssnitt för flera plattformar, i Python.

Modulerna Tkinter, CSV och Matplotlib

För att bygga denna utgiftsspårare behöver du modulerna Tkinter, CSV och Matplotlib.

Tkinter låter dig skapa skrivbordsapplikationer. Den erbjuder en mängd olika widgets som knappar, etiketter och textrutor som gör det enkelt att utveckla appar.

CSV-modulen är ett inbyggt Python-bibliotek som ger funktionalitet för läsning och skrivning CSV-filer (kommaseparerade värden)..

Med Matplotlib kan du bygga interaktiva visualiseringar som grafer, plotter och diagram. Att använda det med moduler som OpenCV kan hjälpa dig behärska bildförbättringstekniker för.

instagram viewer

För att installera dessa moduler, kör:

pip install tk matplotlib 

Definiera strukturen för Expense Tracker-appen

Du kan hitta detta projekts källkod i dess GitHub-förråd.

Börja med att importera de nödvändiga modulerna. Definiera en klass, ExpenseTrackerApp. Ställ in titeln och måtten. Definiera en lista för att lagra utgifterna och en annan för kategorierna. Initiera a StringVar som heter kategori_var och ställ in dess initiala värde till den första kategorin i kategorilistan. Avsluta med att ringa skapa_widgets metod.

import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import csv
import matplotlib.pyplot as plt

classExpenseTrackerApp(tk.Tk):
def__init__(self):
super().__init__()
self.title("Expense Tracker")
self.geometry("1300x600")
self.expenses = []
self.categories = [
"Food",
"Transportation",
"Utilities",
"Entertainment",
"Other",
]
self.category_var = tk.StringVar(self)
self.category_var.set(self.categories[0])
self.create_widgets()

De skapa_widgets metod är ansvarig för att lägga till UI-komponenter i din app. Skapa en ram för utgiftspostens etiketter och poster. Skapa sex etiketter: en vardera för rubrik, kostnadsbelopp, artikelbeskrivning, kategori, datum och total kostnad. Ställ in var och ens överordnade element, texten den ska visa och dess teckensnittsstil.

Skapa tre ingångswidgetar och en Kombinationsrutan för att få motsvarande input. För inmatningswidgetarna ställer du in det överordnade elementet, teckensnittsstilen och bredden. Definiera det överordnade elementet, värdelistan, teckensnittsstilen och bredden för Kombinationsrutan. Binda kategori_var till det, så att det valda värdet uppdateras automatiskt.

defcreate_widgets(self):
self.label = tk.Label(
self, text="Expense Tracker", font=("Helvetica", 20, "bold")
)
self.label.pack(pady=10)
self.frame_input = tk.Frame(self)
self.frame_input.pack(pady=10)
self.expense_label = tk.Label(
self.frame_input, text="Expense Amount:", font=("Helvetica", 12)
)
self.expense_label.grid(row=0, column=0, padx=5)
self.expense_entry = tk.Entry(
self.frame_input, font=("Helvetica", 12), width=15
)
self.expense_entry.grid(row=0, column=1, padx=5)
self.item_label = tk.Label(
self.frame_input, text="Item Description:", font=("Helvetica", 12)
)
self.item_label.grid(row=0, column=2, padx=5)
self.item_entry = tk.Entry(self.frame_input, font=("Helvetica", 12), width=20)
self.item_entry.grid(row=0, column=3, padx=5)
self.category_label = tk.Label(
self.frame_input, text="Category:", font=("Helvetica", 12)
)
self.category_label.grid(row=0, column=4, padx=5)
self.category_dropdown = ttk.Combobox(
self.frame_input,
textvariable=self.category_var,
values=self.categories,
font=("Helvetica", 12),
width=15,
)
self.category_dropdown.grid(row=0, column=5, padx=5)
self.date_label = tk.Label(
self.frame_input, text="Date (YYYY-MM-DD):", font=("Helvetica", 12)
)
self.date_label.grid(row=0, column=6, padx=5)
self.date_entry = tk.Entry(self.frame_input, font=("Helvetica", 12), width=15)
self.date_entry.grid(row=0, column=7, padx=5)

Definiera fem knappar: Lägg till kostnad, Redigera kostnad, Ta bort kostnad, Spara utgifter, och Visa kostnadsdiagram. Ställ in det överordnade elementet för var och en, texten den ska visa och kommandot den kommer att köra när du klickar på den. Skapa en ram för listrutan. Ställ in det överordnade elementet, teckensnittsstilen och bredden.

Skapa en vertikal rullningslist och placera den på höger sida av ramen. Använd den för att bläddra igenom innehållet i listrutan. Organisera alla element med nödvändig utfyllnad och ring update_total_label().

 self.add_button = tk.Button(self, text="Add Expense", command=self.add_expense)
self.add_button.pack(pady=5)
self.frame_list = tk.Frame(self)
self.frame_list.pack(pady=10)
self.scrollbar = tk.Scrollbar(self.frame_list)
self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.expense_listbox = tk.Listbox(
self.frame_list,
font=("Helvetica", 12),
width=70,
yscrollcommand=self.scrollbar.set,
)
self.expense_listbox.pack(pady=5)
self.scrollbar.config(command=self.expense_listbox.yview)
self.edit_button = tk.Button(
self, text="Edit Expense", command=self.edit_expense
)
self.edit_button.pack(pady=5)
self.delete_button = tk.Button(
self, text="Delete Expense", command=self.delete_expense
)
self.delete_button.pack(pady=5)
self.save_button = tk.Button(
self, text="Save Expenses", command=self.save_expenses
)
self.save_button.pack(pady=5)
self.total_label = tk.Label(
self, text="Total Expenses:", font=("Helvetica", 12)
)
self.total_label.pack(pady=5)
self.show_chart_button = tk.Button(
self, text="Show Expenses Chart", command=self.show_expenses_chart
)
self.show_chart_button.pack(pady=5)
self.update_total_label()

Definiera funktionen för utgiftsspåraren

Definiera en metod, add_expense. Hämta värdet på utgiften, artikeln, kategorin och datumet. Om utgiftens värde och datum är giltiga, lägg till utgiften till utgifter lista. Infoga denna post i listrutan och formatera den på lämpligt sätt. När den har infogats, radera användarinmatningen i inmatningsrutorna för ny inmatning.

Annars, visa en varning om att värdena för kostnad och datum inte kan vara tomma. Ring upp update_total_label.

defadd_expense(self):
expense = self.expense_entry.get()
item = self.item_entry.get()
category = self.category_var.get()
date = self.date_entry.get()
if expense and date:
self.expenses.append((expense, item, category, date))
self.expense_listbox.insert(
tk.END, f"{expense} - {item} - {category} ({date})"
)
self.expense_entry.delete(0, tk.END)
self.item_entry.delete(0, tk.END)
self.date_entry.delete(0, tk.END)
else:
messagebox.showwarning("Warning", "Expense and Date cannot be empty.")
self.update_total_label()

Definiera en metod, edit_expense. Hämta indexet för den valda posten och få kostnaden. Öppna en dialogruta och ber dig att ange kostnaden. Om användaren angav en ny utgift, ändra utgiftslistan i enlighet med detta. Ring refresh_list och update_total_label.

defedit_expense(self):
selected_index = self.expense_listbox.curselection()
if selected_index:
selected_index = selected_index[0]
selected_expense = self.expenses[selected_index]
new_expense = simpledialog.askstring(
"Edit Expense", "Enter new expense:", initialvalue=selected_expense[0]
)
if new_expense:
self.expenses[selected_index] = (
new_expense,
selected_expense[1],
selected_expense[2],
selected_expense[3],
)
self.refresh_list()
self.update_total_label()

Definiera en metod, delete_expense. Hämta indexet för den valda posten och få kostnaden. Passera indexet för posten du vill radera. Ta bort posten från listrutan och ring update_total_label.

defdelete_expense(self):
selected_index = self.expense_listbox.curselection()
if selected_index:
selected_index = selected_index[0]
del self.expenses[selected_index]
self.expense_listbox.delete(selected_index)
self.update_total_label()

Definiera en metod, refresh_list. Ta bort den befintliga posten och lägg till en ny post med de uppdaterade värdena istället.

defrefresh_list(self):
self.expense_listbox.delete(0, tk.END)
for expense, item, category, date in self.expenses:
self.expense_listbox.insert(
tk.END, f"{expense} - {item} - {category} ({date})"
)

Definiera en metod, update_total_label. Beräkna summan av alla utgifter i listan och uppdatera den på etiketten. Definiera en annan metod, spara_kostnader. Skapa och öppna en CSV fil namngiven utgifter.csv i skrivläge. Lägg till kolumnrubriker i CSV-filen som den första raden. Iterera över varje utgiftspost och skriv den som en rad.

defupdate_total_label(self):
total_expenses = sum(float(expense[0]) for expense in self.expenses)
self.total_label.config(text=f"Total Expenses: USD {total_expenses:.2f}")

defsave_expenses(self):
with open("expenses.csv", "w", newline="") as csvfile:
writer = csv.writer(csvfile)
column_headers = ["Expense Amount", "Item Description", "Category", "Date"]
writer.writerow(column_headers)
for expense in self.expenses:
writer.writerow(expense))

Definiera en metod, show_expenses_chart. Definiera en ordbok, kategori_total. Iterera genom utgifter lista och konvertera utgiftsbeloppet till flytande. Lagra det totala kostnadsbeloppet för varje kategori. Om kategorin redan finns i ordboken, öka summan med det aktuella utgiftsbeloppet. Skapa annars en ny post med aktuellt utgiftsbelopp.

defshow_expenses_chart(self):
category_totals = {}
for expense, _, category, _ in self.expenses:
try:
amount = float(expense)
except ValueError:
continue
category_totals[category] = category_totals.get(category, 0) + amount

Extrahera kategorierna och utgifterna i två olika listor. Skapa en ny figur för tomten med angiven storlek. Skapa ett cirkeldiagram, använd utgiftslistan som data och kategorilistan som etikett. De autopkt parameter anger formatet för visning av procentvärdena på diagramskivorna. Passera likvärdig till plt.axel för att säkerställa att du ritar cirkeldiagrammet som en cirkel. Ställ in titeln på cirkeldiagrammet och visa det.

 categories = list(category_totals.keys())
expenses = list(category_totals.values())
plt.figure(figsize=(8, 6))
plt.pie(
expenses, labels=categories, autopct="%1.1f%%", startangle=140, shadow=True
)
plt.axis("equal")
plt.title(f"Expense Categories Distribution (USD)")
plt.show()

Skapa en instans av ExpenseTrackerApp klass. De mainloop() funktionen säger åt Python att köra Tkinter-händelsslingan och lyssna efter händelser tills du stänger fönstret.

if __name__ == "__main__":
app = ExpenseTrackerApp()
app.mainloop()

Testa olika funktioner i Python Expense Tracker

När du kör programmet kommer det att starta ett programfönster. Detta har inmatningsfält för att registrera utgiften, artikelbeskrivningen, kategorin och datumet. Ange några uppgifter och klicka på Lägg till kostnad knapp; du ser att posten läggs till i listrutan. Programmet uppdaterar också de totala kostnaderna.

Välj en post och klicka på Redigera utgifter knapp. En dialogruta visas som låter dig uppdatera den individuella posten.

Genom att klicka på Ta bort utgifter för att ta bort den valda posten.

På att slå Visa kostnadsdiagram knappen visar programmet ett cirkeldiagram. Cirkeldiagrammet visar kostnaden för varje kategori tillsammans med dess namn och procent.

Förbättra utgiftsspåraren

Du kan lägga till sökfunktioner för att låta användare hitta specifika utgifter baserat på deras beskrivning, belopp, kategori eller datum. Du kan lägga till ett alternativ för att sortera och filtrera poster. Lokalisera appen för att stödja olika språk och valutaformat.

Du kan också utöka appen med stöd för aviseringar. Låt användaren ställa in varningar för att förhindra dem från att överskrida budgetgränser eller markera ovanliga utgifter.