Introduction
This project aims to develop a Personal Finance Manager application that helps users efficiently track their income, expenses, and savings. The goal is to provide a tool that simplifies financial management, offers insights into spending patterns, and assists users in setting and achieving their financial goals.
本项目旨在开发一款个人财务管理应用软件,帮助用户有效跟踪其收入、支出和储蓄情况。目标是提供一个简化财务管理的工具,让用户深入了解支出模式,并协助用户设定和实现财务目标。
User Problem
Our target user for this application is a young people who may be a graduate or an early-career individual. This kind of user typically has a limited understanding of financial planning. They often face challenges in tracking their daily expenses, managing their income, and planning for savings.
本应用程序的目标用户是年轻人,他们可能是毕业生,也可能是初入职场者。这类用户通常对财务规划了解有限。他们往往在跟踪日常开支、管理收入和计划储蓄方面面临挑战。
Current Solution
The user's current method for managing finances involves a combination of paper records, mental notes, and spreadsheets.:
- Paper Records: Easily misplaced or lost.
- Mental Notes: Forget easily.
- Spreadsheets: While providing some structure, they require manual entry and are not user-friendly.
Consequently, users often lack a comprehensive view of their financial situation.
Data In and Data Out
Data In:
- Income
- Expenses
- Budget Information
- Savings Goals
Data Out:
- Financial Overview
- Expense Reports
- Budget Tracking
- Savings Progress
Criteria for Success
The success of the Personal Finance Manager application will be measured by its ability to meet the following criteria:
Expense Tracking:
The application must allow users to input and categorize expenses, specifying the amount and date.
Income Tracking:
Users should be able to record various income sources, detailing the amount, source, and date.
Budgeting and Alerts:
The software must allow users to set monthly budgets for different expense categories and provide notifications when they are close to or over these budgets.
Savings Goals:
The app should let users set savings goals and show their progress.
User-Friendly Interface:
The interface should be user-friendly and easy to navigate for all skill levels.
Code
import tkinter as tk
from tkinter import messagebox
from tkinter import ttk
class FinanceManager:
def __init__(self, root):
self.root = root
self.root.title("Personal Finance Manager")
self.root.geometry("600x400") # Set window size
self.expenses = []
self.income = []
self.budgets = {}
self.savings_goals = [] # Added savings goals list
self.style = ttk.Style()
self.style.configure('TButton', padding=6, relief='flat', background='#4CAF50', foreground='black') # Set text color to black
self.style.configure('TLabel', font=('Arial', 12))
self.style.configure('TEntry', padding=5)
self.create_ui()
def create_ui(self):
# Tabs
self.tabControl = ttk.Notebook(self.root)
self.tab_expenses = ttk.Frame(self.tabControl)
self.tab_income = ttk.Frame(self.tabControl)
self.tab_budget = ttk.Frame(self.tabControl)
self.tab_savings = ttk.Frame(self.tabControl) # Added savings goals tab
self.tab_summary = ttk.Frame(self.tabControl)
self.tabControl.add(self.tab_expenses, text='Expenses')
self.tabControl.add(self.tab_income, text='Income')
self.tabControl.add(self.tab_budget, text='Budget')
self.tabControl.add(self.tab_savings, text='Savings Goals') # Added savings goals tab
self.tabControl.add(self.tab_summary, text='Summary')
self.tabControl.pack(expand=1, fill="both")
# Expense Tab
self.create_expense_tab_ui()
# Income Tab
self.create_income_tab_ui()
# Budget Tab
self.create_budget_tab_ui()
# Savings Tab
self.create_savings_tab_ui() # Added savings goals tab UI
# Summary Tab
self.create_summary_tab_ui()
def create_expense_tab_ui(self):
ttk.Label(self.tab_expenses, text="Amount:").grid(row=0, column=0, padx=10, pady=5, sticky='w')
self.entry_expense_amount = ttk.Entry(self.tab_expenses)
self.entry_expense_amount.grid(row=0, column=1, padx=10, pady=5, sticky='ew')
ttk.Label(self.tab_expenses, text="Category:").grid(row=1, column=0, padx=10, pady=5, sticky='w')
self.entry_expense_category = ttk.Entry(self.tab_expenses)
self.entry_expense_category.grid(row=1, column=1, padx=10, pady=5, sticky='ew')
ttk.Label(self.tab_expenses, text="Date (YYYY-MM-DD):").grid(row=2, column=0, padx=10, pady=5, sticky='w')
self.entry_expense_date = ttk.Entry(self.tab_expenses)
self.entry_expense_date.grid(row=2, column=1, padx=10, pady=5, sticky='ew')
ttk.Button(self.tab_expenses, text="Add Expense", command=self.add_expense).grid(row=3, columnspan=2, pady=10)
def create_income_tab_ui(self):
ttk.Label(self.tab_income, text="Amount:").grid(row=0, column=0, padx=10, pady=5, sticky='w')
self.entry_income_amount = ttk.Entry(self.tab_income)
self.entry_income_amount.grid(row=0, column=1, padx=10, pady=5, sticky='ew')
ttk.Label(self.tab_income, text="Source:").grid(row=1, column=0, padx=10, pady=5, sticky='w')
self.entry_income_source = ttk.Entry(self.tab_income)
self.entry_income_source.grid(row=1, column=1, padx=10, pady=5, sticky='ew')
ttk.Label(self.tab_income, text="Date (YYYY-MM-DD):").grid(row=2, column=0, padx=10, pady=5, sticky='w')
self.entry_income_date = ttk.Entry(self.tab_income)
self.entry_income_date.grid(row=2, column=1, padx=10, pady=5, sticky='ew')
ttk.Button(self.tab_income, text="Add Income", command=self.add_income).grid(row=3, columnspan=2, pady=10)
def create_budget_tab_ui(self):
ttk.Label(self.tab_budget, text="Amount:").grid(row=0, column=0, padx=10, pady=5, sticky='w')
self.entry_budget_amount = ttk.Entry(self.tab_budget)
self.entry_budget_amount.grid(row=0, column=1, padx=10, pady=5, sticky='ew')
ttk.Button(self.tab_budget, text="Set Budget", command=self.set_budget).grid(row=1, columnspan=2, pady=10)
def create_savings_tab_ui(self):
ttk.Label(self.tab_savings, text="Goal Name:").grid(row=0, column=0, padx=10, pady=5, sticky='w')
self.entry_savings_goal_name = ttk.Entry(self.tab_savings)
self.entry_savings_goal_name.grid(row=0, column=1, padx=10, pady=5, sticky='ew')
ttk.Label(self.tab_savings, text="Target Amount:").grid(row=1, column=0, padx=10, pady=5, sticky='w')
self.entry_savings_goal_amount = ttk.Entry(self.tab_savings)
self.entry_savings_goal_amount.grid(row=1, column=1, padx=10, pady=5, sticky='ew')
ttk.Button(self.tab_savings, text="Add Savings Goal", command=self.add_savings_goal).grid(row=2, columnspan=2, pady=10)
def create_summary_tab_ui(self):
self.label_total_income = ttk.Label(self.tab_summary, text="Total Income: $0.00")
self.label_total_income.grid(row=0, column=0, padx=10, pady=5, sticky='w')
self.label_total_expense = ttk.Label(self.tab_summary, text="Total Expenses: $0.00")
self.label_total_expense.grid(row=1, column=0, padx=10, pady=5, sticky='w')
self.label_difference = ttk.Label(self.tab_summary, text="Surplus = Income - Expenses: $0.00")
self.label_difference.grid(row=2, column=0, padx=10, pady=5, sticky='w')
self.label_total_budget = ttk.Label(self.tab_summary, text="Total Budget: $0.00")
self.label_total_budget.grid(row=3, column=0, padx=10, pady=5, sticky='w')
self.label_savings_goals = ttk.Label(self.tab_summary, text="Savings Goals:")
self.label_savings_goals.grid(row=4, column=0, padx=10, pady=5, sticky='w')
self.alert_label = ttk.Label(self.tab_summary, text="", foreground='red') # Alert label
self.alert_label.grid(row=6, column=0, padx=10, pady=5, sticky='w')
ttk.Button(self.tab_summary, text="Update Summary", command=self.update_summary).grid(row=5, column=0, pady=10)
def add_expense(self):
amount = self.entry_expense_amount.get()
category = self.entry_expense_category.get()
date = self.entry_expense_date.get()
if not amount or not category or not date:
messagebox.showwarning("Input Error", "Please fill all the fields.")
return
try:
amount = float(amount)
except ValueError:
messagebox.showwarning("Input Error", "Invalid amount or date format.")
return
self.expenses.append({"amount": amount, "category": category, "date": date})
messagebox.showinfo("Expense Added", "Expense added successfully.")
self.clear_expense_fields()
def add_income(self):
amount = self.entry_income_amount.get()
source = self.entry_income_source.get()
date = self.entry_income_date.get()
if not amount or not source or not date:
messagebox.showwarning("Input Error", "Please fill all the fields.")
return
try:
amount = float(amount)
except ValueError:
messagebox.showwarning("Input Error", "Invalid amount or date format.")
return
self.income.append({"amount": amount, "source": source, "date": date})
messagebox.showinfo("Income Added", "Income added successfully.")
self.clear_income_fields()
def set_budget(self):
amount = self.entry_budget_amount.get()
if not amount:
messagebox.showwarning("Input Error", "Please fill in the budget amount.")
return
try:
amount = float(amount)
except ValueError:
messagebox.showwarning("Input Error", "Invalid amount format.")
return
# For simplicity, setting a single budget value (without category)
self.budgets["Total"] = amount
messagebox.showinfo("Budget Set", "Budget set successfully.")
self.clear_budget_fields()
def add_savings_goal(self):
goal_name = self.entry_savings_goal_name.get()
amount = self.entry_savings_goal_amount.get()
if not goal_name or not amount:
messagebox.showwarning("Input Error", "Please fill all the fields.")
return
try:
amount = float(amount)
except ValueError:
messagebox.showwarning("Input Error", "Invalid amount format.")
return
self.savings_goals.append({"goal_name": goal_name, "amount": amount})
messagebox.showinfo("Savings Goal Added", "Savings goal added successfully.")
self.clear_savings_fields()
def update_summary(self):
total_income = sum(item['amount'] for item in self.income)
total_expenses = sum(item['amount'] for item in self.expenses)
difference = total_income - total_expenses
total_budget = sum(self.budgets.values())
self.label_total_income.config(text=f"Total Income: ${total_income:.2f}")
self.label_total_expense.config(text=f"Total Expenses: ${total_expenses:.2f}")
self.label_difference.config(text=f"Surplus = Income - Expenses: ${difference:.2f}")
self.label_total_budget.config(text=f"Total Budget: ${total_budget:.2f}")
# Display savings goals progress
savings_goals_text = "\n".join([f"{goal['goal_name']}: ${goal['amount']:.2f}" for goal in self.savings_goals])
self.label_savings_goals.config(text=f"Savings Goals:\n{savings_goals_text}")
# Alert if Total Expenses is greater than Total Budget
if total_expenses > total_budget:
self.alert_label.config(text="Alert: Your current financial situation surpasses your set budget!")
else:
self.alert_label.config(text="")
def clear_expense_fields(self):
self.entry_expense_amount.delete(0, tk.END)
self.entry_expense_category.delete(0, tk.END)
self.entry_expense_date.delete(0, tk.END)
def clear_income_fields(self):
self.entry_income_amount.delete(0, tk.END)
self.entry_income_source.delete(0, tk.END)
self.entry_income_date.delete(0, tk.END)
def clear_budget_fields(self):
self.entry_budget_amount.delete(0, tk.END)
def clear_savings_fields(self):
self.entry_savings_goal_name.delete(0, tk.END)
self.entry_savings_goal_amount.delete(0, tk.END)
if __name__ == "__main__":
root = tk.Tk()
app = FinanceManager(root)
root.mainloop()