파이썬 기초 배우기: 간단한 가계부 및 비용 추적기를 코딩 해 보기
예산을 세워본 적이 있다면, 원하는 일을 하는 비용 추적기를 구하는 것이 얼마나 어려울 수 있는지 알고 계실 겁니다. 하지만 직접 만들어보는 건 어떨까요? 실제로 사용할 수 있는 간단한 비용 추적기를 만들어 Python 기본 사항을 배워보겠습니다.
비용 추적 앱의 요구 사항 정의
이 아이디어를 떠올렸을 때, 저는 단순한 다른 명령줄 터미널 앱 이상의 앱을 만들고 싶었습니다. 우리는 파이썬을 사용한 간단한 할 일 목록과 같은 몇 가지를 만들었습니다. 이번에는 GUI를 사용하고 싶어서 사용 가능한 UI 요소를 얻기 위해 Tkinter 라이브러리를 가져오기로 결정했습니다.
라이브러리를 통해 코드를 재사용할 수 있습니다. 보통 파이썬으로 대부분의 작업을 수행할 수 있는 라이브러리가 있습니다. 가져오기를 하면 포함된 모든 코드를 처음부터 다시 쓰는 것을 피할 수 있습니다.
이 앱에서는 다음을 구현할 것입니다:
- 비용 항목
- 예산 정의
- 예산 대비 지출 비교하기
- 지출 내역 보기
이 작업이 끝나면 파이썬이 어떻게 작동하는지에 대한 적절한 아이디어를 얻을 수 있을 것이며, 첫 번째 GUI 기반 파이썬 앱을 완성할 수 있을 것입니다.
프로젝트 설정
Python 버전을 확인하여 기기에 Python이 설치되어 있는지 확인해야 합니다. 이미 제가 좋아하는 IDE(Visual Studio)를 파이썬에 연결하는 방법을 다루었습니다. 기기에 Python을 설치하고 최신 버전으로 업데이트하는 오버헤드를 해결한 후, 새 프로젝트를 만드는 것부터 시작할 수 있습니다.
이 프로젝트를 위해 파이썬을 선택한 이유는 초보자들에게 가장 쉬운 언어 중 하나이기 때문입니다. 비용 추적기 구축에 대해 알아봅시다!
메인 애플리케이션 창 구축
이 애플리케이션의 터미널에서 멀어질 예정이므로 대신 애플리케이션의 그래픽 사용자 인터페이스(GUI)를 구축하기 위해 Tkinter를 설정해야 합니다. 파이썬의 UI 디자인은 복잡할 수 있으므로 단순하게 유지하고 제가 제공하는 코드가 무엇을 하는지 알려드리겠습니다. 제 UI 창은 이렇게 정의될 것입니다. 먼저 Tkinter를 가져오는 것부터 시작하겠습니다:
import tkinter as tk
from tkinter import ttk, messagebox, simpledialog
Tkinter에는 기본 UI를 만드는 데 필요한 모든 기능이 포함되어 있습니다. Tkinter 내부의 테마 엔진인 Ttk도 수입하고 있다는 것을 알게 될 것입니다. 이를 통해 원하는 경우 UI의 모양을 제어할 수 있습니다. 또한 사용자에게 초기 예산 설정을 요청하기 위해 메시지 상자와 간단한 대화 상자를 사용할 예정입니다. 또한 향후 액세스를 원할 경우를 대비하여 월별 데이터를 저장할 수 있기를 원하므로 파일 상단에 추가할 예정입니다:
import json
from datetime import datetime
제 이름과 매우 가까운 것 외에도 JSON은 사실 직렬화 시스템으로서 꽤 멋진 편입니다. 다행히도 Python에는 기본으로 제공되므로 직접 가져올 수 있습니다. datetime 가져오기는 애플리케이션 전체에서 날짜를 올바르게 형식화하는 데 도움이 됩니다.
이제 수입품을 파악했으니 실제로 창을 만들어 보겠습니다:
def create_widgets(self):
# Main Frame
main_frame = ttk.Frame(self.root, padding="10")
main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
# Expense Input Frame
input_frame = ttk.LabelFrame(main_frame, text="Add Expense", padding="10")
input_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=5, pady=5)
ttk.Label(input_frame, text="Date (YYYY-MM-DD):").grid(row=0, column=0, sticky=tk.W)
self.date_entry = ttk.Entry(input_frame)
self.date_entry.grid(row=0, column=1, padx=5, pady=2)
ttk.Label(input_frame, text="Category:").grid(row=1, column=0, sticky=tk.W)
self.category_combobox = ttk.Combobox(input_frame, values=self.categories)
self.category_combobox.grid(row=1, column=1, padx=5, pady=2)
ttk.Label(input_frame, text="Amount:").grid(row=2, column=0, sticky=tk.W)
self.amount_entry = ttk.Entry(input_frame)
self.amount_entry.grid(row=2, column=1, padx=5, pady=2)
ttk.Button(input_frame, text="Add Expense", command=self.add_expense).grid(row=3, column=0, columnspan=2, pady=5)
# Category Management Frame
category_frame = ttk.LabelFrame(main_frame, text="Manage Categories", padding="10")
category_frame.grid(row=1, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=5, pady=5)
self.new_category_entry = ttk.Entry(category_frame)
self.new_category_entry.grid(row=0, column=0, padx=5, pady=2)
ttk.Button(category_frame, text="Add Category", command=self.add_category).grid(row=0, column=1, padx=5, pady=2)
이 항목들은 단지 우리의 창을 스타일링하고 있을 뿐입니다. 원한다면 숫자를 가지고 놀면서 숫자를 만지작거리는 것은 무해하기 때문에 (마지막 창이 끔찍해 보이는 것 외에는) 어떤 결과가 나오는지 확인할 수 있습니다. 프레임과 저장 버튼을 표시하고 그리드가 멋지게 보이도록 구성해야 합니다:
# Display Frame
display_frame = ttk.LabelFrame(main_frame, text="Expenses and Budget", padding="10")
display_frame.grid(row=0, column=1, rowspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), padx=5, pady=5)
self.expense_tree = ttk.Treeview(display_frame, columns=('Date', 'Category', 'Amount'), show='headings')
self.expense_tree.heading('Date', text='Date')
self.expense_tree.heading('Category', text='Category')
self.expense_tree.heading('Amount', text='Amount')
self.expense_tree.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
scrollbar = ttk.Scrollbar(display_frame, orient=tk.VERTICAL, command=self.expense_tree.yview)
scrollbar.grid(row=0, column=1, sticky=(tk.N, tk.S))
self.expense_tree.configure(yscrollcommand=scrollbar.set)
self.budget_label = ttk.Label(display_frame, text=f"Monthly Budget: ${self.monthly_budget:.2f}")
self.budget_label.grid(row=1, column=0, sticky=tk.W, pady=2)
self.total_expenses_label = ttk.Label(display_frame, text="Total Expenses: $0.00")
self.total_expenses_label.grid(row=2, column=0, sticky=tk.W, pady=2)
self.remaining_budget_label = ttk.Label(display_frame, text=f"Remaining Budget: ${self.monthly_budget:.2f}")
self.remaining_budget_label.grid(row=3, column=0, sticky=tk.W, pady=2)
# Save Button
ttk.Button(display_frame, text="Save Data", command=self.save_data).grid(row=4, column=0, pady=10)
# Configure grid
self.root.columnconfigure(0, weight=1)
self.root.rowconfigure(0, weight=1)
main_frame.columnconfigure(1, weight=1)
main_frame.rowconfigure(0, weight=1)
display_frame.columnconfigure(0, weight=1)
display_frame.rowconfigure(0, weight=1)
보시다시피, UI는 제대로 작동하기 위해 많은 코딩이 필요합니다. 하지만 파이썬 기초를 배울 계획이므로 UI 디자인을 이해하는 것도 중요합니다. 이제 UI를 실행했으니 기능에 대해 작업해 보겠습니다.
카테고리 정의 및 비용 추가
앱에 약간의 '바디'를 부여하기 위해 몇 가지 비용 카테고리를 미리 정의했습니다. 나머지 정의와 함께 헤더로 포함시켰습니다:
class ExpenseTrackerApp:
def __init__(self, root):
self.root = root
self.root.title("Expense Tracker & Budget Planner")
self.root.geometry("1100x500")
self.expenses = []
self.categories = ["Rent", "Food", "Entertainment", "Car", "Credit Cards"]
self.monthly_budget = self.get_initial_budget()
self.create_widgets()
def get_initial_budget(self):
while True:
budget = simpledialog.askfloat("Monthly Budget", "Enter your monthly budget:", minvalue=0.01)
if budget is not None:
return budget
else:
if messagebox.askyesno("No Budget", "You haven't entered a budget. Do you want to exit?"):
self.root.quit()
return 0
이와 같은 정의는 우리 프로그램의 최상위에 있어야 합니다. 이를 위해 이 스니펫은 이미 개발한 위젯 생성 코드보다 먼저 제공되어야 합니다.
get_initial_budget(자체) 기능은 앱 실행 시작 시 팝업을 생성하여 사용 가능한 금액을 결정하는 데이터를 수집합니다. 값을 입력하지 않으면 앱이 즉시 종료됩니다.
우리는 또한 새로운 맞춤형 항목으로 비용을 추가하고 카테고리를 업데이트할 수 있는 기능이 필요합니다. 다행히도 이것은 구현하기도 간단합니다:
def add_expense(self):
try:
date = self.date_entry.get()
category = self.category_combobox.get()
amount = float(self.amount_entry.get())
self.expenses.append({
'date': date,
'category': category,
'amount': amount
})
self.update_expense_list()
self.update_budget_info()
self.clear_input_fields()
except ValueError:
messagebox.showerror("Error", "Invalid input. Please check your entries.")
def add_category(self):
new_category = self.new_category_entry.get().strip()
if new_category and new_category not in self.categories:
self.categories.append(new_category)
self.category_combobox['values'] = self.categories
self.new_category_entry.delete(0, tk.END)
messagebox.showinfo("Category Added", f"'{new_category}' has been added to the categories.")
else:
messagebox.showerror("Error", "Invalid category name or category already exists.")
기본 기능을 정리하려면 새로운 비용을 입력할 때 비용 목록을 업데이트하는 기능이 필요합니다. 데이터를 입력한 후 콤보 상자를 지우려면 도우미 기능이 필요합니다. 마지막으로, 우리는 아직 사용 가능한 예산의 양을 계산해야 할 것입니다. 이 간단한 코드 조각은 우리가 그것을 할 수 있게 해줄 것입니다:
def update_expense_list(self):
for item in self.expense_tree.get_children():
self.expense_tree.delete(item)
for expense in self.expenses:
self.expense_tree.insert('', 'end', values=(
expense['date'],
expense['category'],
f"${expense['amount']:.2f}"
))
def update_budget_info(self):
total_expenses = sum(expense['amount'] for expense in self.expenses)
remaining_budget = self.monthly_budget - total_expenses
self.total_expenses_label.config(text=f"Total Expenses: ${total_expenses:.2f}")
self.remaining_budget_label.config(text=f"Remaining Budget: ${remaining_budget:.2f}")
def clear_input_fields(self):
self.date_entry.delete(0, tk.END)
self.category_combobox.set('')
self.amount_entry.delete(0, tk.END)
그렇다면 이 모든 데이터를 입력한 후, 어떻게 하면 손실되지 않도록 보장할 수 있을까요? 이전에 가져온 JSON 형식을 사용하여 간단한 저장 기능을 구현했습니다:
def save_data(self):
data = {
'budget': self.monthly_budget,
'categories': self.categories,
'expenses': self.expenses
}
# Get the current date to use in the filename
current_date = datetime.now().strftime("%Y-%m")
default_filename = f"expense_data_{current_date}.json"
file_path = filedialog.asksaveasfilename(
defaultextension=".json",
filetypes=[("JSON files", "*.json")],
initialfile=default_filename
)
if file_path:
with open(file_path, 'w') as f:
json.dump(data, f, indent=2)
messagebox.showinfo("Save Successful", f"Data saved to {file_path}")
이 함수는 데이터를 직렬화하여 파일 이름에 현재 날짜가 추가된 특정 파일 위치에 저장합니다. 마지막으로 해야 할 일은 메인() 함수 루프를 구성하는 것입니다:
if __name__ == "__main__":
root = tk.Tk()
app = ExpenseTrackerApp(root)
root.mainloop()
그렇게 하면 우리의 비용 추적기가 문제 없이 작동할 수 있을 것입니다. 파이썬에서 첫 번째 GUI 기반 애플리케이션을 완료하신 것을 축하드립니다!
추가, 단점 및 맞춤 설정
이 작업을 완료한 후, Tkinter가 어떻게 작동하는지와 GUI 생성에 어떻게 사용할 수 있는지에 대해 조금 이해하게 됩니다. CSS나 그래픽 디자인에 대해 조금 알고 있다면, Tkinter를 빠르게 사용하는 방법을 알아낼 수 있을 것입니다. 몇 가지 도전 과제가 필요하다면 다음에 시도해 볼 수 있습니다:
- 앱에 새로운 테마를 만들거나 사용하세요.
- "로드" 기능과 버튼을 생성합니다. 더 많은 탐험 공간을 제공하기 위해 로드 함수를 제외했습니다.
- 그래픽 기반 예산 내역을 파이 차트로 분석하는 방법을 살펴보세요.
최종 애플리케이션은 현재 다음과 같은 모습이어야 합니다:
여기서 어디로 가야 할까요?
이 개발 튜토리얼은 Tkinter에 대한 광범위한 개요만 제공했지만, 더 많은 GUI 기반 앱을 만들 계획이라면 Tkinter가 무엇을 할 수 있는지 더 잘 이해해야 합니다. RealPython은 Tkinter 또는 기타 사용 가능한 GUI 프레임워크나 툴킷을 사용하는 방법에 대한 아이디어를 제공할 수 있습니다. 파이썬은 기본적으로 이해하기 쉽지만, 파이썬의 기초를 배우면서 탐구할 수 있는 것이 너무 많습니다. 당신이 창조할 수 있는 것을 제한하는 유일한 것은 상상력입니다.
-
'IT 이것저것 > 파이썬python' 카테고리의 다른 글
초보자를 위한 파이썬 프로그래밍: 간단한 퀴즈 앱을 만들자 (0) | 2025.02.03 |
---|---|
파이썬을 사용한 초보 코딩: 주사위 굴리기 시뮬레이터 개발 (0) | 2025.02.02 |
파이썬을 계산기로 사용해야 하는 이유(및 시작하는 방법) (1) | 2025.02.01 |
파이썬으로, 네이버 자동로그인 하는 프로그램 짜기 (0) | 2019.08.28 |
파이썬python 본격적으로 학생 성적 관리 프로그램을 만들어 보자! (1) | 2017.06.19 |
댓글