# 生成测试数据 · 课堂演示件
#
# 作用：在本文件旁边建立 原始表格 与 原始表格_CSV 两个文件夹，
#       各生成十份格式相同的成绩表，其中若干份带有事先安排好的脏数据。
# 用法：直接运行。重复运行会清空并重建，可用于重置练习环境。
#
# 需要 pandas 与 openpyxl：pip install pandas openpyxl

import csv
import random
from pathlib import Path

import pandas as pd

xlsx_dir = Path(__file__).with_name('原始表格')
csv_dir = Path(__file__).with_name('原始表格_CSV')

# ① 清空并重建两个文件夹，使每次生成的内容一致
for d in [xlsx_dir, csv_dir]:
    if d.exists():
        for p in d.iterdir():
            p.unlink()
    else:
        d.mkdir()

random.seed(1101)          # 固定随机种子，保证每台机器生成的数据相同

surnames = list('李王张刘陈杨黄赵周吴徐孙马朱胡林郭何高罗')
givens = ['雅琴', '文博', '一凡', '思远', '嘉伟', '晓宇', '梦洁', '子涵',
          '浩然', '若溪', '博文', '欣怡', '天磊', '静姝', '鹏程', '语彤']
classes = ['数据2301', '数据2302', '数据2303']

number = 2023000
rows_all = []

# ② 十份表，每份八到十二人
for i in range(1, 11):
    rows = []
    for _ in range(random.randint(8, 12)):
        number = number + 1
        name = random.choice(surnames) + random.choice(givens)
        cls = random.choice(classes)
        daily = random.randint(60, 100)
        final = random.randint(55, 100)

        # ③ 第 3、5、8 份表中安排缺失值：平时分留空
        if i in [3, 5, 8] and random.random() < 0.25:
            daily = None

        # ④ 第 9 份表的班级列混入全角空格
        if i == 9:
            cls = '\u3000' + cls + ' '

        rows.append({'学号': number, '姓名': name, '班级': cls,
                     '平时分': daily, '期末分': final})

    # ⑤ 第 7 份表中间插入两个全空行，模拟有人删了内容却没有删行
    if i == 7:
        blank = {'学号': None, '姓名': None, '班级': None,
                 '平时分': None, '期末分': None}
        rows.insert(3, dict(blank))
        rows.insert(4, dict(blank))

    name = '成绩表_' + str(i).zfill(2)
    frame = pd.DataFrame(rows)
    frame.to_excel(xlsx_dir / (name + '.xlsx'), index=False)

    # ⑥ 同一份数据另存一份 CSV，供无法安装第三方库时使用
    with open(csv_dir / (name + '.csv'), 'w', encoding='utf-8-sig', newline='') as fp:
        writer = csv.DictWriter(fp, fieldnames=['学号', '姓名', '班级', '平时分', '期末分'])
        writer.writeheader()
        for r in rows:
            writer.writerow({k: ('' if v is None else v) for k, v in r.items()})

    rows_all.extend(rows)
    print('已生成', name, '，', len(rows), '行')

print()
print('两个文件夹各十份表，合计', len(rows_all), '行（含空行）')
print('其中安排的脏数据：第 07 份中间两个全空行；第 09 份班级列含全角空格；'
      '第 03、05、08 份平时分有空值')
input('按回车键结束')
