python项目开发——个人开支管理系统

项目名称:个人开支管理系统

  • 项目简介

开发一个简单的个人开支管理系统,帮助用户记录和管理日常开支。该系统应具备记录开支、查看开支、计算总支出和删除记录等基本功能。

  • 项目需求
1. 用户界面
  1. 提供简易的命令行界面供用户操作。
  2. 用户可以选择不同的操作:记录开支、查看开支、计算总支出、删除记录和退出程序。
2. 功能模块
    a.记录开支

     - 用户输入开支金额、类别(如食品、交通、娱乐等)和日期。

     - 将记录保存到一个数据结构中(如列表)。

    b.查看开支

     - 显示所有已记录的开支。

     - 每条记录包括金额、类别和日期。

    c.计算总支出

     - 计算并显示用户的总支出金额。

    d.删除记录

     - 用户可以按日期或类别删除特定的开支记录。

    e.退出程序

     - 用户选择退出程序后,系统保存所有开支记录到一个文件中,以便下次启动时读取。

3. 数据存储

   使用文本文件保存和读取开支记录,确保数据在程序关闭后不丢失。

  • 项目步骤
1. 初始化项目

   - 创建一个新的Python项目文件。

   - 创建必要的函数和数据结构(如列表、字典等)。

2. 实现功能模块

   - 编写记录开支的函数,提示用户输入必要信息,并保存到数据结构中。

   - 编写查看开支的函数,遍历数据结构并打印所有记录。

   - 编写计算总支出的函数,遍历数据结构并累计总金额。

   - 编写删除记录的函数,根据用户输入的条件(日期或类别)删除相应记录。

   - 编写文件读写函数,在程序启动时读取文件并加载记录,在程序退出时保存记录到文件。

3. 用户交互界面

   - 使用循环结构创建用户交互界面,根据用户选择调用相应的功能模块。

   - 提供明确的提示信息和错误处理机制,确保用户输入的有效性。

4. 测试和调试

   - 对每个功能模块进行单独测试,确保其正确性。

   - 测试整个系统的工作流程,检查各功能模块之间的交互是否正常。

   - 处理可能出现的异常情况,如文件读写错误、用户输入错误等。

  • 项目扩展

完成基本功能后,可以考虑添加以下扩展功能,完成者将获得更高评分。

- 按月份或类别生成开支报告。

- 支持多用户的开支管理。

- 图形用户界面(GUI)实现,使用如Tkinter等库。

实验器材、设备和平台

  1. 计算机
  2. 操作系统:Windows、macOS或Linux
  3. 编程语言:Python 3.x
  4. 开发环境:任意Python集成开发环境(IDE),例如PyCharm、VSCode,或文本编辑器如Sublime Text
  5. 必要的Python库:标准库Tkinter、json、os

接下来,将代码划分成各个模块,解释说明其功能与实现。

部分 1: 导入库,初始化全局变量

import json
import os
from datetime import datetime
import tkinter as tk
from tkinter import messagebox, simpledialog

data_file = "expenses.json"
users = {}
current_user = None
  • import json 和 import os:用于数据的持久化和文件操作。
  • from datetime import datetime:日期处理。
  • import tkinter as tk 和 from tkinter import messagebox, simpledialog:用于创建图形用户界面。
  • data_file:指定存储数据的文件名。
  • users:存储所有用户及其开支记录的字典。
  • current_user:当前登录的用户。

部分 2: 数据加载和保存

# 从json文件加载用户数据
def load_data():
    global users
    if os.path.exists(data_file):
        with open(data_file, 'r') as file:
            users = json.load(file)

# 将用户数据保存到json文件中
def save_data():
    with open(data_file, 'w') as file:
        json.dump(users, file)
  • load_data函数:从JSON文件加载用户数据。
  • save_data函数:将用户数据保存到JSON文件。

部分 3: 用户登录

# 用户登录。如若没有则创建用户
def login():
    global current_user
    username = simpledialog.askstring("登录", "请输入用户名:")
    if username:
        if username not in users:
            users[username] = []
        current_user = username
        main_menu()
  • login函数:提示用户输入用户名。如果用户名不存在,则创建新的用户记录。调用 main_menu() 函数显示主菜单。

部分 4: 记录开支

# 将用户输入的信息记录到当前用户的开支列表中,如若日期的格式错误,将记录失败
def record_expense():
    money = simpledialog.askfloat("记录开支", "花了多少?:")
    if money is None:
        return
    kinds = simpledialog.askstring("记录开支", "干什么了?(食品?交通?娱乐?):")
    if kinds is None:
        return
    date_str = simpledialog.askstring("记录开支", "啥时候花的?(例:2024-05-26):")
    try:
        if date_str is None:
            return
        date = datetime.strptime(date_str, "%Y-%m-%d")
        expense = {
            "money": money,
            "kinds": kinds,
            "date": date_str
        }
        users[current_user].append(expense)
        messagebox.showinfo("提示", "记录已保存!")
    except Exception as V:
        messagebox.showerror("错误", "日期输错了!记录失败!!!")
  • record_expense函数:提示用户输入开支信息,并将其记录到当前用户的开支列表中。使用try-except块捕获日期格式错误。

部分 5: 查看开支

# 用户开支的查看
def cat_expenses():
    expenses_str = "\n".join(
        [f"金额: {expense['money']}, 类别: {expense['kinds']}, 日期: {expense['date']}" for expense in users[current_user]]
    )
    if expenses_str:
        messagebox.showinfo("查看开支", expenses_str)
    else:
        messagebox.showinfo("查看开支", "当前无开支记录")
  • cat_expenses函数:显示当前用户的所有开支记录,通过消息框 (messagebox.showinfo) 显示结果。

部分 6: 计算总支出

# 用户总开支的查看
def total_expense():
    total = sum(expense['money'] for expense in users[current_user])
    messagebox.showinfo("总支出", f"总支出金额: {total}")
  • total_expense函数:计算并输出当前用户的总支出金额,通过消息框 (messagebox.showinfo) 显示结果。

部分 7: 删除记录

# 按照用户指定的条件(日期或类别)删除相应的记录。
def delete_expense():
    option = simpledialog.askstring("删除开支", "想怎样删除?(1: 按日期, 2: 按类别):")
    if option == '1':
        date_str = simpledialog.askstring("删除开支", "删除哪天?(例:2024-05-26):")
        if date_str:
            users[current_user] = [expense for expense in users[current_user] if expense['date'] != date_str]
            messagebox.showinfo("提示", "记录删除成功!")
    elif option == '2':
        category = simpledialog.askstring("删除开支", "删除哪一类:")
        if category:
            users[current_user] = [expense for expense in users[current_user] if expense['category'] != category]
            messagebox.showinfo("提示", "删除成功!")
    else:
        messagebox.showerror("错误", "无效删除方式!!!")
  • delete_expense函数:按照用户指定的条件(日期或类别)删除相应的开支记录。使用消息框显示操作结果。

部分 8: 生成报告

'''
根据用户选择,按月份或类别生成并显示开支报告。
按月份统计:截取日期字符串的前7位(如"2024-05")。
按类别统计:根据类别分类汇总支出。
'''
def generate_report():
    option = simpledialog.askstring("生成报告", "选择生成报告的方式(1: 按月份, 2: 按类别):")
    report = {}
    if option == '1':
        for expense in users[current_user]:
            month = expense['date'][:7]
            if month not in report:
                report[month] = 0
            report[month] += expense['money']
    elif option == '2':
        for expense in users[current_user]:
            kinds = expense['kinds']
            if kinds not in report:
                report[kinds] = 0
            report[kinds] += expense['money']

    report_str = "\n".join([f"{key}: {report[key]}" for key in report])
    messagebox.showinfo("报告", report_str)
  • generate_report函数:根据用户选择,按月份或类别生成并显示开支报告。通过消息框 (messagebox.showinfo) 显示结果。
  • 按月份统计:截取日期字符串的前7位(如"2024-05")。
  • 按类别统计:根据类别分类汇总支出。

部分 9: 主菜单

'''程序的入口,负责加载数据,用户登录,显示操作菜单以及根据用户选择调用相应功能模块。
while循环用来提供持续的用户交互,直到用户选择退出。'''

def main_menu():
    # root.withdraw()  # 隐藏登录窗口
    menu = tk.Tk()
    menu.title("个人开支管理系统")

    tk.Label(menu, text=f"当前用户: {current_user}", font=("Arial", 30)).pack(pady=30)
    tk.Button(menu, text="记录开支", command=record_expense, width=30).pack(pady=30)
    tk.Button(menu, text="查看开支", command=cat_expenses, width=30).pack(pady=30)
    tk.Button(menu, text="计算总支出", command=total_expense, width=30).pack(pady=30)
    tk.Button(menu, text="删除记录", command=delete_expense, width=30).pack(pady=30)
    tk.Button(menu, text="生成报告", command=generate_report, width=30).pack(pady=30)
    tk.Button(menu, text="退出并保存", command=lambda: [save_data(), menu.destroy(), root.deiconify()], width=30).pack(pady=30)

    menu.mainloop()
  • main_menu函数:程序的入口,负责加载数据,用户登录,显示操作菜单以及根据用户选择调用相应功能模块。使用 tk.Tk 创建主菜单窗口,包含多个按钮,每个按钮绑定一个功能函数。

部分 10: 主窗口和登录界面

# 主窗口和登录界面及函数的调用
root = tk.Tk()
root.title("个人开支管理系统")
tk.Button(root, text="登录", command=login, width=50).pack(pady=50)
root.mainloop()
  • 在程序启动时显示登录窗口 (root),用户登录后进入主菜单 (main_menu)。
  • tk.Button 创建一个登录按钮,点击后调用 login 函数。通过 root.mainloop() 运行Tkinter事件循环,保持界面响应。

项目完整代码如下:

# 部分库的导入以及全局变量的初始化
import json
import os
from datetime import datetime
import tkinter as tk
from tkinter import messagebox, simpledialog

data_file = "expenses.json"
users = {}
current_user = None


# 从json文件加载用户数据
def load_data():
    global users
    if os.path.exists(data_file):
        with open(data_file, 'r') as file:
            users = json.load(file)


# 将用户数据保存到json文件中
def save_data():
    with open(data_file, 'w') as file:
        json.dump(users, file)


# 用户登录。如若没有则创建用户
def login():
    global current_user
    username = simpledialog.askstring("登录", "请输入用户名:")
    if username:
        if username not in users:
            users[username] = []
        current_user = username
        main_menu()


# 将用户输入的信息记录到当前用户的开支列表中,如若日期的格式错误,将记录失败
def record_expense():
    money = simpledialog.askfloat("记录开支", "花了多少?:")
    if money is None:
        return
    kinds = simpledialog.askstring("记录开支", "干什么了?(食品?交通?娱乐?):")
    if kinds is None:
        return
    date_str = simpledialog.askstring("记录开支", "啥时候花的?(例:2024-05-26):")
    try:
        if date_str is None:
            return
        date = datetime.strptime(date_str, "%Y-%m-%d")
        expense = {
            "money": money,
            "kinds": kinds,
            "date": date_str
        }
        users[current_user].append(expense)
        messagebox.showinfo("提示", "记录已保存!")
    except Exception as V:
        messagebox.showerror("错误", "日期输错了!记录失败!!!")


# 用户开支的查看
def cat_expenses():
    expenses_str = "\n".join(
        [f"金额: {expense['money']}, 类别: {expense['kinds']}, 日期: {expense['date']}" for expense in
         users[current_user]]
    )
    if expenses_str:
        messagebox.showinfo("查看开支", expenses_str)
    else:
        messagebox.showinfo("查看开支", "当前无开支记录")


# 用户总开支的查看
def total_expense():
    total = sum(expense['money'] for expense in users[current_user])
    messagebox.showinfo("总支出", f"总支出金额: {total}")


# 按照用户指定的条件(日期或类别)删除相应的记录。
def delete_expense():
    option = simpledialog.askstring("删除开支", "想怎样删除?(1: 按日期, 2: 按类别):")
    if option == '1':
        date_str = simpledialog.askstring("删除开支", "删除哪天?(例:2024-05-26):")
        if date_str:
            users[current_user] = [expense for expense in users[current_user] if expense['date'] != date_str]
            messagebox.showinfo("提示", "记录删除成功!")
    elif option == '2':
        category = simpledialog.askstring("删除开支", "删除哪一类:")
        if category:
            users[current_user] = [expense for expense in users[current_user] if expense['category'] != category]
            messagebox.showinfo("提示", "删除成功!")
    else:
        messagebox.showerror("错误", "无效删除方式!!!")


'''
根据用户选择,按月份或类别生成并显示开支报告。
按月份统计:截取日期字符串的前7位(如"2024-05")。
按类别统计:根据类别分类汇总支出。
'''


def generate_report():
    option = simpledialog.askstring("生成报告", "选择生成报告的方式(1: 按月份, 2: 按类别):")
    report = {}
    if option == '1':
        for expense in users[current_user]:
            month = expense['date'][:7]
            if month not in report:
                report[month] = 0
            report[month] += expense['money']
    elif option == '2':
        for expense in users[current_user]:
            kinds = expense['kinds']
            if kinds not in report:
                report[kinds] = 0
            report[kinds] += expense['money']

    report_str = "\n".join([f"{key}: {report[key]}" for key in report])
    messagebox.showinfo("报告", report_str)


'''程序的入口,负责加载数据,用户登录,显示操作菜单以及根据用户选择调用相应功能模块。
while循环用来提供持续的用户交互,直到用户选择退出。'''


def main_menu():
    # root.withdraw()  # 隐藏登录窗口
    menu = tk.Tk()
    menu.title("个人开支管理系统")

    tk.Label(menu, text=f"当前用户: {current_user}", font=("Arial", 30)).pack(pady=30)
    tk.Button(menu, text="记录开支", command=record_expense, width=30).pack(pady=30)
    tk.Button(menu, text="查看开支", command=cat_expenses, width=30).pack(pady=30)
    tk.Button(menu, text="计算总支出", command=total_expense, width=30).pack(pady=30)
    tk.Button(menu, text="删除记录", command=delete_expense, width=30).pack(pady=30)
    tk.Button(menu, text="生成报告", command=generate_report, width=30).pack(pady=30)
    tk.Button(menu, text="退出并保存", command=lambda: [save_data(), menu.destroy(), root.deiconify()], width=30).pack(
        pady=30)

    menu.mainloop()


# 主窗口和登录界面及函数的调用
root = tk.Tk()
root.title("个人开支管理系统")
tk.Button(root, text="登录", command=login, width=50).pack(pady=50)
root.mainloop()

项目特色

  1. 用户友好的界面:通过Tkinter提供简洁明了的图形用户界面,用户可以方便地进行开支记录和管理。
  2. 数据持久性:使用JSON文件保存用户数据,即使程序关闭,也能保留用户的开支记录。
  3. 详细的统计功能:提供按月份和类别的开支报告,使用户可以清晰了解自己的消费情况。
  4. 灵活的删除功能:用户可以根据日期或类别删除开支记录,确保数据管理的灵活性。

使用总结

该项目以实际需求出发,实现了个人开支管理的基本功能,并通过Python的Tkinter库提供了良好的用户交互体验。
在开发过程中,涵盖了数据处理、文件操作、异常处理等多种技术,具有一定的实用价值和学习意义。
未来我们可以在此基础上增加更多功能,如图表分析、预算管理、多用户支持等,以进一步提升系统的实用性。

  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值