需求分析与计费逻辑定义
在开发档案培训收费系统前,必须明确“按周收费”的具体技术定义。档案培训通常以连续天数计算,而非自然周(周一至周日)。本系统采用“连续7天为一周期,不足一周按一周计算”的逻辑(即向上取整)。例如,培训8天计费为2周,培训3天计费为1周。系统需支持学员信息录入、自动计算周期、生成费用报表及数据导出功能。
开发环境准备与依赖安装
本指南使用Python作为开发语言,因其内置强大的日期处理库和文件操作能力,无需安装复杂的数据库或Web框架即可满足需求。
1. 安装Python环境
请确保操作系统已安装Python 3.8或更高版本。打开终端或命令行窗口,输入以下命令检查版本:
python --version
若未安装,请直接访问Python官网下载对应操作系统的安装包并安装。本系统仅使用Python标准库(datetime, csv, math),无需执行任何pip install命令,确保了环境配置的零门槛。
数据存储结构设计
为保持系统轻量且易于通过Excel查看,我们采用CSV文件作为数据存储介质。请在项目根目录下创建一个名为trainees_data.csv的文件,并写入以下表头。如果文件不存在,系统代码会自动创建。
数据字段定义如下:
- id:学员唯一标识(自动生成)。
- name:学员姓名。
- start_date:培训开始日期(格式:YYYY-MM-DD)。
- end_date:培训结束日期(格式:YYYY-MM-DD)。
- weekly_rate:每周收费标准(单位:元)。
- total_weeks:计算出的总周数。
- total_fee:计算出的总费用。
核心计费算法实现
在编写完整系统前,先解析核心的计费逻辑。我们需要处理日期差值,并将其转换为周数。关键技术点在于使用datetime模块解析日期字符串,并利用timedelta计算天数差。
计算公式逻辑:
- 解析开始日期和结束日期。
- 计算天数差:
diff_days = (end_date - start_date).days。
- 处理跨天问题:如果培训包含开始和结束当天,通常需要加1天(根据业务规则,本系统默认包含首尾两日,即实际培训时长为天数差+1)。
- 计算周数:
weeks = math.ceil(total_days / 7)。
完整管理系统代码实现

将以下代码完整复制并保存为training_billing_system.py。该脚本实现了数据录入、自动计费、列表展示和CSV持久化存储功能。
```python
import csv
import os
import math
from datetime import datetime
DATA_FILE = 'trainees_data.csv'
def init_csv():
"""初始化CSV文件,如果不存在则创建并写入表头"""
if not os.path.exists(DATA_FILE):
with open(DATA_FILE, mode='w', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow(['id', 'name', 'start_date', 'end_date', 'weekly_rate', 'total_weeks', 'total_fee'])
def calculate_fee(start_date_str, end_date_str, rate):
"""
核心计费函数
:param start_date_str: 开始日期字符串 YYYY-MM-DD
:param end_date_str: 结束日期字符串 YYYY-MM-DD
:param rate: 每周费率
:return: (周数, 总费用)
"""
try:
start = datetime.strptime(start_date_str, "%Y-%m-%d")
end = datetime.strptime(end_date_str, "%Y-%m-%d")
except ValueError:
return None, None
计算天数差,加1是因为包含开始和结束当天
days_diff = (end - start).days + 1
if days_diff <= 0:
return 0, 0
向上取整计算周数
weeks = math.ceil(days_diff / 7)
total_fee = weeks rate
return weeks, total_fee
def add_trainee():
"""交互式添加学员"""
print("\n 添加新学员 ")
name = input("请输入学员姓名: ")
start_date = input("请输入培训开始日期 (YYYY-MM-DD): ")
end_date = input("请输入培训结束日期 (YYYY-MM-DD): ")
try:
rate = float(input("请输入每周收费标准 (元): "))
except ValueError:
print("错误:费率必须是数字。")
return
weeks, fee = calculate_fee(start_date, end_date, rate)
if weeks is None:
print("错误:日期格式不正确,请使用 YYYY-MM-DD 格式。")
return
生成简单ID (基于当前时间戳)
trainee_id = datetime.now().strftime("%Y%m%d%H%M%S")
写入CSV
with open(DATA_FILE, mode='a', newline='', encoding='utf-8') as f:
writer = csv.writer(f)
writer.writerow([trainee_id, name, start_date, end_date, rate, weeks, fee])
print(f"学员 {name} 添加成功!培训时长 {weeks} 周,总费用 {fee} 元。")
def view_report():
"""查看所有学员收费报表"""
print("\n 档案培训收费报表 ")
print(f"{'ID':<12} {'姓名':<10} {'开始日期':<12} {'结束日期':<12} {'周数':<6} {'费率':<8} {'总费用':<8}")
print("-" 70)
if not os.path.exists(DATA_FILE):
print("暂无数据。")
return
with open(DATA_FILE, mode='r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
print(f"{row['id']:<12} {row['name']:<10} {row['start_date']:<12} {row['end_date']:<12} "
f"{row['total_weeks']:<6} {row['weekly_rate']:<8} {row['total_fee']:<8}")
def main():
init_csv()
while True:
print("\n===== 档案培训收费管理系统 =====")
print("1. 添加学员及计费")
print("2. 查看收费报表")
print("3. 退出系统")
choice = input("请选择操作 (1-3): ")
if choice == '1':
add_trainee()
elif choice == '2':
view_report()
elif choice == '3':
print("系统已退出。")
break
else:
print("无效输入,请重新选择。")
if __name__ == "__main__":
main()
```
系统部署与实操演练
代码完成后,按照以下步骤进行实际操作,验证按周收费逻辑的准确性。
1. 启动系统
在命令行中进入脚本所在目录,执行以下命令启动交互式界面:
python training_billing_system.py
2. 实操案例一:不足一周按一周计算
- 选择菜单 1。
- 输入姓名:张三。
- 输入开始日期:2023-10-01。
- 输入结束日期:2023-10-03(共3天)。
- 输入每周费率:500。
系统应输出:培训时长 1 周,总费用 500 元。验证了3天不足7天按1周计费的逻辑。
3. 实操案例二:跨周且包含余数计算
- 再次选择菜单 1。
- 输入姓名:李四。
- 输入开始日期:2023-10-01。
- 输入结束日期:2023-10-15(共15天)。
- 输入每周费率:500。
系统应输出:培训时长 3 周,总费用 1500 元。验证逻辑:15天 / 7 = 2周余1天,向上取整为3周。
4. 查看与数据导出
- 选择菜单 2,屏幕将打印格式化的CSV数据表格。
- 直接使用Excel或WPS打开项目目录下的
trainees_data.csv文件,即可看到所有已录入的收费明细。这满足了财务部门直接进行数据二次处理的需求。
通过以上步骤,你已成功构建了一个零依赖、逻辑严密的档案培训按周收费系统。该系统利用Python的标准库解决了日期计算中的边界问题,并实现了数据的持久化存储,可直接应用于小微型培训机构的日常收费管理。