วิธีสร้างตัวติดตามค่าใช้จ่ายโดยใช้ Python
เครื่องมือติดตามค่าใช้จ่ายเป็นเครื่องมือสำคัญที่ช่วยให้บุคคลและธุรกิจจัดการธุรกรรมทางการเงินของตน ด้วยตัวติดตามค่าใช้จ่าย คุณสามารถสร้างงบประมาณ จัดหมวดหมู่ค่าใช้จ่าย และวิเคราะห์รูปแบบการใช้จ่ายได้
สำรวจวิธีการสร้างแอปพลิเคชันอินเทอร์เฟซผู้ใช้แบบกราฟิก (GUI) ข้ามแพลตฟอร์มสำหรับการติดตามค่าใช้จ่ายโดยใช้ภาษาการเขียนโปรแกรม Python
โมดูล Tkinter, CSV และ Matplotlib
ในการสร้างแอปพลิเคชันติดตามค่าใช้จ่ายนี้ จำเป็นต้องใช้ไลบรารี Tkinter, CSV และ Matplotlib
Tkinter ช่วยให้นักพัฒนาสามารถสร้างแอปพลิเคชันเดสก์ท็อปที่น่าดึงดูดใจได้ โดยจัดเตรียมส่วนประกอบกราฟิกที่หลากหลาย เช่น ปุ่ม ป้ายกำกับ และช่องป้อนข้อความ ส่วนต่อประสานที่ใช้งานง่ายทำให้กระบวนการสร้างแอปพลิเคชันเพื่อวัตถุประสงค์ต่างๆ ง่ายขึ้น
โมดูล CSV เป็นแพ็คเกจ Python โดยธรรมชาติที่นำเสนอฟังก์ชันที่เกี่ยวข้องกับการตีความและองค์ประกอบของไฟล์ Comma-Separated Value (CSV) ซึ่งใช้กันอย่างแพร่หลายในการแลกเปลี่ยนข้อมูลระหว่างแอปพลิเคชันและระบบที่หลากหลาย เนื่องจากความเรียบง่ายและความเข้ากันได้กับแพลตฟอร์มต่างๆ
Matplotlib เป็นเครื่องมืออันทรงพลังสำหรับการสร้างการแสดงภาพแบบไดนามิก รวมถึงกราฟ พล็อต และแผนภูมิ ซึ่งสามารถปรับปรุงเพิ่มเติมได้โดยการรวมเข้ากับ OpenCV เพื่อเพิ่มพูนความเชี่ยวชาญในเทคนิคการจัดการภาพขั้นสูง
หากต้องการติดตั้งโมดูลเหล่านี้ ให้รัน:
pip install tk matplotlib
กำหนดโครงสร้างของแอปติดตามค่าใช้จ่าย
ต้นกำเนิดของซอร์สโค้ดของโปรเจ็กต์นี้อยู่ภายในพื้นที่เก็บข้อมูล GitHub ที่กำหนด ซึ่งทำหน้าที่เป็นแหล่งเก็บข้อมูลดิจิทัลสำหรับไฟล์และเอกสารที่เกี่ยวข้องทั้งหมด
ในการเริ่มต้น เราจะนำเข้าโมดูลที่จำเป็น จากนั้นเราจะสร้างคลาสที่เรียกว่า ExpenseTrackerApp
ซึ่งกำหนดชื่อและขนาดของแอปพลิเคชัน ต่อไป เราจะกำหนดคู่ของรายการตามลำดับ รายการหนึ่งประกอบด้วยรายจ่ายที่บันทึกไว้ทั้งหมด ในขณะที่อีกรายการหนึ่งครอบคลุมประเภทการเงินต่างๆ ตัวแปรสตริงซึ่งมีชื่อเรียกว่า category\_var
ก็ได้ถูกสร้างขึ้นเช่นกัน โดยมีการตั้งค่าเริ่มต้นที่สอดคล้องกับหมวดหมู่หลักในรายการของเรา สุดท้ายนี้ เราเรียกกระบวนการ create\_widgets
ขึ้นมาเพื่อสร้างอินเทอร์เฟซผู้ใช้แบบกราฟิกขึ้นมา
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()
เมธอด create\_widgets
ทำหน้าที่เป็นองค์ประกอบสำคัญในการสร้างอินเทอร์เฟซผู้ใช้ภายในแอปพลิเคชัน เพื่อสร้างกรอบสำหรับการแสดงข้อมูลที่เกี่ยวข้องกับค่าใช้จ่าย เราต้องสร้างองค์ประกอบภาพซึ่งประกอบด้วยกรอบที่รองรับรายละเอียดเฉพาะที่เกี่ยวข้องกับบันทึกเหล่านี้ โดยเฉพาะ เราจะพัฒนาวิดเจ็ตป้ายกำกับแยกกันหกรายการ แต่ละรายการได้รับการออกแบบมาเพื่อนำเสนอข้อมูลที่เกี่ยวข้อง เช่น หัวข้อ มูลค่าทางการเงิน คำอธิบาย หมวดหมู่ วันที่ และผลรวมโดยรวม การกำหนดองค์ประกอบหลักให้กับป้ายกำกับแต่ละป้ายถือเป็นสิ่งสำคัญ ในขณะเดียวกันก็ระบุข้อความและลักษณะการพิมพ์ตามลำดับด้วย
ในการสร้างอินเทอร์เฟซที่มีการป้อนข้อความ 3 รายการและเมนูแบบเลื่อนลง ให้สร้างการเชื่อมต่อระหว่างรายการหลังกับตัวแปรชื่อ category\_var
เริ่มต้นด้วยการกำหนดเค้าโครงสำหรับแต่ละองค์ประกอบเหล่านี้ ระบุรูปแบบและขนาดแบบอักษรตามลำดับดังนี้:1. สร้างวิดเจ็ตรายการสามรายการ และกำหนดคอนเทนเนอร์พาเรนต์ ตัวเลือกการจัดรูปแบบ และข้อจำกัดด้านความกว้างให้กับแต่ละวิดเจ็ต สร้างวิดเจ็ต Combobox กำหนดคอนเทนเนอร์หลัก รายการตัวเลือกที่มีอยู่ รูปแบบแบบอักษร และข้อกำหนดด้านมิติ3. เชื่อมโยง Combobox กับตัวแปร category\_var
เพื่อให้แน่ใจว่าการเลือกภายในเมนูแบบเลื่อนลงจะอัปเดตแบบเรียลไทม์ตามการโต้ตอบของผู้ใช้
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)
สร้างอินเทอร์เฟซผู้ใช้ที่มีส่วนประกอบต่อไปนี้:ปุ่มที่มีป้ายกำกับ “เพิ่มค่าใช้จ่าย” ที่เพิ่มค่าใช้จ่ายลงในรายการ ปุ่มที่มีป้ายกำกับ “แก้ไขค่าใช้จ่าย” ที่แก้ไขค่าใช้จ่ายที่มีอยู่ในรายการ ปุ่มที่มีป้ายกำกับ “ลบค่าใช้จ่าย” ที่จะลบรายการ ค่าใช้จ่ายจากรายการ ปุ่มที่มีป้ายกำกับ “บันทึกค่าใช้จ่าย” ซึ่งจะบันทึกค่าใช้จ่ายทั้งหมดในรายการ ปุ่มที่มีป้ายกำกับ “แสดงแผนภูมิค่าใช้จ่าย” ที่แสดงแผนภูมิค่าใช้จ่ายในรายการ กรอบที่ล้อมรอบปุ่มเหล่านี้พร้อมชื่อ “ผู้จัดการค่าใช้จ่าย”".
รวมฟังก์ชันการทำงานของการสร้างแถบเลื่อนแนวตั้งซึ่งวางตำแหน่งทางด้านขวามือของพื้นที่เนื้อหาหลักของ GUI ช่วยให้สามารถนำทางเนื้อหาภายในกล่องรายการได้อย่างราบรื่น การใช้เทคนิคการเสริมที่เหมาะสม ช่วยให้มั่นใจในการนำเสนอด้วยภาพที่เหมาะสมที่สุด นอกจากนี้ เมื่ออัปเดตป้ายกำกับทั้งหมดด้วยข้อมูลใหม่ ให้ทำการปรับเปลี่ยนที่จำเป็นเพื่อรักษาความสอดคล้องกันทั่วทั้งอินเทอร์เฟซ
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()
กำหนดฟังก์ชันการทำงานของตัวติดตามค่าใช้จ่าย
รวมข้อมูลโค้ดที่กำหนดลงในอินเทอร์เฟซของแอปพลิเคชันที่มีอยู่เพื่อเป็นวิธีการบันทึกค่าใช้จ่ายตามหมวดหมู่และวันที่ที่ระบุ จากนั้นการตรวจสอบข้อมูลที่ป้อนจะถูกเพิ่มลงในรายการไดนามิกที่แสดงภายในอินเทอร์เฟซผู้ใช้แบบกราฟิก จากนั้นจะลบภาระผูกพันในการป้อนข้อมูลด้วยตนเองเพิ่มเติมออกจาก ผู้ใช้.
มิฉะนั้นจำเป็นต้องแสดงการแจ้งเตือนว่าค่า"ค่าใช้จ่าย"และ"วันที่"ไม่สามารถเว้นว่างได้ ต่อไปนี้ ควรดำเนินการเรียกใช้ฟังก์ชันเพื่อ 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()
ในการแก้ไขค่าใช้จ่ายที่มีอยู่ภายในฐานข้อมูลบันทึก เราสามารถใช้วิธีที่เรียกว่า"แก้ไข\_ค่าใช้จ่าย"วิธีนี้จะดึงข้อมูลดัชนีของเรกคอร์ดที่เลือกและรับค่าใช้จ่ายที่เกี่ยวข้อง จากนั้นจะแจ้งให้ผู้ใช้ป้อนค่าใหม่สำหรับค่าใช้จ่ายผ่านกล่องโต้ตอบ หากผู้ใช้ระบุค่าใช้จ่ายใหม่ วิธีการจะอัพเดตรายการค่าใช้จ่ายด้วยข้อมูลนี้ สุดท้าย วิธีการนี้เรียกใช้ฟังก์ชัน"refresh\_list"เช่นเดียวกับรูทีนย่อย"update\_total\_label"เพื่อให้แน่ใจว่าการเปลี่ยนแปลงทั้งหมดสะท้อนให้เห็นอย่างถูกต้องในแอปพลิเคชัน
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()
เพื่อใช้งานฟังก์ชันที่อธิบายไว้ในข้อมูลโค้ดที่กำหนด เราจะกำหนดวิธีการที่เรียกว่า delete\_expense
ซึ่งจะดึงดัชนีของบันทึกที่เลือกและรับค่าใช้จ่ายที่เกี่ยวข้อง จากนั้นเราจะส่งดัชนีนี้ไปยังฟังก์ชันเพื่อให้สามารถลบออกจากกล่องรายการได้ ต่อไปนี้ เราจะเรียกใช้ฟังก์ชัน update\_total\_label
เพื่อให้แน่ใจว่าป้ายกำกับทั้งหมดได้รับการอัปเดตตามนั้น
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()
แน่นอน! ต่อไปนี้คือตัวอย่างวิธีที่คุณสามารถนำไปใช้ใน Python โดยใช้ Flask และ SQLAlchemy:pythonfrom flask import gfrom sqlalchemy import create_engine, Column, Integer, String, ForeignKeyfrom sqlalchemy.orm import sessionmaker, allowancefrom 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=คอลัมน์(‘created_at’, DateTime, default=datetime.utcnow)updated_at=คอลัมน์ (‘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})"
)
เพื่อปรับแต่งข้อความที่ให้มา ฉันจำเป็นต้องมีบริบทเพิ่มเติมเกี่ยวกับสิ่งที่คุณต้องการให้ฉันทำกับข้อมูลโค้ดนี้ อย่างไรก็ตาม นี่คือความพยายามของฉันในการทำให้ข้อความที่ให้มาฟังดูซับซ้อนมากขึ้น:pythondef update_total_label(expenses):total=sum(expenses)return Totaldef save_expenses(filename=“expenses.csv”, allowances=None):if not allowances:expenses=[ ]# เปิดไฟล์ CSV ที่ระบุหรือสร้างขึ้นใหม่หากไม่มีอยู่ ลอง:ด้วย open(ชื่อไฟล์, “w”) เป็น f:writer=csv.writer(f)# เขียนส่วนหัว 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))
เพื่อให้เห็นภาพการกระจายรายจ่ายรายเดือนในหมวดหมู่ต่างๆ เราสามารถใช้วิธีที่เรียกว่า show\_expenses\_chart
ซึ่งใช้เป็นอินพุตในรายการ ค่าใช้จ่าย
ขั้นแรก เรามานิยามพจนานุกรมชื่อ category\_totals
กันก่อน ซึ่งจะทำหน้าที่เป็นตัวนับในการสะสมค่าใช้จ่ายรวมสำหรับการใช้จ่ายแต่ละประเภท เราจะวนซ้ำรายการในรายการ ค่าใช้จ่าย
โดยแปลงจำนวนค่าใช้จ่ายแต่ละรายการจากสตริงเป็นแบบทศนิยม สำหรับแต่ละหมวดหมู่ หากมีอยู่ในพจนานุกรม category\_totals
เราจะเพิ่มค่าคีย์ให้กับผลรวมที่มีอยู่ มิฉะนั้น เราจะสร้างคู่คีย์-ค่าใหม่ซึ่งแสดงถึงจำนวนค่าใช้จ่ายปัจจุบัน
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
หากต้องการสร้างการแสดงการกระจายค่าใช้จ่ายในชุดข้อมูลอย่างเป็นหมวดหมู่ เราสามารถใช้ฟังก์ชัน pie
ของ matplotlib ได้ ฟังก์ชันนี้ช่วยให้สามารถสร้างแผนภูมิวงกลมตามจำนวนค่าใช้จ่ายที่กำหนดและหมวดหมู่ที่เกี่ยวข้อง ด้วยการตั้งค่าพารามิเตอร์ต่างๆ เช่น 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 โดยสร้างอินสแตนซ์ จากนั้นเปิดใช้งานลูปเหตุการณ์ Tkinter ด้วยเมธอด mainloop() ซึ่งจะคอยตรวจสอบการโต้ตอบของผู้ใช้อย่างต่อเนื่องจนกระทั่งถึงเวลาที่อินเทอร์เฟซแบบกราฟิกปิด
if __name__ == "__main__":
app = ExpenseTrackerApp()
app.mainloop()
ทดสอบคุณสมบัติต่างๆ ของ Python Expense Tracker
เมื่อดำเนินการโปรแกรม จะมีการเปิดตัวอินเทอร์เฟซผู้ใช้แบบกราฟิก (GUI) ซึ่งมีฟิลด์อินพุตสำหรับบันทึกรายละเอียดที่เกี่ยวข้องกับค่าใช้จ่าย เช่น คำอธิบายรายการ หมวดหมู่ และวันที่ นอกเหนือจากกล่องข้อความสำหรับป้อนค่าตัวเลข โดยการพิมพ์ข้อมูลนี้และคลิกที่ปุ่ม"เพิ่มค่าใช้จ่าย"เราสามารถคาดหวังได้ว่ารายการใหม่จะถูกผนวกเข้ากับกล่องรายการ นอกจากนี้ โปรแกรมจะอัปเดตผลรวมของค่าใช้จ่ายที่บันทึกไว้ทั้งหมดอย่างต่อเนื่องเพื่อความสะดวกของคุณ
เมื่อเลือกรายการค่าใช้จ่ายที่ต้องการแล้ว โปรดคลิกที่ปุ่ม"แก้ไขค่าใช้จ่าย"เพื่อเริ่มกระบวนการแก้ไข ซึ่งจะพร้อมท์กล่องโต้ตอบที่ช่วยให้คุณสามารถแก้ไขรายละเอียดของรายการค่าใช้จ่ายแต่ละรายการที่เลือกภายในบริบทที่มีอยู่
การลบบันทึกค่าใช้จ่ายเฉพาะโดยคลิกที่ปุ่ม"ลบค่าใช้จ่าย"ซึ่งจะลบรายการที่เลือกออกจากรายการค่าใช้จ่าย
เมื่อคลิกที่ปุ่ม “แสดงแผนภูมิค่าใช้จ่าย” ซอฟต์แวร์จะสร้างการแสดงกราฟิกในรูปแบบของแผนภูมิวงกลมที่แสดงการกระจายรายจ่ายในหมวดหมู่ต่างๆ พร้อมด้วยชื่อและเปอร์เซ็นต์ตามลำดับ
การปรับปรุงตัวติดตามค่าใช้จ่าย
เพื่อปรับปรุงประสบการณ์ผู้ใช้ เป็นไปได้ที่จะรวมฟังก์ชันการค้นหาที่ช่วยให้บุคคลสามารถค้นหาค่าใช้จ่ายเฉพาะตามคำอธิบาย มูลค่า การจำแนกประเภท หรือวันที่ได้ นอกจากนี้ คุณอาจมีตัวเลือกสำหรับการเรียงลำดับและการกรองบันทึกข้อมูล การปรับแอปพลิเคชันให้รองรับภาษาและรูปแบบสกุลเงินต่างๆ จะเป็นประโยชน์
พิจารณารวมฟังก์ชันการแจ้งเตือนไว้ในแอปพลิเคชัน เพื่อให้ผู้ใช้สามารถกำหนดเกณฑ์ที่ทำให้เกิดการแจ้งเตือนเมื่อถูกละเมิด การแจ้งเตือนเหล่านี้สามารถใช้เป็นคำเตือนเกี่ยวกับการใช้จ่ายเกินและช่วยระบุค่าใช้จ่ายที่ผิดปกติ