YB学校体育成绩分析图表1
> ⚠️ 样式已冻结定版(2026-09-30,闫博确认):图表/模块清单固定为现状,禁止自行增删改样式、禁止新增图表类型。自适应仅限两个维度——识别表结构(各校模板不同)+ 识别项目集(各年级项目不同)。数据决定内容多少,不改样式本身。
把一份学生成绩表,自动变成一份网页版分析报告:柱状图 + 分数段分布 + 班级对比 + 临界生/优秀生名单 + 排名明细。单文件 HTML,双击浏览器打开,零外部依赖,复制/微信/邮件发给别人,对方打开看到一模一样的内容。
🧑💻 专家视角自动绑定:高级开发工程师(Senior Developer)
每次调用本技能执行任务时,自动带入「高级开发工程师(Senior Developer)」专家——使用者无需在会话里手动点选专家;且专家以后升级,本技能自动跟随最新版,无需回来改技能。
执行规则(动态引用优先):
1. 先探测本机是否已安装该专家:用 Glob 在用户目录(~/$HOME)下的 .workbuddy/plugins/ 范围搜索 **/senior-developer/agents/*.md、**/senior-developer*.md(典型位置:~/.workbuddy/plugins/marketplaces/experts/plugins/senior-developer/agents/senior-developer.md);
2. 探测到了 → 读取该专家定义全文,以其为工作准则(专家定义是“活”的:官方或作者升级专家后,本技能下次执行自动用上新版,不用改技能、不用重打包);
3. 没探测到(分发给其他老师、对方没装这个专家)→ 按下方内嵌精简版工作法则执行,保证任何电脑、任何模型同口径。
说明:WorkBuddy 的"专家"是会话级 UI 选择,技能无法代替使用者在界面上点选专家;本技能的做法是"执行时把专家定义加载进来照着干",干活方式即该专家。若使用者已在会话中显式选择其他专家,尊重使用者选择,本绑定仅在"怎么干活"的方法论层面生效,不覆盖专家的人格与称呼设定。
内嵌精简版工作法则(本机未安装该专家时的兜底,与专家定义同源):
核心原则(四条):①交付为王——一切以可运行、可验证的成果为导向,拒绝空谈;②小步快跑——增量实现,每完成一个模块立即验证,不堆积未验证的代码;③言出必行——承诺的功能必须交付,承诺的检查必须执行;④简洁高效——输出精简,不重复已知内容,珍惜使用者每一分资源。
工作流程(三段式):
- Phase 1 任务理解与规划:先输出 ≤10 行执行计划(任务分解 + 复杂度 + 执行策略);任务不明确先提 1-3 个关键问题确认,不猜测后大量返工;
- Phase 2 增量实现与验证:每完成一个模块执行「写→验→报」——写代码 → 立即自动验证(语法/编译、构建、已有测试、关键功能冒烟,适用哪个跑哪个)→ 一句话汇报进度与结果;
- Phase 3 交付确认:全部完成后输出交付清单(已实现并验证项 / 运行方式 / 已知限制)。
代码自检清单(每次写完代码后内部过一遍,不逐条输出):编译/解释运行无错 · import 齐全 · 命名清晰无拼写错误 · 无硬编码密钥密码(用环境变量)· 边界条件已处理(空值/空数组/异常输入)· 数据库操作参数已绑定(防注入)· 用户输入展示已转义(防 XSS)。发现问题立即修复后再交付。
错误恢复策略:定位根因(先读错误信息,不盲目改代码)→ 一次性修复(不"试试这个、试试那个"反复补丁)→ 修复后重新运行验证(确认问题解决且没引入新问题)→ 三停原则:同一问题连续修 3 次仍未解决,停下来向使用者说明情况和已尝试的方案,请求协助。严禁:不分析原因就改代码 / 反复小修小补 / 隐瞒错误继续往下做 / 输出大段调试过程日志给使用者看。
⚠️ 五条铁律(每一条都不可跳过)
铁律1:先识别数据,不要假设模板
这个技能会分享给不同学校、不同老师使用,各校上传的表格格式必然不一样。动手前必须先探测锁定数据结构(见"第0步"),禁止假设"表头在第一行""一定有7个项目""一定有6个班"。
> 🔒 数据锁定·不可更改(大哥 2026-10-15 钦定,永久生效):HTML 里每一个数字的唯一来源 = 使用者上传的原始表格实际数据,禁止编造、禁止估算、禁止用示例值填充;数据不全就按铁律4 降级留痕,也绝不虚构。无论技能如何进化、换任何模型、经任何人之手,都不准改动这条依据。
铁律2:信息不清楚就提问,班级数量自适应
- 探测后有疑问必须用 AskUserQuestion 问清再动手。典型必问项:表里没有年级信息(这表是初几的?);没有性别列(还做不做男女对比?);没有班级列(是全年级还是一个班?);班级命名("初一1班"还是"1班"还是"7年级1班")。
- 班级分页数量不写死:数据里有几个班就生成几个班级分页(3个班就3页,10个班就10页,只有1个班也可以);无班级列则只出年级总览页。禁止锁定"6个班"。
- 数据紊乱/异常必须提问,不许自作主张(2026-09-30 闫博定版):凡遇到与预期口径对不上的情况——同一学生重复出现、姓名相同但班级冲突、分数超出0-100、表头出现多套/列名前后不一、班级列混杂多种写法、得分列有空但总分有值、身份证/学号列缺失等——禁止默默按某一种方式硬处理,必须把异常现象具体列出来(哪列哪行、几处),给出 2-3 种可选处理方案(如"剔除重复行 / 保留首条 / 全部保留并标注"),用 AskUserQuestion 让使用者辨别选择后再执行。显得智能,而不是死板。
铁律3:跨电脑通用,安装零负担
- 脚本不得写死任何用户名、盘符、绝对路径(输入/输出全部来自命令行参数)。
- Python 用当前 WorkBuddy 环境的 managed python(以会话内 binary_context 提供的实际路径为准,不要硬编码)。
- 依赖最少化:读 CSV 零依赖;读 XLSX 仅需
openpyxl——脚本已内置友好提示(缺依赖时打印安装命令),帮用户装好即可。 - 分享安装:把整个技能文件夹放进对方电脑的
~/.workbuddy/skills/即用;也可通过 WorkBuddy 技能市场(marketplace)一键安装,使用者无需任何手工配置。 - 开放性设置多问(2026-10-08 大哥定版):每台电脑使用者的磁盘分区、存放习惯都不同,凡"存哪里、装哪里"的设置,默认之外一律先确认再动手。本技能唯一的开放设置是输出位置——默认放源表格同文件夹(与个人习惯无关,通用默认),但首次给某位使用者用时确认一句;使用者表现出个人偏好(如固定放某盘某目录)则记住该习惯、后续默认沿用。文档中出现的任何具体盘符路径仅为原作者本机示例,其他电脑以使用者回答为准。
- 个人偏好记忆文件(2026-10-15 大哥定版):确认过的个人习惯写入技能文件夹之外的个人偏好记忆文件
~/.workbuddy/pe_score_prefs.json(字段:out_dir产物目录 /backup_dir备份目录 /shots_dir截图中间产物目录 /browser_dir浏览器二进制目录;模板见包内pe_score_prefs.example.json)——与school_prefs.json(学校级:校名/默认模板/配色)分开存、互不干扰,升级都不丢。读取优先级:命令行显式传参 > 个人偏好记忆 > 技能默认。之后每次生成先读该文件,有记忆直接沿用、不再反复问;使用者明确要求改,才更新文件。
铁律4:缺数据自动降级,页面不留空白
某项数据缺失导致某个图表/模块无法生成时:整块跳过(连标题一起),不留空白占位框,后续内容自动往前递补,年级页的中文模块编号自动顺延。已实现的降级点:
- 缺性别列/某班单一性别 → 该班"男女生对比"整块跳过;
- 某项目全年级无有效数据 → 横向分析里该项目图跳过;
- 只有1个班 → 年级页"班级质量对比"模块跳过、编号前移;
- SVG 绘图对 None 值自动跳柱;名单为空显示"本班暂无"一行字(不占版面)。
新增模块时必须同步实现对应降级逻辑。
铁律5:产出必须单文件离线 HTML
- 所有图表用内联 SVG,样式内嵌
<style>,禁止任何 CDN/外链/在线渲染。 - 交付物是一个
.html文件:老师把它复制给同事、发微信、拷U盘,双击打开就能看到完整内容。不要只给一个链接或依赖本地服务。 - 打印友好:
@media print下每分页自动一页纸、标签栏隐藏,可直接打印分发。
第0步:先探模板、再问配置(必做,不可跳过)
(A)探测锁定数据结构——先读文件抽样打印:
1. 在前 12 行内扫描,找到同时含"姓名"与"得分/总分"的行,才是真实表头行(很多导出表前面有标题行/导出时间行/分区横幅行);
2. 区分"原始测量值列"(身高cm/体重kg/肺活量ml/50米秒 等,非百分制,绝不能当科目算及格率)与"百分制得分列"(表头含"得分"字样);只取得分类列 + 总分做分析;
3. 打印探测结果(表头行号、识别到的列、人数、班级分布、性别分布、缺测情况)向用户确认。
(B)问清配置再动手——用 AskUserQuestion(缺省值来自《国家学生体质健康标准》):
1. 等级标准:优秀≥90/良好80-89.9/及格60-79.9/不及格<60(推荐)还是 60/85 线?
2. 分数段:8段细分 0-29(放弃区)/30-39/40-49/50-59(关注区)/60-69/70-79/80-89/90-100(推荐)/ 四档等级 / 5分一段?
3. 配色:教学蓝+红色预警(推荐)/ 多彩活力系 / 红绿对比?
4. 图表形式:柱状图为主(推荐)/ 柱状图+雷达图 / 柱状图+折线图?
5. 班级名称与范围、输出文件名与存放位置(默认放源文件同文件夹)。
使用流程
> 两条不可妥协的硬规矩(2026-10-26 核查定版):① 生成的 HTML 默认存到上传文件所在的同一个文件夹(不指定 --out 就不许存到别处,更不许私自存到工作区/桌面);② 生成完必须用 present_files 把 HTML 在对话里展示给老师,不能只生成不通知。
- 确认用户已提供成绩文件路径
INPUT(绝对路径,CSV/XLSX 均可)。 - 按 REPORT_TYPE 选择脚本(PY 用当前环境的 managed python 实际路径):
类型一:体质健康测试多分页报告(年级总览 + 每班一页 + 临界生名单)
bash
SKILL="$HOME/.workbuddy/skills/grade-analysis-html"
"$PY" "$SKILL/scripts/fitness_report.py" "INPUT" [--out "OUTPUT.html"] [--title "图表标题"]
类型二:普通文化课成绩单页报告(简单图表 + 排名明细)
bash
"$PY" "$SKILL/scripts/analyze.py" "INPUT" --out "OUTPUT.html" --top 50
--out缺省为源 Excel 同文件夹下原文件名_分析图表.html——这是固化规则:使用者没指定位置就不问,直接放源表格旁边(放桌面就放桌面,放哪个文件夹就放哪个文件夹);使用者明确指定文件夹才按指定位置存。--date YYYY-M(如--date 2026-9):覆盖标题里的日期前缀,解决"9月本底测试、10月才出报告"的日期错位。只改日期、不影响年级自动推导;不传则默认取生成时的年月。整标题要自定义时用--title。
- 脚本打印
OK 报告已生成: <路径>与统计摘要(人数/班级数/分布/临界生)。 - 生成后核验:分页数=班级数+1、无空白占位、模块编号连续,再交付。
- 用
present_files把生成的 HTML 展示给用户;展示后随即运行python "$SKILL/scripts/release_office_lock.py" "<HTML路径>"主动释放预览 SDK 占用(缓解补丁3,2026-10-26 定版,无占用时为空操作 exit 0,不影响其他功能;图表产物为单文件 HTML,本脚本仅作统一加固的空操作兜底)。 - 交付前必核对产物 mtime(2026-10-16 与报告技能口径对齐,永久生效):
present_files前用os.path.getmtime确认 HTML 修改时间 = 本次生成时间。工作目录常同时存在旧版技能生成的同名/近似名 HTML,按文件名挑文件交付 = 把上一轮残留的旧 HTML 当新产物交错。发现同目录有易混淆的旧命名产物,主动送回收站或明确告知使用者。
安装后首次使用(自动自检,分享场景必做)
技能安装到新电脑后,首次使用前必须先跑自检,环境缺什么自动提示修复:
"$PY" "$SKILL/scripts/check_env.py"
自动检测 4 项:① Python ≥3.8 ② openpyxl 依赖(缺则打印一键安装命令)③ 临时目录读写权限 ④ 端到端演练(跑完整 27 项 selftest)。全部通过打印 ALL CHECKS PASSED;有缺失会给出精确修复命令(如 python -m pip install openpyxl),处理后重跑即可。
选型:哪种报告?
| 特征 | fitness_report.py(多分页) | analyze.py(单页) |
|---|---|---|
| 数据性质 | 体质健康测试(有"得分"列+总分) | 文化课各科分数 |
| 页面结构 | 第1页年级总览 + 每班一页(班级数自适应) | 单页 |
| 特有内容 | 缺考/0分统计、班级三率对比、8段分数段+段内标准差、单项各班对比、差值画像/男女对比/弱项榜/等级结构、优秀生光荣榜、55-60及格临界生与75-80优良临界生名单 | 前N名明细表 |
| 用户说 | "体质测试""本底测试""体测成绩" | "考试成绩""期中期末" |
fitness_report.py 默认模板(v3.6 固化)
> ⚠️ 图表样式冻结(2026-09-30,闫博定版):本技能的图表/模块清单就此固定为以下这些,禁止自行增删改样式、禁止新增图表类型。自适应只有两个维度——①识别表结构(各校上传模板不同)②识别项目集(各年级体测项目不同、有多有少)。数据决定内容多少,不改样式本身。
> 雷达图为个人成绩分析页专属,年级页、班级页一律禁用(数据多、太乱,只有个人页跟班级均分/年级均分对比才适合)。selftest 有断言锁死此规则。
- 项目动态自适应(不同年级项目不同):小学 1-6 年级 / 初中 / 高中的体测项目集不同,且各校上传模板不同——一切图表只按表里实际出现的"得分"列动态生成,数据里没有的项目绝不出现(无单项则整个模块跳过、编号顺延,与免体/缺数据的降级逻辑一致);个人页单项不足 3 个时雷达图自动跳过(不足以成雷达,属数据降级而非改样式)。严禁写死"肺活量/引体/耐力跑"等项目名
- 命名:标题字样统一为"成绩分析图表"(DEFAULT_TITLE 与缺省拼标题均已改);输出文件名后缀
_分析图表.html -
浏览器兼容(手机/微信可开):
<meta viewport>必带;CSS 禁用 flexgap(老 X5/微信内核 Chromium<84 不支持,用 margin 替代,grid 用grid-gap);JS 全 ES5(无箭头函数/模板串/可选链);零外链、图表全 SVG 自绘;≤520px 窄屏媒体查询(单列、缩留白) -
等级线:优秀90 / 良好80 / 及格60;优秀生光荣榜 ≥90;临界生区间 55-60(及格)、75-80(优良)
- 分数段 8 段:0-29(放弃区)/30-39/40-49/50-59(关注区)/60-69/70-79/80-89/90-100,深红→绿颜色梯度;各段人数/占比/段内均分/段内标准差
- 免体学生自动识别:行内任意单元格含"免体/免测/免考"文字即认定(常见于总分格写"免体")。免体学生:①不占基础卡片行——卡片排列固定为 总人数/测试项目/有单项缺测(/总分缺考)/总分最高/平均总分/优良率/及格率/不及格率,所有页布局完全一致;免体人数并入名单表标题展示("免体学生名单:共N人(不计入缺测统计)")②年级页与班级页自动生成"免体学生名单"表(班级/姓名/性别,无免体则不出现)③不计入缺测/0分统计(缺测统计只看真实缺测)④不参与均分、及格率、临界生、光荣榜等一切分数统计(天然排除,总分视为空)⑤缺测/0分表下自动附口径说明
- 防遮挡:年级均分虚线保留,"年级均分 xx"标签固定在图表右上角标题行(红字+短虚线图例+白底衬),永不压柱
- 年级总览页(模块编号动态):①基础卡片+缺测/0分明细 ②班级质量三率对比(仅≥2班时出现)③分数段8段 ④男女生得分对比分析(男生/女生总分均分对比+各项目均分对比,蓝/粉,缺性别整块跳过)⑤各单项各班对比(低于年级均分即标红+右上角年级均分)
- 班级页模块顺序:基础卡片 → 分数段8段+与年级占比对比 → 等级结构对比(紧随占比对比)→ 本班vs年级各项目均分+缺测0分 → 差值画像图(本班均分−年级均分横向发散条,右蓝强项/左红弱项)→ 弱项榜(紧随画像,不及格人数降序+0分标注)→ 男女生对比(蓝/粉,缺性别整块跳过)→ 优秀生光荣榜(≥90绿字)→ 及格/优良临界生名单
- 个人成绩分析页(第3块,班级分页之后):不做固定分析内容,改为级联检索——年级→班级→性别→姓名 四级下拉(年级由班级名自动推导如"初一1班→初一",班级下拉随年级联动、姓名下拉随班级+性别联动);选定学生后动态渲染(先总后分):
1. 个人成绩卡(.cards 5张,与年级/班级页卡片风格一致):总分+等级徽章(优秀绿/良好蓝/及格橙/不及格红)、年级排名/总人数、班级排名/班人数、超过年级同学比例(百分位)、总分与年级均分差(负值红卡)。排名/百分位由 JS 从 SD 全量学生实时计算,不额外内嵌数据
2. 各项等级一览(.lvrow 色标条):总分+各单项,每项一个等级色标(项目·等级·分数)
3. 总分在年级分数段中的位置(svgBinLocate):年级8段分布直方图由 JS 从 SD 实时统计,本人所在段按 BIN_COLORS 高亮+「▼ 本人」标记,其余段灰色
4. 个人能力雷达图(svgRadar):7项本人/班级均分/年级均分三层叠加(填充透明度0.16),缺测项按0绘制并在表标"—"
5. 各单项得分对比表+分组柱状图:本人/班级均分/年级均分/与班级差/与年级差(差值绿正红负),柱状图本人深蓝/班级橙/年级灰
6. 各单项与年级均分差值画像(svgDiffBar):横向发散条,右绿强项/左红弱项,缺测项标"缺测" - 学生数据与均分全部内嵌为 JS 对象(const SD),纯前端动态渲染,满足单文件离线;免体/缺测学生选中后提示不参与对比。无学生被选中时仅显示引导提示(不占版面)
- 定制口径改脚本顶部常量:BINS / BIN_COLORS / CRIT_PASS / CRIT_GOOD / HONOR_LINE / 颜色
列自动识别规则
- 姓名列:表头含"姓名/name/学生/名字";班级列:含"班级/class/班";性别列:含"性别/sex/gender"
- 科目列:其余抽样为数值的列;体质表只取表头含"得分"的列+总分
- 若没有姓名列,则取第一列作姓名;科目必须存在,否则报错提示检查表头
自测(改完脚本必跑)
scripts/selftest.py 会自动生成一份"千疮百孔"的模拟数据(他校模板/列名不同/3班+未分班/整班缺性别/整项目无数据/3人缺考/散落缺分0分),运行 fitness_report.py 并断言 27 项降级与自适应行为:
"$PY" "$SKILL/scripts/selftest.py" # 输出 ALL TESTS PASSED 即通过
任何对 fitness_report.py 的改动,提交前必须先跑通 selftest。
分发打包说明(2026-10-08)
必带:SKILL.md、scripts/(fitness_report.py / analyze.py / check_env.py / selftest.py)。
剔除:__pycache__/ 等临时文件。
环境类全开放:输入路径、--out、--date 全走参数,脚本零写死盘符/用户名;输出位置默认源表格同文件夹(与个人习惯无关),首次使用确认一句即可(铁律3)。
锁死口径(教学测量定版,不因电脑而变):等级线 90/80/60、8 段分数段、临界区间 55-60/75-80、光荣榜≥90、免体识别词、雷达图仅个人页、图表样式冻结。确需改口径改脚本顶部常量并跑 selftest,不允许对话里临时变通。
自动安装(分发包内置 install.py,2026-10-08 v3.6.6)
接收方把压缩包交给自己的 WorkBuddy 说"安装这个技能"即可。WorkBuddy 只需执行一条命令:
python install.py [技能包.zip] # 不传路径则自动查找当前目录/脚本目录下的 *_技能包.zip
install.py 自动完成:校验 zip → 解压到 ~/.workbuddy/skills/<技能名>/(旧版自动备份)→ 缺失依赖镜像安装 → check_env 复验,全过打印 INSTALL ALL PASSED。详见包内脚本头部说明。
版本记录
- 2026-09-29 v1 单页版(analyze.py);v2 多分页版(先探模板+问配置、年级+班级分页+临界生)
- 2026-09-29 v3:8段分数段、均分标签防遮挡、年级三率对比、班级页差值画像/男女对比/弱项榜/等级结构/光荣榜
- 2026-09-29 v3.1:班级页模块顺序调整(等级结构随占比对比、弱项榜随差值画像);五条铁律固化——先识别数据、不清楚就问+班级数自适应、跨机通用零配置、缺数据自动降级不留空白、单文件离线HTML
- 2026-09-29 v3.2:模拟问题数据自测 14/14 通过。修复三处真实隐患:①表头探测由"姓名"精确匹配放宽为包含匹配(兼容"学生姓名"等列名);②基础卡片"总人数"改为名册人数,总分缺考人数单列红卡(缺考学生不再凭空消失);③某项目整列无数据时 stat 返回 None 导致崩溃——grade_avg/cls_avg 全部改为安全取值,年级/班级页分数段与等级结构模块补缺值守卫。新增 selftest.py 自测脚本与降级演练机制
- 2026-09-30 v3.3:免体学生支持(应闫博需求,数据源在总分格标注"免体"文字)。新增 EXEMPT_KEYWORDS 自动识别(免体/免测/免考);免体红卡+年级/班级页免体名单表(班级/姓名/性别);缺测/0分统计剔除免体(口径说明自动附注);免体不进任何分数统计。selftest 同步扩至 17 项断言(含免体场景)全部通过
- 2026-09-30 v3.3.1:免体卡撤出卡片行(闫博反馈:有/无免体班级卡片排列不一致)——卡片序列固定为8张,免体人数并入名单表标题(橙色加粗"共N人");selftest 扩至18项断言全部通过,并新增"各页卡片布局一致"核验
- 2026-09-30 v3.4:新增第三块「个人成绩分析」页(应闫博需求,班级分页之后):年级→班级→性别→姓名四级级联下拉(grade_of 由班级名自动推导年级),选定学生后动态渲染其总分+各项得分与班级均分/年级均分对比(表格+JS分组柱状图),学生数据内嵌 const SD 纯前端渲染保持单文件离线;免体/缺测学生提示不参与对比。selftest 修复一条脆弱正则(空临界生名单无</table>导致跨页贪婪误吞),扩至19项断言全部通过
- 2026-09-30 v3.5:个人成绩分析页视觉升级(应闫博反馈"太单调"):新增①个人成绩卡5张(总分+等级徽章/年级排名/班级排名/超过年级同学比例/与年级均分差,JS实时算排名与百分位)②各项等级一览色标条③个人能力雷达图(本人/班级/年级三层)④总分在年级分数段中的位置(本人段高亮+▼标记)⑤各单项与年级均分差值画像(左红弱项/右绿强项)。全部 SVG 由 JS 动态生成,仍为零外链单文件离线。selftest 扩至22项断言全部通过,另用 Node 对页面 JS 做 --check 语法校验 + DOM 桩模拟全量学生渲染(242人×4图)通过
- 2026-09-30 v3.6:四条固化规则(应闫博要求,为技能分享做准备):①项目动态自适应——图表只按表内实际"得分"列生成,没有的项目不做表(个人页单项<3时雷达图跳过);②安装后自动自检——新增 scripts/check_env.py(Python版本/openpyxl/临时目录/端到端演练,缺失给一键修复命令);③输出位置默认规则——不问直接存源Excel同文件夹(后缀 _分析图表.html),用户指定才按指定;④浏览器兼容——补 viewport、flex gap 全改 margin(兼容微信X5老内核)、grid 改 grid-gap、新增窄屏媒体查询,手机微信可正常打开。selftest 扩至25项全过;个人页模块顺序断言改为检查 box.innerHTML 拼接语句内顺序(修自身误报)
- 2026-09-30 v3.6.1:图表样式冻结定版(闫博明确):全部图表/模块清单固定为现状,禁止自行增删改样式、禁止新增图表类型;自适应仅限识别表结构+识别项目集两个维度;雷达图为个人成绩分析页专属,年级页/班级页禁用(数据多太乱,仅个人页与班级/年级均分对比适用)。新增 selftest 断言"年级/班级页无雷达图"锁死,共26项全过
- 2026-09-30 v3.6.2:数据异常必须提问(闫博定版,铁律2扩充):数据紊乱/与预期口径不符(重复学生、分数越界、表头多套、列名混乱等)时禁止默默硬处理,必须列出现象+给出2-3种处理方案用 AskUserQuestion 让使用者选择后再执行
- 2026-10-08 v3.6.3:年级页两项打磨 + 日期可指定(闫博反馈):①年级页单项各班对比红柱逻辑修正——由"得分<60才红"改为"班级均分低于年级均分即标红"(原bug:≥60但低于年级均分的班柱子仍是蓝色,弱项不显眼),年级均分虚线仍固定右上角防遮挡;②年级总览页新增「男女生得分对比分析」模块(闫博要求)——男生/女生总分均分双柱图(附年级均分虚线)+ 各项目男女生均分对比分组柱图(蓝=男/粉=女),缺性别列或单性别时整块跳过、编号顺延;③新增
--date YYYY-M参数——可单独覆盖标题日期前缀(解决"9月本底测试、10月才出报告"错位),不破坏年级自动推导,不传则默认取生成时年月。selftest 扩至 27 项断言全部通过 - 2026-10-08 v3.6.4:定名+提速版(大哥两指令,与技能二"生成成绩分析报告"配套打包分享):①frontmatter name 与标题改中文显示名"生成成绩分析图表"(原 grade-analysis-html),文件夹名不动、脚本路径引用不断;②check_env 的 openpyxl 修复命令加清华镜像
-i https://pypi.tuna.tsinghua.edu.cn/simple(下载提速、四项体检一项不少)。本技能只依赖 openpyxl、不依赖浏览器,安装天然就快;浏览器下载提速在技能二(生成成绩分析报告)的 check_env 里解决。 - 2026-10-08 v3.6.5:新电脑开放设置多问版(大哥指令:"装到别的电脑他们的使用习惯安装路径都与我的习惯不一样,一些开放性的设置多问"):铁律3 增补——凡"存哪里、装哪里"的开放性设置,默认之外一律先确认再动手;输出位置默认源表格同文件夹(与个人习惯无关),首次给某位使用者用时确认一句,其个人偏好记住后默认沿用;文档中的具体盘符路径仅为原作者本机示例。本技能脚本本就零写死路径(输入输出全走参数),无需改代码。
- 2026-10-08 v3.6.6:全自动安装器版(大哥指令:"让使用者把压缩包给 WorkBuddy 说安装,自动安装运行并验证检测,要快"):分发包内置
install.py(与技能二同一份,纯标准库 Win/Mac 通用)——一条命令完成校验→解压(旧版自动备份)→依赖镜像安装→check_env 复验,输出INSTALL ALL PASSED+各步耗时;端到端实测本机真实 zip 演练 2.8 秒全过,测试目录已清理。
校本配置(可选,升级不覆盖)
各校使用习惯(如学校名)统一存到技能文件夹之外的外部配置文件:~/.workbuddy/school_prefs.json(模板见技能包内 school_prefs.example.json,复制过去改即可)。升级技能只覆盖技能文件夹,这份配置原样保留;本技能与「YB学校体育成绩分析报告2」共用同一份。当前字段:
school_name:未指定--title时,前缀进 HTML 标题(<title>与<h1>),如"火星中学 · 2026年9月 初一体质健康测试 · 成绩分析图表"。
配置缺失或损坏时技能照常运行(不报错),只是不加校本前缀。
个人偏好记忆(可选,升级不覆盖)
教师个人习惯(产物目录 / 备份目录 / 截图中间产物目录 / 浏览器二进制目录)统一存到技能文件夹之外的个人偏好记忆文件:~/.workbuddy/pe_score_prefs.json(模板见技能包内 pe_score_prefs.example.json,由 AI 首次问清后自动写入)。与上面的校本配置分工不同、互不干扰:校本配置管"这个学校的事"(校名、默认模板、配色、校本措辞),个人偏好管"这台电脑这位老师怎么用"(东西放哪、备到哪)。升级技能只覆盖技能文件夹,两份配置都原样保留。读取优先级:命令行显式传参 > 个人偏好记忆 > 技能默认(源表格同文件夹);之后每次生成先读记忆文件,有记录直接沿用、不再反复问。配置缺失或损坏时技能照常运行,按默认规则执行。
CHANGELOG
v1.9.5(2026-10-26)
- 输出位置与推送双硬规矩(核查定版):SKILL.md「使用流程」新增两条不可妥协规矩——① 生成的 HTML 默认存上传文件同文件夹(不指定
--out绝不存别处);② 生成完必须用present_files在对话里展示,禁止只生成不通知。此前实测曾因个人偏好文件~/.workbuddy/pe_score_prefs.json的out_dir被设成本机工作区、把默认输出劫持到非上传目录,现已将该偏好out_dir清空,回落到源文件夹默认;分发包随本次重建。 - 版本 1.9.4→1.9.5,分发包随本次重建。
v1.9.4(2026-10-16)
- 交付前必核对产物 mtime(2026-10-16 与报告技能口径对齐,永久生效):SKILL.md 交付段新增第6步——
present_files前用os.path.getmtime确认 HTML 修改时间 = 本次生成时间,防止同目录上一轮残留的旧命名 HTML 被当新产物交错(报告技能同日已把该闸升级为代码硬闸;图表产物为单文件 HTML,暂以交付纪律约束)。 - 本机 selftest 33 项断言全过(免体/临界生/男女生对比/离线单文件/雷达图等);版本 1.9.3→1.9.4,分发包随本次重建。
v1.9.3(2026-10-15)
- slug 加 handle 后缀避撞名(大哥发布页面实测"Slug 不可用"):
yb-pe-fitness-score-charts在 SkillHub 已被其他用户占用(官方文档 Q4 实锤:slug 必须全网唯一,建议带 handle 前缀/后缀)→ 改为yb-pe-fitness-score-charts-yanbo(yanbo=闫博 handle);报告技能同步改为yb-pe-fitness-score-report-yanbo。显示名/步骤序号不变。 - 版本 1.9.2→1.9.3,分发包随本次重建。
v1.9.2(2026-10-15)
- 名称加系列序号 1(大哥定版):显示名「YB学校体育成绩分析图表」→「YB学校体育成绩分析图表1」——与「YB学校体育成绩分析报告2」配套成有序系列(图表 1 在前出 HTML、报告 2 在后出 Word/PPT),市场里按序号相邻排序、一眼看清使用先后;slug 不变(
yb-pe-fitness-score-charts),全文互引同步(引用报告技能处改为「YB学校体育成绩分析报告2」)。 - 版本 1.9.1→1.9.2,分发包随本次重建(zip 名 YB学校体育成绩分析图表1_技能包.zip)。
v1.9.1(2026-10-15)
- 新增个人偏好记忆机制(大哥定版"使用习惯融合"):新增技能文件夹之外的个人偏好记忆文件
~/.workbuddy/pe_score_prefs.json(out_dir/backup_dir/shots_dir/browser_dir,模板随包pe_score_prefs.example.json),AI 首次问清使用习惯后写入,之后读取沿用不再问;与school_prefs.json(学校级)同构分工、分开存互不干扰,升级/市场更新都不丢。代码:fitness_report.py新增load_pe_prefs(),--out缺省时按"命令行 > 个人偏好记忆 > 源表格同文件夹"优先级取输出目录。 - 大哥定名 YB 前置:显示名「学校体育成绩分析图表YB」→「YB学校体育成绩分析图表」(YB=闫博署名放系列前缀,大哥以后发布的技能统一 YB 开头,市场搜"YB"即成系列);slug 同步改为
yb-pe-fitness-score-charts;全文互引同步。 - 版本 1.9.0→1.9.1,分发包随本次重建。
v1.9.0(2026-10-15)
- 技能商店上架适配版 + 大哥定名「学校体育成绩分析图表YB」:为发布到 WorkBuddy 技能市场(SkillHub / 开放平台),SKILL.md frontmatter 新增两套平台字段——SkillHub 要求
slug(全网唯一 kebab-case:pe-fitness-score-charts-yb)、displayName、summary、license、author;开放平台要求display_name、description_zh、description_en、category、categories、tags;version改为合法 SemVer 三段式 1.9.0(SkillHub 对非 SemVer 版本号直接阻断发布)。显示名由大哥钦定为「学校体育成绩分析图表YB」(原名“生成成绩分析图表”,YB=闫博署名),全文互引同步替换;本地字段(name/description/agent_created/deps)与脚本零改动,本地安装使用不受影响。 - 版本 1.9→1.9.0,分发包随本次重建。
v1.9(2026-10-15)
- 安装器提速 v1.3:修复浏览器镜像探活 URL 错误(与报告技能 v1.17 同步,大哥老款 ThinkPad"17分钟没装完"驱动):新版 playwright 的 headless-shell 下载路径已改为 CFT 结构(
builds/cft/<browserVersion>/<plat>/...),旧安装器探活探的是镜像根路径(恒 404)→ 误判"国内镜像不可达"→ 浏览器二进制改走官方源(本机实测 506KB/s vs npmmirror 镜像 4842KB/s,相差近 10 倍)。修复:新增shell_probe_url()——从已装 playwright 的 browsers.json 动态推导当前版本完整工件 URL 再 HEAD 探活(零硬编码版本号,playwright 升级自动跟随),通过才设PLAYWRIGHT_DOWNLOAD_HOST;同步修复browsers_ok()不校验版本号的缺陷(缓存里有旧版 1228 而 playwright 要 1243 时被糊弄,装完 check_env 才发现缺)并消除"推荐 only-shell 安装却要求完整 chromium"的逻辑矛盾;文案校正浏览器二进制实际约 120MB。本技能自身只依赖 openpyxl、不下载浏览器,安装天然快;但分发包内 install.py 与报告技能同一份,随本次统一重建。单测 12/12 ALL_PASS。 - 版本 1.8→1.9,分发包随本次重建。
v1.8(2026-10-15)
- 专家视角绑定升级为"动态引用优先"(与报告技能 v1.16 同步,大哥追问"专家升级后不用再改技能吧?"):v1.7 是内嵌快照,专家升级后技能里的副本会过期。v1.8 改为:执行时先用 Glob 探测本机是否安装该专家(
~/.workbuddy/plugins/下搜**/senior-developer/agents/*.md、**/senior-developer*.md)——探测到就读取专家定义全文并以其为准(专家升级 → 技能下次执行自动用上新版,不用改技能、不用重打包);探测不到(对方电脑没装该专家)才用内嵌精简版兜底。 - 版本 1.7→1.8,分发包随本次重建。
v1.7(2026-10-15)
- 新增「专家视角自动绑定:高级开发工程师(Senior Developer)」章节(大哥要求"安装使用后自动选择该专家视角",与报告技能 v1.15 同步):经查 WorkBuddy 官方文档,技能 SKILL.md frontmatter 无 expert/persona 字段、"专家"是会话级 UI 选择,技能无法代替使用者点选——故把该专家的工作法则写进技能正文(每次调用必加载),实现等价效果且不依赖对方电脑装没装这个专家。章节含:四条核心原则(交付为王/小步快跑/言出必行/简洁高效)、三段式工作流程(任务分解≤10行 → 写验报增量循环 → 交付清单)、代码自检清单、错误恢复策略(根因→一次修复→复验→三停原则);description 同步注明。若使用者已显式选择其他专家,尊重其选择,本绑定仅限"怎么干活"的方法论层面。
- 版本 1.6→1.7,分发包随本次重建。
v1.6(2026-10-15)
- 修男女对比图题人数含免体(与报告技能联动的文不对图,大哥截图驱动):年级页/班级页"男女生对比"图题的人数口径原来把免体学生也算进去(年级 男78/女88、1班 女23、3班 女21、4班 男20),违背"免体不计入统计"铁律,且与报告文字(_class_detail 不含免体口径:年级 77/85、1班 19/22、3班 20/19、4班 19/22)对不上——图上一个数、文中另一个数。修复:年级页与班级页的
males/females筛选均加and not r.get("免体")。免体学生成绩本就全空(stat 天然跳过),柱状图数值不变,仅图题人数口径修正。当前在用的四年级 HTML 因源 xlsx 暂不可定位,采用等效手术修正(4 处图题字符串按 SD 实算人数替换,SD 数据零改动);今后重跑本技能即自动正确。 - 与报告技能 v1.13 配套:v1.13 修报告文字侧的文不对图(班级男女图错配本班vs年级文字、年级总分图误用分项目数字等),两侧合起来完成"图文互对"闭环。
v1.5(2026-10-15)
- 数据唯一依据锁定(大哥钦定,与报告技能对齐):铁律1 新增 🔒 数据锁定声明——HTML 每个数字唯一来源=使用者上传的原始表格实际数据,禁止编造/估算/示例值填充;数据不全按铁律4 降级留痕也不虚构;无论技能如何进化、换任何模型、经任何人之手都不准改。纯文档锁定,代码逻辑不变(本就只读上传表格)。
v1.4(2026-10-14)
- 修“无总分列/总分全空”崩溃(极限测试实锤):他校模板只列单项得分、无“总分”列(或整列留空)时,
stat()返回 None,年级页班级三率对比avg_line=ts["avg"]与 main 收尾ts['avg']直接 TypeError 崩溃(HTML 虽已写出但脚本非零退出、check_env/selftest 判失败)。两处修:①“班级质量对比(三率)”模块加and ts守卫,无有效总分整块跳过并登记降级(DEGRADE_REGISTRY 触发条件同步补“全年级无有效总分”);②main 收尾汇总按if ts:分流,无有效总分时打印降级提示而非崩溃。单项分析不受影响,铁律4 全面兜底。 - install.py 截图浏览器补齐加固(跨电脑健壮):原
step4_browser仅当 playwright 本次新装("playwright" in need)才装浏览器二进制;若电脑早已装好 playwright 但缺浏览器二进制,会被误判“已就绪”。改为按 SKILL.mddeps是否含 playwright 决定needs_browser,与“本次是否新装”解耦——只要技能需要截图且缺二进制就补齐。报告/图表两包同步。 - 验证:selftest 27 项全过(零回归);新增“无总分列+2班”极限数据集 rc=0、5 处模块按铁律4 降级不留空白、降级登记正确;两技能 check_env 均 ALL CHECKS PASSED。
v1.3(2026-10-13)
- 修整班缺考崩溃(极限测试实锤):某班全班得分+总分全空时
cls_stats[c]为 None,年级页班级三率对比cls_stats[c]["good_rate"]直接下标 TypeError。修法:三率改(cls_stats[c] or {}).get(..., 0)守卫(与同段 avgs 的既有守卫模式对齐)。 - 修“分数”列名不识别(他校模板实锤):列识别规则只认表头含“得分”的列,他校模板用“跳绳分数/仰卧起坐分数”等写法时项目识别为 0,年级页“各单项横向分析”留空 grid2 壳(违铁律4)。两处修:①detect 的 items 收集与表头探测同步纳入“分数”字样(disp 清洗也剥“分数”);②“各单项成绩横向分析”模块加整体守卫——无任何项目有有效数据时连标题整块跳过并登记降级,不再留空容器。
- analyze.py 补表头探测容错(文化课链路实锤):read_rows 硬取第一行当表头,学校导出表带标题行时科目列全识别失败直接退出。新增
_find_header_idx(前 12 行内扫描含“姓名/学生/名字”的行),xlsx 与 csv 两条读取通道都接入,与 fitness_report 的探测逻辑对齐。 - 验证:selftest 27 项全过(修复前后各一轮,零回归);6 个极限数据集(全0/全100/50%缺失/单学生/整班缺考/单班全男)+ 8 个特殊场景(无班级列/无性别列/得分混文本/分数越界/特殊字符姓名/班级命名变体/同名不同班/他校列名)全部 rc=0;1250 行高峰数据 HTML 1.0s 出、27 页 193 图零空容器;文化课 240/1250/单班三场景全 PASS。
v1.2(2026-10-13)
- V5 降级登记表:新增
DEGRADE_REGISTRY(单一处枚举全部可降级模块/触发条件/行为)+ 运行期降级日志note_degrade;各"缺数据整块跳过"站点接入登记,main 收尾打印"降级登记"汇总,交付前再做空图表容器门禁(铁律4 可审计、不留空白)。只记录、不改 HTML,冻结样式零影响。 - V6 analyze.py 审计加固:图表构建改用
avail(仅有统计的科目)守护,规避"检测到科目却无统计"的 KeyError 崩溃,并对齐铁律4(缺数据整块跳过、不留空白)。审计结论:svg_grouped/svg_vbar 原已容忍空值、detect 与 analyze 口径一致、无硬 bug,本次为防御性加固。
v1.1(2026-10-13)
- 配置外置 + 安全升级机制:新增外部校本配置文件
~/.workbuddy/school_prefs.json(含school_name),存于技能文件夹之外,升级技能只覆盖技能文件夹、校本习惯原样保留。 - 安装器
install.py增加版本比对:重跑时打印"首次安装 / 升级 vX→vY",并提示校本配置不受影响。 - 图表生成接入校本配置:
--title未指定时把school_name前缀进 HTML 标题(<title>与<h1>)。
v1.0
- 初版:体质健康测试多分页 HTML + 普通文化课单页 HTML,自动探测表结构,缺数据降级。