账单管理系统

项目综述:

有个朋友委托我做一个基于python的账单管理系统,通过在控制台输入语句,实现账单的存储。

大致分为这样几个功能模块:

数据字典(data):

存储用户购买数据的字典。

validate_date 函数:

用于验证用户输入的日期格式是否正确。它使用 datetime.datetime.strptime 来尝试将输入日期解析为月份,如果日期格式无效则捕获 ValueError 异常并提示用户重新输入。
add_data 函数: 允许用户输入购买的类别、金额和日期,并将这些信息添加到数据字典中。在这之前,它会通过循环确保用户输入的日期是有效的。

delete_data 函数:

根据用户选择删除数据。如果选择 “A”,则清除所有数据;如果选择 “O”,则删除特定类别的最后一次输入。

generate_graph 函数:

根据用户选择生成柱状图。用户可以选择生成所有购买的柱状图(“A”)、特定类别的柱状图(“C”),或特定月份的柱状图(“M”)。

generate_report_csv 函数:

根据用户选择生成 CSV 报告。用户可以选择生成所有购买的报告(“A”)、特定类别的报告(“C”),或特定月份的报告(“M”)。生成的报告将保存到用户指定的文件中。

generate_report_sql 函数:

类似于生成 CSV 报告,但将数据导出到 SQLite 数据库中。

end_program 函数:

退出程序。

主程序循环:

提供一个简单的命令行交互界面,用户可以选择添加购买数据、删除数据、生成图表、生成报告、查看数据或退出程序。

下面是具体功能展示

账单输入及月份校验:

账单管理系统_第1张图片

删除账单
账单管理系统_第2张图片

全部账单可视化展示

账单管理系统_第3张图片

某一种类账单
账单管理系统_第4张图片

某一月份账单
账单管理系统_第5张图片

导出数据csv
账单管理系统_第6张图片

导出数据sql
账单管理系统_第7张图片

原代码

import matplotlib.pyplot as plt
import datetime
import pandas as pd
from sqlalchemy import create_engine

# 存储用户数据的字典
data = {}

def validate_date(input_date):
    try:
        # 尝试将输入日期解析为月份
        datetime.datetime.strptime(input_date, "%B")
        return True
    except ValueError:
        print("Invalid date format. Please use the format 'January', 'February', etc.")
        return False
def add_data():
    category = input("What category did you purchase? ")
    value = float(input("How much did you spend? (X.XX) "))

    # 循环直到用户输入有效日期
    while True:
        date = input("Date of Purchase (e.g. January): ")
        if validate_date(date):
            break

    if category not in data:
        data[category] = []
    data[category].append({"value": value, "date": date})


def delete_data(option):
    if option == "A":
        data.clear()
    elif option == "O":
        if data:
            category = input("Enter the category to delete the last entry: ")
            if category in data and data[category]:
                data[category].pop()
                print("Last entry for category {} deleted.".format(category))
            else:
                print("No entries to delete for category {}.".format(category))
        else:
            print("No data to delete.")
    else:
        print("Invalid option for deleting data")


def generate_graph(option):
    if option == "A":
        # 生成所有购买的柱状图
        categories = list(data.keys())
        values = [sum(entry['value'] for entry in data[category]) for category in categories]

        plt.bar(categories, values)
        plt.xlabel('Category')
        plt.ylabel('Total Spent')
        plt.title('All Purchases')
        plt.show()
    elif option == "C":
        category = input("Enter the category for the graph: ")
        if category in data:
            values = [sum(entry['value'] for entry in data[category])]
            plt.bar([category], values)
            plt.xlabel('Category')
            plt.ylabel('Total Spent')
            plt.title('Purchases in Category: {}'.format(category))
            plt.show()
        else:
            print("No data available for category {}".format(category))
    elif option == "M":
        month = input("Enter the month for the graph (e.g., January): ")
        total_spent = sum(sum(entry['value'] for entry in data[category]) for category in data if any(entry['date'].startswith(month) for entry in data[category]))
        plt.bar([month], [total_spent])
        plt.xlabel('Month')
        plt.ylabel('Total Spent')
        plt.title('Purchases in Month: {}'.format(month))
        plt.show()
    else:
        print("Invalid option for generating graph")


def generate_report_csv(option):
    filename = input("Enter the filename for the CSV report: ")

    if option == "A":
        # 输出所有购买到CSV文件
        all_entries = []
        for category, entries in data.items():
            for entry in entries:
                all_entries.append([category, entry['value'], entry['date']])

        df = pd.DataFrame(all_entries, columns=['Category', 'Value', 'Date'])
    elif option == "C":
        category = input("Enter the category for the report: ")
        if category in data:
            entries = [[category, entry['value'], entry['date']] for entry in data[category]]
            df = pd.DataFrame(entries, columns=['Category', 'Value', 'Date'])
        else:
            print("No data available for category {}".format(category))
            return
    elif option == "M":
        month = input("Enter the month for the report (e.g., January): ")
        entries = [[category, entry['value'], entry['date']] for category, entries in data.items() for entry in entries
                   if entry['date'].startswith(month)]
        df = pd.DataFrame(entries, columns=['Category', 'Value', 'Date'])
    else:
        print("Invalid option for generating report")
        return

    # 导出到 CSV 文件
    df.to_csv(filename, index=False)
    print(f"Report has been saved to {filename}")


def generate_report_sql(option):
    if option not in ["A", "C", "M"]:
        print("Invalid option for generating report")
        return

    # 获取用户输入的文件名和表名
    filename = input("Enter the filename for the SQL report (excluding extension): ")
    table_name = input("Enter the table name: ")

    # 准备数据
    if option == "A":
        all_entries = []
        for category, entries in data.items():
            for entry in entries:
                all_entries.append([category, entry['value'], entry['date']])
        columns = ['Category', 'Value', 'Date']
        # 创建数据框
        df = pd.DataFrame(all_entries, columns=columns)

    elif option == "C":
        category = input("Enter the category for the report: ")
        if category in data:
            entries = [[category, entry['value'], entry['date']] for entry in data[category]]
            columns = ['Category', 'Value', 'Date']
            # 创建数据框
            df = pd.DataFrame(entries, columns=columns)
        else:
            print("No data available for category {}".format(category))
            return

    elif option == "M":
        month = input("Enter the month for the report (e.g., January): ")
        entries = [[category, entry['value'], entry['date']] for category, entries in data.items() for entry in entries if entry['date'].startswith(month)]
        columns = ['Category', 'Value', 'Date']
        # 创建数据框
        df = pd.DataFrame(entries, columns=columns)

    # 导出到 SQL 数据库
    engine = create_engine('sqlite:///{}.db'.format(filename))
    df.to_sql(table_name, engine, index=False, if_exists='replace')

    print(f"Report has been saved to {filename}.db, table name: {table_name}")


def end_program():
    print("Exiting the program.")
    exit()


# 主程序循环
while True:
    print("Options: A, D, G, P, E")
    choice = input("Choose an option: ")

    if choice == "A":
        add_data()
    elif choice == "D":
        d_sub_menu_string = """
        A = All Data
        O = Only one previous data
        """
        delete_option = input(d_sub_menu_string + " Choose a deletion option (A, O): ")
        delete_data(delete_option)
    elif choice == "G":
        g_sub_menu_string = """
        A = All purchases
        C = Purchases in specific category
        M = Purchases in specific month
        """
        graph_option = input(g_sub_menu_string + "Choose a graph option (A, C, M): ")
        generate_graph(graph_option)
    elif choice == "P":
        p_sub_menu_string = """
        A = All purchases
        C = Purchases in specific category
        M = Purchases in specific month
        """
        report_option = input(p_sub_menu_string + "Choose a report option (A, C, M): ")
        choice =  input("Save csv or sql (C,S)")
        if choice=="C":
            generate_report_csv(report_option)
        else:
            generate_report_sql(report_option)
    elif choice == "E":
        end_program()
    # elif choice == "data":
    #     print(data)
    else:
        print("Invalid option. Please choose again.")

程序目前没有实现启动时加载数据库或者cvs中的订单记录的功能,感兴趣的小伙伴可以自己设计一下

你可能感兴趣的:(python,小程序,账单管理)