Създайте това просто приложение, за да практикувате математическото си програмиране и да научите малко за GUI кодирането по пътя.
Инструментът за проследяване на разходите е основен инструмент, който помага на хората и фирмите да управляват своите финансови транзакции. С инструмент за проследяване на разходите можете да създавате бюджети, да категоризирате разходите и да анализирате моделите на разходите.
Научете как да изградите приложение за проследяване на разходи с междуплатформен GUI в Python.
Модулите Tkinter, CSV и Matplotlib
За да създадете този инструмент за проследяване на разходите, ще ви трябват модулите Tkinter, CSV и Matplotlib.
Tkinter ви позволява създаване на настолни приложения. Той предлага разнообразие от приспособления като бутони, етикети и текстови полета, които улесняват разработването на приложения.
CSV модулът е вградена библиотека на Python, която предоставя функционалност за четене и писане CSV (стойности, разделени със запетая) файлове.
С Matplotlib можете да създавате интерактивни визуализации като графики, графики и диаграми. Използването му с модули като OpenCV може да ви помогне
овладейте техники за подобряване на изображението също.За да инсталирате тези модули, изпълнете:
pip install tk matplotlib
Определете структурата на приложението за проследяване на разходите
Можете да намерите изходния код на този проект в него GitHub хранилище.
Започнете с импортиране на необходимите модули. Определете клас, ExpenseTrackerApp. Задайте заглавието и размерите. Дефинирайте списък за съхраняване на разходите и друг за категориите. Инициализирайте a StringVar на име категория_вар и задайте първоначалната му стойност на първата категория в списъка с категории. Завършете, като се обадите на create_widgets метод.
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 методът отговаря за добавянето на UI компоненти към вашето приложение. Създайте рамка за етикетите и записите на записа на разходите. Създайте шест етикета: по един за заглавие, сума на разходите, описание на артикул, категория, дата и общ разход. Задайте родителския елемент на всеки един, текста, който трябва да показва, и неговия стил на шрифта.
Създайте три приспособления за въвеждане и a Комбобокс за да получите съответния вход. За приспособленията за въвеждане задайте родителския елемент, стила на шрифта и ширината. Дефинирайте родителския елемент, списъка със стойности, стила на шрифта и ширината за Комбобокс. Обвързване категория_вар към него, така че избраната стойност се актуализира автоматично.
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)
Определете пет бутона: Добавяне на разходи, Редактиране на разходите, Изтриване на разходите, Спестете разходи, и Показване на диаграмата на разходите. Задайте родителския елемент на всеки, текста, който трябва да показва, и командата, която ще изпълнява, когато щракнете върху него. Създайте рамка за списъка. Задайте родителския елемент, стила на шрифта и ширината.
Създайте вертикална лента за превъртане и я поставете от дясната страна на рамката. Използвайте го, за да превъртате през съдържанието на списъка. Организирайте всички елементи с необходимата подложка и се обадете 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()
Определете функционалността на инструмента за проследяване на разходите
Определете метод, add_expense. Извлечете стойността на разхода, артикула, категорията и датата. Ако стойността на разхода и датата са валидни, добавете разхода към разходи списък. Вмъкнете този запис в списъка и го форматирайте по подходящ начин. След като бъде вмъкнат, изтрийте въведеното от потребителя в полетата за ново въвеждане.
В противен случай покажете предупреждение, че стойностите на разходите и датата не могат да бъдат празни. Обадете се 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()
Определете метод, редактиране_разходи. Извлечете индекса на избрания запис и вземете разходите. Отворете диалогов прозорец с молба да въведете разхода. Ако потребителят предостави нов разход, променете съответно списъка с разходите. Обадете се на refresh_list и 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()
Определете метод, изтриване_разходи. Извлечете индекса на избрания запис и вземете разходите. Предайте индекса на записа, който искате да изтриете. Изтрийте този запис от списъка и извикайте 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()
Определете метод, refresh_list. Изтрийте съществуващия запис и вместо това добавете нов запис с актуализираните стойности.
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})"
)
Определете метод, update_total_label. Изчислете сумата на всички разходи в списъка и я актуализирайте на етикета. Определете друг метод, спестяване на_разходи. Създайте и отворете a CSV файл с име разходи.csv в режим на запис. Добавете заглавки на колони към CSV файла като първи ред. Прегледайте всеки запис на разход и го напишете като ред.
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))
Определете метод, покажи_разходи_диаграма. Определете речник, категория_общо. Итерация през разходи избройте и преобразувайте сумата на разходите в плаваща. Съхранявайте общата сума на разходите за всяка категория. Ако категорията вече съществува в речника, увеличете общата сума с текущата сума на разходите. В противен случай създайте нов запис с текущата сума на разходите.
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
Извлечете категориите и разходите в два различни списъка. Създайте нова фигура за графиката с посочения размер. Генерирайте кръгова диаграма, като използвате списъка с разходите като данни и списъка с категории като етикет. The autopct параметърът определя формата за показване на процентните стойности върху срезовете на диаграмата. Пас равен да се плт.ос за да сте сигурни, че начертавате кръговата диаграма като кръг. Задайте заглавието на кръговата диаграма и я покажете.
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()
Създайте екземпляр на ExpenseTrackerApp клас. The mainloop() функцията казва на Python да стартира цикъла на събитията на Tkinter и да слуша за събития, докато затворите прозореца.
if __name__ == "__main__":
app = ExpenseTrackerApp()
app.mainloop()
Тествайте различни функции на Python Expense Tracker
Когато стартирате програмата, тя ще стартира прозорец на приложението. Това има полета за въвеждане за запис на разходите, описанието на артикула, категорията и датата. Въведете някои данни и щракнете върху Добавяне на разходи бутон; ще видите, че записът се добавя към списъка. Програмата актуализира и общите разходи.
Изберете запис и щракнете върху Редактиране на разходите бутон. Появява се диалогов прозорец, който ви позволява да актуализирате отделния запис.
Щраквайки върху Изтриване на разходи бутон за премахване на избрания запис.
При удряне на Показване на диаграмата на разходите бутон, програмата показва кръгова диаграма. Кръговата диаграма показва разходите за всяка категория заедно с нейното име и процент.
Подобряване на инструмента за проследяване на разходите
Можете да добавите функция за търсене, за да позволите на потребителите да намират конкретни разходи въз основа на тяхното описание, сума, категория или дата. Можете да добавите опция за сортиране и филтриране на записи. Локализирайте приложението, за да поддържа различни езици и валутни формати.
Можете също така да разширите приложението с поддръжка за известия. Позволете на потребителя да настрои сигнали, за да им попречи да превишат бюджетните лимити или да подчертаят всякакви необичайни разходи.