python (第九章 项目开发阶段)
第6周学习计划:项目开发
目标:通过小型项目掌握开发流程,熟悉从需求分析到代码实现的完整过程。
项目总览
- 小型项目:个人记账工具(本周重点)。
- 后续方向:天气查询工具、电影推荐系统(第7-8周)。
项目:个人记账工具
目标:
编写一个命令行程序,记录用户的收入和支出,按月统计并生成简单报表。
功能需求
- 添加记录:输入金额、类别(收入/支出)、日期。
- 查看记录:显示所有记录。
- 按月统计:显示某个月的收入、支出和余额。
- 保存到文件:记录持久化存储。
技术点
- 类和对象(OOP)。
- 文件操作(JSON)。
datetime
模块处理日期。- 列表和字典操作。
代码实现
以下是完整代码,我会逐步讲解:
from datetime import datetime
import json
class Transaction:
def __init__(self, amount, category, date):
self.amount = amount
self.category = category # "income" 或 "expense"
self.date = datetime.strptime(date, "%Y-%m-%d")
def __str__(self):
return f"{self.date.strftime('%Y-%m-%d')} | {self.category} | {self.amount}"
class AccountBook:
def __init__(self, filename="transactions.json"):
self.transactions = []
self.filename = filename
self.load_transactions()
def add_transaction(self, amount, category, date):
if category not in ["income", "expense"]:
raise ValueError("类别必须是 'income' 或 'expense'!")
if amount < 0:
raise ValueError("金额不能为负!")
transaction = Transaction(amount, category, date)
self.transactions.append(transaction)
self.save_transactions()
print(f"已添加记录:{transaction}")
def view_transactions(self):
if not self.transactions:
print("暂无记录!")
else:
print("\n所有记录:")
for i, t in enumerate(self.transactions, 1):
print(f"{i}. {t}")
def monthly_report(self, year, month):
income = 0
expense = 0
for t in self.transactions:
if t.date.year == year and t.date.month == month:
if t.category == "income":
income += t.amount
else:
expense += t.amount
balance = income - expense
print(f"\n{year}年{month}月报表:")
print(f"收入:{income}")
print(f"支出:{expense}")
print(f"余额:{balance}")
def save_transactions(self):
data = [{"amount": t.amount, "category": t.category, "date": t.date.strftime("%Y-%m-%d")}
for t in self.transactions]
with open(self.filename, 'w', encoding='utf-8') as f:
json.dump(data, f)
def load_transactions(self):
try:
with open(self.filename, 'r', encoding='utf-8') as f:
data = json.load(f)
self.transactions = [Transaction(t["amount"], t["category"], t["date"]) for t in data]
except FileNotFoundError:
pass
def main():
book = AccountBook()
while True:
print("\n=== 个人记账工具 ===")
print("1. 添加记录")
print("2. 查看所有记录")
print("3. 查看月度报表")
print("4. 退出")
choice = input("请选择操作(1-4):")
if choice == "1":
try:
amount = float(input("请输入金额:"))
category = input("请输入类别(income/expense):")
date = input("请输入日期(格式:YYYY-MM-DD):")
book.add_transaction(amount, category, date)
except ValueError as e:
print(f"错误:{e}")
except Exception:
print("错误:请输入有效数据!")
elif choice == "2":
book.view_transactions()
elif choice == "3":
try:
year = int(input("请输入年份(如 2025):"))
month = int(input("请输入月份(1-12):"))
book.monthly_report(year, month)
except ValueError:
print("错误:请输入有效的年月!")
elif choice == "4":
print("谢谢使用!")
break
else:
print("无效选择,请输入 1-4!")
if __name__ == "__main__":
main()
代码讲解
-
类设计:
Transaction
:表示单条记录,包含金额、类别、日期。AccountBook
:管理所有记录,提供操作方法。
-
功能实现:
add_transaction()
:添加记录,验证输入。view_transactions()
:显示所有记录。monthly_report()
:统计指定月份的收支。save_transactions()
和load_transactions()
:用 JSON 实现数据持久化。
-
日期处理:
- 用
datetime.strptime()
解析字符串日期。 - 用
strftime()
格式化输出。
- 用
动手实践
- 新建文件
account_book.py
,复制代码。 - 运行程序,试试:
- 选
1
,添加记录:金额 500,类别income
,日期2025-02-25
。 - 选
1
,添加记录:金额 200,类别expense
,日期2025-02-26
。 - 选
2
,查看所有记录。 - 选
3
,输入2025
和2
,查看月报。 - 选
4
,退出。
- 选
- 检查
transactions.json
,确认数据保存。
预期输出
- 添加后查看:
所有记录:
1. 2025-02-25 | income | 500
2. 2025-02-26 | expense | 200
- 月报:
2025年2月报表:
收入:500
支出:200
余额:300
小挑战
- 分类统计:在月报中显示不同类别(如“工资”、“餐饮”)的支出。
- 删除记录:添加删除功能。
- CSV 支持:将数据保存为 CSV 而不是 JSON。
第6周进展
我们完成了一个小型项目,接下来可以:
- 第7-8周:开发天气查询工具或电影推荐系统。
- 扩展:优化当前项目。