Izradite ovu jednostavnu aplikaciju za vježbanje matematičkog programiranja i usput naučite nešto o GUI kodiranju.
Praćenje troškova bitan je alat koji pomaže pojedincima i tvrtkama u upravljanju njihovim financijskim transakcijama. Pomoću alata za praćenje troškova možete izraditi proračune, kategorizirati troškove i analizirati obrasce potrošnje.
Saznajte kako izraditi aplikaciju za praćenje troškova, s višeplatformskim GUI-jem, u Pythonu.
Tkinter, CSV i Matplotlib moduli
Za izradu ovog uređaja za praćenje troškova trebat će vam moduli Tkinter, CSV i Matplotlib.
Tkinter vam omogućuje kreirati desktop aplikacije. Nudi razne widgete kao što su gumbi, oznake i tekstualni okviri koji olakšavaju razvoj aplikacija.
CSV modul je ugrađena Python biblioteka koja pruža funkcionalnost za čitanje i pisanje CSV (vrijednosti odvojene zarezima) datoteke.
Uz Matplotlib možete izraditi interaktivne vizualizacije kao što su grafikoni, dijagrami i dijagrami. Korištenje s modulima kao što je OpenCV može vam pomoći ovladati tehnikama poboljšanja slike isto.
Da biste instalirali ove module, pokrenite:
pip install tk matplotlib
Definirajte strukturu aplikacije za praćenje troškova
Izvorni kod ovog projekta možete pronaći u GitHub spremište.
Započnite s uvozom potrebnih modula. Definirajte klasu, ExpenseTrackerApp. Postavite naslov i dimenzije. Definirajte popis za pohranjivanje troškova i drugi za kategorije. Inicijalizirati a StringVar imenovani kategorija_var i postavite početnu vrijednost na prvu kategoriju na popisu kategorija. Završite pozivom na create_widgets metoda.
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()
The create_widgets metoda odgovorna je za dodavanje komponenti korisničkog sučelja vašoj aplikaciji. Stvorite okvir za oznake i unose evidencije troškova. Napravite šest oznaka: po jednu za naslov, iznos troška, opis stavke, kategoriju, datum i ukupni trošak. Postavite nadređeni element za svaki, tekst koji bi trebao prikazati i njegov stil fonta.
Izradite tri widgeta za unos i a Combobox da biste dobili odgovarajući unos. Za widgete za unos postavite nadređeni element, stil fonta i širinu. Definirajte nadređeni element, popis vrijednosti, stil fonta i širinu za Combobox. Vezati kategorija_var na njega, tako da se odabrana vrijednost automatski ažurira.
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)
Definirajte pet gumba: Dodaj trošak, Uredi trošak, Izbriši trošak, Uštedite troškove, i Prikaži grafikon troškova. Postavite nadređeni element za svaki, tekst koji bi trebao prikazati i naredbu koju će pokrenuti kada kliknete na njega. Napravite okvir za popisni okvir. Postavite nadređeni element, stil fonta i širinu.
Napravite okomitu traku za pomicanje i postavite je na desnu stranu okvira. Koristite ga za pomicanje kroz sadržaj okvira s popisom. Organizirajte sve elemente s potrebnim oblogama i nazovite 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()
Definirajte funkcionalnost Praćenja troškova
Definirajte metodu, dodati_trošak. Dohvaćanje vrijednosti troška, stavke, kategorije i datuma. Ako su vrijednost troška i datum valjani, dodajte trošak u troškovi popis. Umetnite ovaj zapis u okvir s popisom i oblikujte ga na odgovarajući način. Nakon umetanja, izbrišite korisnički unos u okvirima za novi unos.
U suprotnom, prikazati upozorenje da vrijednosti troška i datuma ne mogu biti prazne. Poziv ažuriranje_ukupne_oznake.
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()
Definirajte metodu, edit_expense. Dohvatite indeks odabranog zapisa i dohvatite trošak. Otvorite dijaloški okvir tražeći unos troška. Ako je korisnik naveo novi trošak, u skladu s tim promijenite popis troškova. Nazovite Osvježi popis i ažuriranje_ukupne_oznake.
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()
Definirajte metodu, brisati_trošak. Dohvatite indeks odabranog zapisa i dohvatite trošak. Proslijedite indeks unosa koji želite izbrisati. Izbrišite taj unos s popisa i nazovite ažuriranje_ukupne_oznake.
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()
Definirajte metodu, Osvježi popis. Izbrišite postojeći zapis i umjesto toga dodajte novi zapis s ažuriranim vrijednostima.
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})"
)
Definirajte metodu, ažuriranje_ukupne_oznake. Izračunajte zbroj svih troškova u popisu i ažurirajte ga na naljepnici. Definirajte drugu metodu, uštedi_troškove. Stvorite i otvorite a CSV datoteka pod nazivom troškovi.csv u načinu pisanja. Dodajte zaglavlja stupaca u CSV datoteku kao prvi redak. Iterirajte svaki zapis troška i zapišite ga kao red.
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))
Definirajte metodu, prikaži grafikon_troškova. Definirajte rječnik, kategorija_ukupno. Ponavljaj kroz troškovi navedite i pretvorite iznos rashoda u pokretni. Pohranite ukupni iznos troškova za svaku kategoriju. Ako kategorija već postoji u rječniku, povećajte ukupan iznos za iznos tekućeg troška. U suprotnom, kreirajte novi unos s trenutnim iznosom troška.
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
Izdvojite kategorije i troškove u dva različita popisa. Stvorite novu figuru za dijagram s navedenom veličinom. Generirajte tortni grafikon, koristeći popis troškova kao podatke i popis kategorija kao oznaku. The autopct parametar određuje format za prikaz postotnih vrijednosti na presjecima grafikona. Proći jednak do plt.os kako biste osigurali da kružni grafikon nacrtate kao krug. Postavite naslov tortnog grafikona i prikažite ga.
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()
Stvorite instancu ExpenseTrackerApp razreda. The glavna petlja() funkcija govori Pythonu da pokrene Tkinter petlju događaja i osluškuje događaje dok ne zatvorite prozor.
if __name__ == "__main__":
app = ExpenseTrackerApp()
app.mainloop()
Testirajte različite značajke Python Expense Trackera
Kada pokrenete program, on će pokrenuti prozor aplikacije. Ima polja za unos za bilježenje troškova, opis stavke, kategoriju i datum. Unesite neke podatke i kliknite Dodaj trošak dugme; vidjet ćete da se zapis dodaje u okvir s popisom. Program također ažurira ukupne troškove.
Odaberite zapis i kliknite Uredi troškove dugme. Pojavljuje se dijaloški okvir koji vam omogućuje ažuriranje pojedinačnog zapisa.
Klikom na Izbriši troškove gumb za uklanjanje odabranog zapisa.
Pri udaru u Prikaži grafikon troškova gumb, program prikazuje tortni grafikon. Tortni grafikon prikazuje trošak za svaku kategoriju zajedno s njezinim nazivom i postotkom.
Poboljšanje Praćenja troškova
Možete dodati funkciju pretraživanja kako biste korisnicima omogućili pronalaženje određenih troškova na temelju njihovog opisa, iznosa, kategorije ili datuma. Možete dodati opciju sortiranja i filtriranja zapisa. Lokalizirajte aplikaciju da podržava različite jezike i formate valuta.
Također možete proširiti aplikaciju podrškom za obavijesti. Neka korisnik postavi upozorenja kako bi spriječio prekoračenje proračunskih ograničenja ili istaknuo neuobičajenu potrošnju.