有个朋友委托我做一个基于python的账单管理系统,通过在控制台输入语句,实现账单的存储。
大致分为这样几个功能模块:
存储用户购买数据的字典。
用于验证用户输入的日期格式是否正确。它使用 datetime.datetime.strptime 来尝试将输入日期解析为月份,如果日期格式无效则捕获 ValueError 异常并提示用户重新输入。
add_data 函数: 允许用户输入购买的类别、金额和日期,并将这些信息添加到数据字典中。在这之前,它会通过循环确保用户输入的日期是有效的。
根据用户选择删除数据。如果选择 “A”,则清除所有数据;如果选择 “O”,则删除特定类别的最后一次输入。
根据用户选择生成柱状图。用户可以选择生成所有购买的柱状图(“A”)、特定类别的柱状图(“C”),或特定月份的柱状图(“M”)。
根据用户选择生成 CSV 报告。用户可以选择生成所有购买的报告(“A”)、特定类别的报告(“C”),或特定月份的报告(“M”)。生成的报告将保存到用户指定的文件中。
类似于生成 CSV 报告,但将数据导出到 SQLite 数据库中。
退出程序。
提供一个简单的命令行交互界面,用户可以选择添加购买数据、删除数据、生成图表、生成报告、查看数据或退出程序。
账单输入及月份校验:
全部账单可视化展示
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中的订单记录的功能,感兴趣的小伙伴可以自己设计一下