学业诊断书 · 一人一份
一句话:给每个学生出一份能落到"下周做什么"的诊断书,而不是一张只有名次的表格。
何时用
- 段考/期末后,班主任要给全班每人一份诊断材料
- 家长会前,需要按人准备可沟通的证据与抓手
- 需要目标校对标(还差多少名、哪几科在拖后腿)
- 已有"进退数据表",但原表进退公式不可信、表头混乱
不适用:只看班级均分或知识点掌握率的学情分析(那是另一类任务)。
先问清楚,再动手(不可跳过)
排名表的列结构每个班每学期都不同。必须先向用户确认下列 6 项,再开始解析。
用 wizard.py 走问答,或直接把问题抛给用户。
| # | 必问项 | 为什么要问 | 默认/推断方式 |
|---|---|---|---|
| 1 | 年级(初一/初二/初三) | 决定目标校结论能否下"升学判断"。初一二只作长期参考,不下结论 | 默认初三 |
| 2 | 年级总人数 | 校内百分位=名次÷该值。这一项错了,全部结论都会错 | 可按表中最大排名自动推断,但必须请用户确认 |
| 3 | 排名口径(校排名/班级排名/不确定) | 若是班级排名,不能用它换算市区或目标校 | 默认校排名;不确定则全部降级标注"待确认" |
| 4 | 数据覆盖到哪次考试 | 决定"最近一次"是谁,以及趋势结论的有效期 | 取最后一列有值的考试 |
| 5 | 班级名称 | 用于文件名与标题 | 必填 |
| 6 | 目标校清单 | 是否沿用内置切线,或换成本地数据 | 内置 2026 泉州中心市区 13 校 |
解析后还需让用户复核两项(脚本会自动体检并打印):
- 科目块与考试次数是否符合实际(自动探测结果)
- 疑似复制填充列、表头重名(自动告警,由用户决定是否剔除)
> 若用户只丢一个文件、什么都没说,不要直接跑全量。先 dry-run 出体检报告,把上面 6 项一次性问清。
执行流程
步骤 0:数据体检(先跑,不生成文档)
python run_all.py "<排名表.xlsx>" --class-name "27届8班" --grade 初三 --out "<输出目录>" --dry-run
输出三样东西,逐条给用户看:
1. 探测到的科目块与考试次数
2. 疑似复制填充列(相邻列排名变化中位数 < 10 名)
3. 表头重名(同一科目内出现两次"期末"之类)
步骤 1:先出 1 人样例
python run_all.py "<表.xlsx>" --sample "<学生姓名>" ...
把样例给用户看,确认版式与结论口径无误。用户认可后再全量。
步骤 2:全量生成
python run_all.py "<表.xlsx>" --class-name "27届8班" --grade 初三 --out "<输出目录>"
产出:
<输出目录>/
├── <班级>_<姓名>_诊断书.md ×N(每人 8 章 + 附录)
├── <班级>_全班诊断汇总.md
├── <班级>_班级整体诊断报告.md
├── _00_生成核对清单.md ← 交付前自检结果
└── images/ *.png (每人趋势图 + 雷达图)
步骤 3:验收
核验脚本自动跑,四项判据:章节齐全 / 图片可用 / 无错误口径 / 含对标结论。
交付前必须亲自看一份(建议看中间段位与数据不足各一份)。
口径铁律(违反则结论整体反转)
- 校内百分位=名次 ÷ 年级人数。严禁用名次 ÷ 市区考生数——两者不是同一把尺子,混用会把后段生算成"已达名校线"。
- 进退一律重算:进退 = 上次排名 − 下次排名(正数=进步)。原表进退列常见"累计口径""跨列错位",一律不采信。
- 空值不补 0,不参与任何统计与趋势。
- 排名不是分数,数值越小越好。
- 目标校切线是往年数据,不等于本届录取线;换算结论一律标注估算性质。
- 数据不足(有效考试 ≤ 2 次)的学生出"数据不足版":不画雷达图、不下趋势结论、不编造薄弱点。
- 交付给家长前提示匿名化(文件含真实姓名与年级排名)。
详细推导与反例见 references/口径铁律.md。
初中各年级适配
| 初一 | 初二 | 初三 | |
|---|---|---|---|
| 科目 | 语数英 + 政史地生(各地不同) | 常加物理;生物地理可能已考完 | 常加化学;生物地理结业 |
| 科目处理 | 完全自动探测,无需改代码 | 同左 | 同左 |
| 目标校结论 | 只作长期参考,不下升学判断 | 同左,可加"距目标还差多少" | 可下"公办线可达性"结论 |
| 措辞强度 | 第0节标"目标定位(初一·参考)",第6节加警示 | 同左 | 标"公办线可达性" |
科目变化不需要改任何代码:parse_data.py 按第 1 行科目名切块、第 2 行"进退"关键字分列,任意科目组合都能识别。
环境
- 系统 Python 3.12:
C:/Users/lyhroger/AppData/Local/Programs/Python/Python312/python.exe
(需matplotlib、numpy;不需要 openpyxl——解析走原始 XML) - 中文路径经命令行传参可能乱码,优先在脚本内写绝对路径,或设
PYTHONIOENCODING=utf-8
参数来源优先级
run_all.py 命令行参数 > config.json > cfg.py 内置默认值。
换班级/换学校只需改 config.json,不要改代码。
已知边界
- 目标校切线为泉州中心市区 2026 数据;外地使用需替换
config.json的schools(或cfg.py的DEFAULT_SCHOOLS)。 - 只处理"排名"型数据。若是"分数"型,需先转排名,否则雷达图与百分位全部失真。
- 一次考试的样本量少于 2 次时,趋势类结论不成立,脚本会自动降级。