Építsd meg ezt az egyszerű alkalmazást a matematikai programozás gyakorlásához, és tanulj meg egy kicsit a GUI kódolásról az út során.

A költségkövető alapvető eszköz, amely segít az egyéneknek és a vállalkozásoknak pénzügyi tranzakcióik kezelésében. A költségkövető segítségével költségvetéseket hozhat létre, kategorizálhatja a kiadásokat és elemezheti a kiadási mintákat.

Ismerje meg, hogyan hozhat létre költségkövető alkalmazást többplatformos grafikus felhasználói felülettel Pythonban.

A Tkinter, CSV és Matplotlib modulok

Ennek a költségkövetőnek az elkészítéséhez szüksége lesz a Tkinter, CSV és Matplotlib modulokra.

Tkinter lehetővé teszi asztali alkalmazások létrehozása. Számos widgetet kínál, például gombokat, címkéket és szövegdobozokat, amelyek megkönnyítik az alkalmazások fejlesztését.

A CSV-modul egy beépített Python-könyvtár, amely olvasási és írási funkciókat biztosít CSV (vesszővel tagolt értékek) fájlokat.

A Matplotlib segítségével interaktív vizualizációkat, például grafikonokat, diagramokat és diagramokat készíthet. Használata olyan modulokkal, mint az OpenCV, segíthet

instagram viewer
képjavító technikák elsajátítása is.

A modulok telepítéséhez futtassa:

pip install tk matplotlib 

Határozza meg a Költségkövető alkalmazás szerkezetét

A projekt forráskódja megtalálható benne GitHub adattár.

Kezdje a szükséges modulok importálásával. Határozzon meg egy osztályt, ExpenseTrackerApp. Állítsa be a címet és a méreteket. Határozzon meg egy listát a kiadások tárolásához, egy másikat pedig a kategóriákhoz. Inicializálás a StringVar nevezett kategória_var és állítsa be a kezdeti értékét a kategórialista első kategóriájára. Fejezze be a telefonszámot create_widgets módszer.

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()

A create_widgets metódus felelős azért, hogy UI összetevőket adjon hozzá az alkalmazáshoz. Hozzon létre egy keretet a költségrekord címkéihez és bejegyzéseihez. Hozzon létre hat címkét: egy-egy címkét a címsorhoz, a kiadás összegéhez, a cikk leírásához, a kategóriához, a dátumhoz és a teljes költséghez. Állítsa be mindegyik szülőelemét, a megjelenítendő szöveget és a betűtípus stílusát.

Hozzon létre három bejegyzés widgetet és a Combobox hogy megkapjuk a megfelelő bemenetet. A bejegyzés widgetekhez állítsa be a szülőelemet, a betűstílust és a szélességet. Határozza meg a szülőelemet, az értékek listáját, a betűtípus stílusát és a szélességét Combobox. Bind kategória_var hozzá, így a kiválasztott érték automatikusan frissül.

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)

Határozzon meg öt gombot: Költség hozzáadása, Költség szerkesztése, Költség törlése, Költségek megtakarítása, és Költségek diagram megjelenítése. Állítsa be mindegyik szülőelemét, a megjelenítendő szöveget és a kattintáskor futtatandó parancsot. Hozzon létre egy keretet a listadobozhoz. Állítsa be a szülőelemet, a betűstílust és a szélességet.

Hozzon létre egy függőleges görgetősávot, és helyezze a keret jobb oldalára. Használja a listadoboz tartalmának görgetéséhez. Rendszerezze az összes elemet a szükséges párnázással és hívja 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()

Határozza meg a Költségkövető funkcióját

Határozzon meg egy módszert, add_expense. Keresse meg a költség, a tétel, a kategória és a dátum értékét. Ha a kiadás értéke és dátuma érvényes, adja hozzá a költséget a költségek lista. Helyezze be ezt a rekordot a listába, és formázza megfelelően. A beillesztés után törölje a felhasználói bevitelt az új bevitel beviteli mezőiből.

Ellenkező esetben jelenítsen meg egy figyelmeztetést, hogy a költség és a dátum értéke nem lehet üres. Hívás 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()

Határozzon meg egy módszert, edit_expense. Töltse le a kiválasztott rekord indexét, és kapja meg a költséget. Nyisson meg egy párbeszédpanelt, amelyben meg kell adnia a költséget. Ha a felhasználó új költséget adott meg, ennek megfelelően módosítsa a költséglistát. Hívja a lista frissítése és 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()

Határozzon meg egy módszert, törlés_költség. Töltse le a kiválasztott rekord indexét, és kapja meg a költséget. Adja át a törölni kívánt bejegyzés indexét. Törölje a bejegyzést a listából, és hívja a 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()

Határozzon meg egy módszert, lista frissítése. Törölje a meglévő rekordot, és adjon hozzá egy új rekordot a frissített értékekkel.

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})"
)

Határozzon meg egy módszert, update_total_label. Számítsa ki a listán szereplő összes költség összegét, és frissítse a címkén. Határozzon meg egy másik módszert, költségmegtakarítás. Hozzon létre és nyissa meg a CSV nevű fájl kiadások.csv írási módban. Adja hozzá az oszlopfejléceket a CSV-fájlhoz első sorként. Ismételje meg az egyes költségrekordokat, és írja be egy sorba.

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))

Határozzon meg egy módszert, show_expenses_chart. Szótár meghatározása, kategória_összegek. Iteráljon a költségek listázza ki és váltsa át a költségösszeget lebegővé. Tárolja el az egyes kategóriák teljes költségösszegét. Ha a kategória már létezik a szótárban, növelje a végösszeget az aktuális kiadási összeggel. Ellenkező esetben hozzon létre egy új bejegyzést az aktuális költségösszeggel.

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

Bontsa ki a kategóriákat és a költségeket két különböző listába. Hozzon létre egy új ábrát a telekre a megadott mérettel. Készítsen kördiagramot, adatként a költséglistát és címkeként a kategórialistát használva. A autopct paraméter határozza meg a százalékértékek diagramszeleteken való megjelenítésének formátumát. Pass egyenlő nak nek plt.tengely hogy a kördiagramot körként rajzolja meg. Állítsa be a kördiagram címét, és jelenítse meg.

 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()

Hozzon létre egy példányt a ExpenseTrackerApp osztály. A mainloop() függvény azt mondja a Pythonnak, hogy futtassa a Tkinter eseményhurkot, és figyelje az eseményeket, amíg be nem zárja az ablakot.

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

Tesztelje a Python Expense Tracker különböző funkcióit

A program futtatásakor egy alkalmazás ablakot indít el. Ennek beviteli mezői vannak a kiadás, a cikk leírása, a kategória és a dátum rögzítéséhez. Adjon meg néhány adatot, és kattintson a gombra Költség hozzáadása gomb; látni fogja, hogy a rekord hozzáadódik a listamezőhöz. A program frissíti a teljes kiadást is.

Válasszon ki egy rekordot, és kattintson a gombra Költségek szerkesztése gomb. Megjelenik egy párbeszédpanel, amely lehetővé teszi az egyedi rekord frissítését.

Kattintson a Költségek törlése gombot a kiválasztott rekord eltávolításához.

Az ütéskor a Költségek diagram megjelenítése gombot, a program egy kördiagramot jelenít meg. A kördiagram megjeleníti az egyes kategóriák költségeit a nevükkel és százalékos arányukkal együtt.

A költségkövető fejlesztése

Keresési funkciót is hozzáadhat, hogy a felhasználók konkrét kiadásokat találjanak leírásuk, összegük, kategóriájuk vagy dátumuk alapján. Lehetőséget adhat a rekordok rendezésére és szűrésére. Lokalizálja az alkalmazást a különböző nyelvek és pénznemformátumok támogatásához.

Az alkalmazást az értesítések támogatásával is bővítheti. Engedje meg, hogy a felhasználó riasztásokat állítson be, hogy megakadályozza a költségvetési korlátok túllépését, vagy kiemelje a szokatlan kiadásokat.