成绩分析
概述
把一份或两份成绩单,转成教师可直接使用的分析结论:三率(优秀率 / 合格率 / 低分率)、成绩进退情况、排名,输出 Excel 多维表格 + HTML 可视化报告,并给出面向教学的解释与建议。
核心计算全部由 scripts/analyze_scores.py 完成,不要手写计算逻辑——口径统一、避免算错。
快速开始
# 首选解释器(已预装 openpyxl)
PY="C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/python.exe"
[ -x "$PY" ] || PY=python # 回退;若提示缺 openpyxl 则先 pip install openpyxl
# 单次考试:三率 + 排名
"$PY" scripts/analyze_scores.py --current 期末成绩.xlsx --out ./成绩分析输出
# 两次考试:额外得到进退分析
"$PY" scripts/analyze_scores.py --current 期末成绩.xlsx --previous 期中成绩.csv --out ./成绩分析输出
脚本运行后会在 --out 目录生成 成绩分析报告_<时间戳>.xlsx 与 .html,同时在控制台打印摘要。
工作流程
第 1 步:确认输入与意图
判断用户处在哪种场景,决定是否要 --previous:
| 用户说法 | 配置 |
|---|---|
| "分析一下这次期中考试成绩" | 只用 --current |
| "对比期中期末,看谁进步了" / "成绩进退" | 加 --previous |
| "排一下班里的名次" | --rank-scope class(默认) |
| "整个年级排一下" | --rank-scope grade(需表内有「年级」列) |
文件已上传但只有文件内容没有本地路径时,先把内容落成本地 .csv 或 .xlsx 再调用脚本。
第 2 步:确认分数线(关键)
默认口径为百分制 优秀 ≥90、合格 ≥60、低分 <40,脚本按各科满分自动折算(如 150 分制 → 135 / 90 / 60)。
出现以下情况必须向用户确认,不要默认套用:
- 学校有自定标准(如优秀 85、低分 30)→ 用
--excellent--pass--low覆盖 - 科目满分不是 100 → 用
--full-marks "语文:150,数学:150,英语:150" - 用户要的"低分率"其实指不及格率(<60)→ 说明区别,建议同时给出「不合格率」(报告已含此列)
一句话确认即可,例如:"按百分制优秀 90 / 合格 60 / 低分 40 算,如果学校另有标准告诉我。"
第 3 步:执行脚本
"$PY" scripts/analyze_scores.py \
--current 本次成绩.xlsx \
--previous 上次成绩.xlsx \
--full-marks "语文:150,数学:150" \
--excellent 90 --pass 60 --low 40 \
--rank-scope class \
--out ./成绩分析输出
常用参数:
| 参数 | 说明 | 默认 |
|---|---|---|
--current / --previous |
本次 / 上次成绩单(必填 / 可选) | — |
--sheet / --prev-sheet |
指定工作表名(多 sheet 时必填) | 第一个 sheet |
--subject-cols |
手动指定科目列,如 "语文,数学,英语" |
自动识别 |
--full-marks |
各科满分 | 100 |
--excellent --pass --low |
优秀线 / 合格线 / 低分线(百分制基准) | 90 / 60 / 40 |
--line-mode |
ratio 按满分折算;absolute 直接用给定分数线 |
ratio |
--rank-scope |
class 班级内 / grade 年级内 |
class |
--progress-mode |
rank 按名次变化 / score 按分数变化 |
rank |
--flat-threshold |
score 模式下判定持平的分数阈值 | 1.0 |
--allow-missing-total |
有缺考科目时仍按有效科目求和参与总分排名 | 关闭 |
--json |
额外输出机器可读 JSON(喂给后续制图/PPT) | 关闭 |
--no-html |
不生成 HTML 报告 | 关闭 |
进退口径怎么选:试卷难度不同的两次考试(如期中 vs 期末)用 rank,名次变化更真实;同一份卷子的前后测(如周测复测)用 score。
第 4 步:解读结果
脚本已算好数字,这一步要把数字翻成教学判断。按「三率 → 分布 → 进退 → 建议」四层来写,参考下面的话术:
三率
- 优秀率看尖子生厚度;合格率看底线;低分率看兜底风险。
- 三率之和不等于 100%,不要合成"综合得分"。
- 单科合格率低于 85% 或低分率高于 10%,点名为重点科目。
分数段分布
- 看「中等段」是否臃肿:中等与及格人数过多说明教学停在"能听懂、不会用",需要拔高训练。
- 看尖子与后段是否两极分化:标准差超过满分的 15% 提示分化明显。
进退
- 先看整体:进步率与退步率的差值,反映班级整体走势(注意两次试卷难度不同时,rank 口径不受影响)。
- 再看分层:优秀层退步要防滑坡,临界层进步说明帮扶有效,后进层大面积退步要查原因。
- 重点列出「进步之星」和「需要关注」名单,教师可直接找学生谈话。
建议(每条都要落到人和科目,不要泛泛而谈)
- 按名次变化幅度排序取前 5 / 后 5。
- 结合分层进退:优秀层退步 → 拔高与心理;临界层 → 精准补差;后进层 → 基础与信心。
第 5 步:交付
用 present_files 同时给出 Excel 和 HTML:
- Excel 适合教师继续加工(筛选、排序、贴进其他表),含冻结窗格与自动筛选。
- HTML 适合快速看结论和汇报,含三率卡片、分数段堆叠条、进退分层图。
结论要点写进回复正文,不要只说"报告已生成"。
输出物结构
Excel 工作表:
| Sheet | 内容 |
|---|---|
| 分析概览 | 各科与总分的三率、均分、中位数、标准差、极值、各条分数线 |
| 分数段分布 | 优秀/良好/中等/及格/不及格/低分的人数与占比 |
| 学生排名 | 总分名次 + 各单科名次 + 各科分数 |
| 进退明细 | 两次考试的分数与名次变化、分层标签、进退判定(有 previous 时) |
| 进退汇总 | 进步/退步/持平人数与比率、幅度分布、分层进退(有 previous 时) |
| 缺考名单 | 缺考科目明细 |
数据准备与容错
脚本已处理以下情况,无需预处理:
- 表头不在第一行:自动在前 12 行内定位含「姓名/学号/考号」的表头行(跳过"XX中学考试成绩表""制表:教务处"等标题行)。
- 列名变体:学号/考号/准考证号、姓名/学生姓名、班级/班别、总分/合计均可识别。
- 自动识别科目列:排除序号、性别、排名、总分等元数据列,其余数字列视为科目。
- 缺考:
缺考缺请假-/空值均识别为无成绩,不计入三率分母,不参与总分排名,并列入「缺考名单」。 - 并列名次:竞赛式排名(1、2、2、4),同分同名次、后续跳号。
- 编码:CSV 自动尝试 UTF-8 / GBK / GB18030,WPS 与 Excel 导出的文件都可直接读。
- 只支持 .xlsx / .csv,
.xls会提示先另存,不要尝试解析。
若科目列识别错误(例如把"班级排名""体育"当成科目),用 --subject-cols "语文,数学,英语" 显式指定。
指标口径
三率分母、进退判定、排名规则与边界情况的严格定义见 references/metric-definitions.md。
在回答用户关于"为什么这个人的优秀率算进/没算进""名次为什么并列"时,先读该文件再解释,避免口径说错。
示例数据
assets/sample/期中成绩.csv 与 assets/sample/期末成绩.csv 是 40 名学生、两班、三科、含缺考的示例数据,可用于试跑验证:
"$PY" scripts/analyze_scores.py --current assets/sample/期末成绩.csv \
--previous assets/sample/期中成绩.csv --out ./示例输出
预期:40 人、每科 39 人有效、总分 37 人有效、3 人缺考。
资源
scripts/analyze_scores.py:分析引擎(读表 → 三率 → 排名 → 进退 → 生成 Excel/HTML)references/metric-definitions.md:三率、进退、排名的口径定义与边界情况assets/sample/:可直接试跑的两份示例成绩单