Jak zbudować narzędzie do śledzenia wydatków w Pythonie?
Narzędzie do śledzenia wydatków jest niezbędnym narzędziem, które pomaga osobom fizycznym i firmom zarządzać ich transakcjami finansowymi. Dzięki narzędziu do śledzenia wydatków można tworzyć budżety, kategoryzować wydatki i analizować wzorce wydatków.
Poznaj metody tworzenia wieloplatformowej aplikacji z graficznym interfejsem użytkownika (GUI) do śledzenia wydatków przy użyciu języka programowania Python.
Moduły Tkinter, CSV i Matplotlib
W celu skonstruowania tej aplikacji do śledzenia wydatków konieczne jest wykorzystanie bibliotek Tkinter, CSV i Matplotlib.
Tkinter umożliwia programistom tworzenie atrakcyjnych aplikacji desktopowych, zapewniając szereg wszechstronnych komponentów graficznych, takich jak przyciski, etykiety i pola wprowadzania tekstu. Jego przyjazny dla użytkownika interfejs upraszcza proces tworzenia aplikacji do różnych celów.
Moduł CSV to nieodłączny pakiet Pythona, który oferuje funkcje związane z interpretacją i tworzeniem plików CSV (Comma-Separated Value), które są szeroko wykorzystywane do wymiany danych między różnymi aplikacjami i systemami ze względu na ich prostotę i kompatybilność z różnymi platformami.
Matplotlib to potężne narzędzie do tworzenia dynamicznych reprezentacji wizualnych, w tym wykresów, wykresów i wykresów, które można dodatkowo ulepszyć, łącząc je z OpenCV, aby zdobyć wiedzę na temat zaawansowanych technik manipulacji obrazem.
Aby zainstalować te moduły, uruchom:
pip install tk matplotlib
Define the Structure of the Expense Tracker App
Pochodzenie kodu źródłowego tego projektu znajduje się w wyznaczonym repozytorium GitHub, które służy jako cyfrowy depozyt dla wszystkich powiązanych plików i dokumentacji.
Aby rozpocząć, importujemy moduły imperatywne. Następnie tworzymy klasę o nazwie ExpenseTrackerApp
, która określa tytuł i wymiary aplikacji. Następnie definiujemy uporządkowaną parę list; jedna zawiera wszystkie zarejestrowane wydatki, podczas gdy druga obejmuje różne kategorie pieniężne. Tworzona jest również zmienna łańcuchowa o nazwie category_var
, z początkowym ustawieniem odpowiadającym pierwszej kategorii na naszej liście. Na koniec wywołujemy procedurę create_widgets
w celu stworzenia graficznego interfejsu użytkownika.
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
import csv
import matplotlib.pyplot as plt
class ExpenseTrackerApp(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()
Metoda create_widgets
służy jako istotny element w konstruowaniu interfejsów użytkownika w aplikacjach. Aby ustanowić ramy do wyświetlania informacji związanych z wydatkami, musimy wygenerować elementy wizualne składające się z ramek, które zawierają określone szczegóły związane z tymi rekordami.W szczególności opracujemy sześć oddzielnych widżetów etykiet; każdy przeznaczony do prezentacji odpowiednich danych, takich jak nagłówki, wartości pieniężne, opisy, kategorie, daty i ogólne sumy. Kluczowe jest przypisanie elementu nadrzędnego dla każdej etykiety, przy jednoczesnym określeniu ich odpowiednich tekstów i cech typograficznych.
Aby utworzyć interfejs z trzema wejściami tekstowymi i menu rozwijanym, należy ustanowić połączenie między tym ostatnim a zmienną o nazwie category_var
. Rozpocznij od zdefiniowania układu dla każdego z tych elementów; określ ich odpowiednie style czcionek i wymiary w następujący sposób:1. Utwórz trzy widżety Entry i przypisz im indywidualne kontenery nadrzędne, opcje stylizacji i ograniczenia szerokości.2. Skonstruuj widżet Combobox, zdefiniuj jego kontener nadrzędny, listę dostępnych wyborów, styl czcionki i specyfikacje wymiarowe.3. Powiąż Combobox ze zmienną category_var
, zapewniając w ten sposób, że wybór w menu rozwijanym będzie aktualizowany w czasie rzeczywistym w oparciu o interakcję użytkownika.
def create_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)
Utwórz interfejs użytkownika z następującymi komponentami:Przycisk o nazwie “Add Expense”, który dodaje wydatek do listy;Przycisk o nazwie “Edit Expense”, który edytuje istniejący wydatek na liście;Przycisk o nazwie “Delete Expense”, który usuwa wydatek z listy;Przycisk o nazwie “Save Expenses”, który zapisuje wszystkie wydatki na liście;Przycisk o nazwie “Show Expenses Chart”, który wyświetla wykres wydatków na liście;Ramka otaczająca te przyciski z tytułem “Expense Manager”.
Włącz funkcjonalność tworzenia pionowego paska przewijania, który jest umieszczony po prawej stronie głównego obszaru zawartości GUI, umożliwiając płynną nawigację po zawartości w polu listy. Wykorzystanie odpowiednich technik wypełniania zapewnia optymalną prezentację wizualną. Ponadto, po zaktualizowaniu całkowitej etykiety o nowe informacje, wykonaj wszelkie niezbędne korekty, aby zachować spójność w całym interfejsie.
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()
Zdefiniuj funkcjonalność narzędzia do śledzenia wydatków
Włącz podany fragment kodu do interfejsu istniejącej aplikacji jako sposób rejestrowania wydatków z określonymi kategoriami i datami, po czym walidacja wprowadzonych danych jest dodawana do dynamicznej listy wyświetlanej w graficznym interfejsie użytkownika, a następnie usuwa wszelkie dalsze obowiązki ręcznego wprowadzania danych przez użytkownika końcowego.
W przeciwnym razie konieczne jest wyświetlenie powiadomienia wskazującego, że wartości “wydatku” i “daty” nie mogą być puste. Następnie należy wykonać wywołanie funkcji update\_total\_label.
def add_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()
Aby zmodyfikować istniejący wydatek w bazie danych rekordów, można zaimplementować metodę o nazwie “edit\_expense”.Ta metoda pobierze indeks wybranego rekordu i uzyska odpowiadający mu wydatek. Następnie poprosi użytkownika o wprowadzenie nowej wartości wydatku w oknie dialogowym. Jeśli użytkownik poda nowy wydatek, metoda zaktualizuje listę wydatków o te informacje. Na koniec metoda wywołuje funkcję “refresh\_list”, a także podprogram “update\_total\_label”, aby upewnić się, że wszystkie zmiany są dokładnie odzwierciedlone w aplikacji.
def edit_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()
Aby zaimplementować funkcjonalność opisaną w podanym fragmencie kodu, zdefiniujemy metodę o nazwie delete_expense
, która pobiera indeks wybranego rekordu i pobiera odpowiadający mu wydatek. Następnie przekażemy ten indeks do funkcji, aby można go było usunąć z pola listy. Następnie wywołamy funkcję update_total_label
, aby upewnić się, że łączna etykieta zostanie odpowiednio zaktualizowana.
def delete_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()
Jasne! Oto przykład, jak można to zaimplementować w Pythonie przy użyciu Flask i SQLAlchemy:pythonfrom flask import gfrom sqlalchemy import create_engine, Column, Integer, String, ForeignKeyfrom sqlalchemy.orm import sessionmaker, relationshipfrom datetime import datetimeclass User(db.Model): tablename = ‘users’id = Column(‘id’, Integer, primary_key=True)name = Column(’name’, String)email = Column(’email’, String)created_at = Column(‘created_at’, DateTime, default=datetime.utcnow)updated_at = Column(‘updated_at’, DateTime, onupdate=datetime.utcnow)
def refresh_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})"
)
Aby dopracować dostarczony tekst, będę potrzebował więcej kontekstu na temat tego, co chcesz, abym zrobił z tym fragmentem kodu. Oto jednak moja próba nadania podanemu tekstowi bardziej wyrafinowanego brzmienia:pythondef update_total_label(expenses):total = sum(expenses)return totaldef save_expenses(filename=“expenses.csv”, expenses=None):if not expenses:expenses = []# Otwórz podany plik CSV lub utwórz go, jeśli nie istniejetry:with open(filename, “w”) as f:writer = csv.writer(f)# Write the header rowwriter.writerow([…])
def update_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}")
def save_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))
Aby zwizualizować rozkład miesięcznych wydatków w różnych kategoriach, możemy zaimplementować metodę o nazwie show_expenses_chart
, która przyjmuje jako dane wejściowe listę wydatków
. Najpierw zdefiniujmy słownik o nazwie category_totals
, który będzie służył jako licznik do gromadzenia całkowitych wydatków dla każdej kategorii wydatków. Będziemy iterować po wpisach na liście expenses
, konwertując każdą kwotę wydatku z łańcucha na liczbę zmiennoprzecinkową.Dla każdej kategorii, jeśli jest ona obecna w słowniku category_totals
, dodamy jej wartość klucza do istniejącej sumy; w przeciwnym razie utworzymy nową parę klucz-wartość reprezentującą bieżącą kwotę wydatków.
def show_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
Aby stworzyć wizualną reprezentację kategorycznego rozkładu wydatków w zbiorze danych, można wykorzystać funkcję pie matplotlib. Funkcja ta umożliwia wygenerowanie wykresu kołowego na podstawie podanych kwot wydatków i odpowiadających im kategorii. Ustawiając różne parametry, takie jak
autopct ,
equal i tytuł wykresu, użytkownicy mogą dostosować sposób wyświetlania końcowego wyniku.
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()
Wykorzystaj możliwości klasy ExpenseTrackerApp, tworząc jej instancję, a następnie aktywując pętlę zdarzeń Tkinter za pomocą metody mainloop(), która utrzymuje ciągłe monitorowanie interakcji użytkownika do momentu zamknięcia interfejsu graficznego.
if __name__ == "__main__":
app = ExpenseTrackerApp()
app.mainloop()
Testowanie różnych funkcji Python Expense Tracker
Po uruchomieniu programu uruchomiony zostanie graficzny interfejs użytkownika (GUI), zawierający pola wejściowe do rejestrowania istotnych szczegółów dotyczących wydatków, takich jak opis przedmiotu, kategoria i data, a także pola tekstowe do wprowadzania wartości liczbowych. Po wpisaniu tych informacji i kliknięciu przycisku “Dodaj wydatek” można oczekiwać, że nowy wpis zostanie dołączony do pola listy. Co więcej, dla wygody użytkownika program stale aktualizuje sumę wszystkich zarejestrowanych wydatków.
Po wybraniu konkretnego wydatku należy kliknąć przycisk “Edytuj wydatki”, aby rozpocząć proces edycji. Spowoduje to wyświetlenie okna dialogowego umożliwiającego modyfikację szczegółów wybranej pozycji wydatków w istniejącym kontekście.
Usunięcie określonego rekordu wydatków poprzez kliknięcie przycisku “Usuń wydatki”, co spowoduje usunięcie wybranej pozycji z listy wydatków.
Po kliknięciu przycisku “Pokaż wykres wydatków” oprogramowanie generuje graficzną reprezentację w postaci wykresu kołowego, który ilustruje rozkład wydatków w różnych kategoriach, wraz z ich odpowiednimi nazwami i wartościami procentowymi.
Ulepszanie narzędzia do śledzenia wydatków
W celu zwiększenia komfortu użytkowania możliwe jest włączenie funkcji wyszukiwania, która umożliwia użytkownikom zlokalizowanie określonych wydatków według ich opisu, wartości, klasyfikacji lub dat.Dodatkowo można zapewnić opcje sortowania i filtrowania rekordów danych. Korzystne byłoby dostosowanie aplikacji do różnych języków i stylów walutowych.
Rozważ włączenie funkcji powiadomień do aplikacji, umożliwiając użytkownikom ustalenie progów, które uruchamiają alerty po ich przekroczeniu. Alerty te mogą służyć jako ostrzeżenie przed nadmiernymi wydatkami i pomóc w identyfikacji nieregularnych wydatków.