Compare commits

...

1 Commits

116 changed files with 6817 additions and 248 deletions

View File

@@ -80,7 +80,7 @@ tools: Read, Grep, Glob, Bash, Agent, Write
**根目录**:`E:/cc/4work_project/ClassFeedback/output/课评汇总/`
**文件名规则**:`202X年第X周课评汇总.md`
**文件名规则**:`202X年教学第X周课评汇总.md`
**排序规则**:最新生成的课评放在文件最前面

View File

@@ -0,0 +1,52 @@
# AIAGENT03橙子周五1500 第4课班级反馈
**授课日期**:2026-09-24(周四,中秋调课)
**课程**:《视频管线与Sprite拆帧动画》(萌宠快速版 · AIAGENT03 秋季第4课)
**上课地点**:13教室
---
## 本周教学内容
- **课程主题**:《视频管线与Sprite拆帧动画》(萌宠快速版第2课)
- **调课说明**:原周五 9/25 为中秋节停课一次,本节课平移至周四 15:00–16:30,下周恢复周五原时段
- **核心知识点**:
1. 理解动画原理:游戏动画是把一组静止帧按顺序快速播放,就像"手翻书"
2. 认识四步动画管线:视频生成→自动拆帧→SpriteSheet(雪碧图)合成→引擎播放
3. 用提示词驱动AI批量生产:动作是2秒的视频,先让AI把每个动作的中英文提示词写成文档
4. 掌握绿幕规范与素材质检:统一绿幕背景方便抠图,生成后逐一检查素材是否完好
5. 认识序列帧标注:可以标注某几帧是特定状态(如第16~25帧是被攻击状态),为下节课交互做准备
- **学生掌握情况**:本周到课学生:李梓宁(分时段一对一)
## 学生表现概述
**整体表现**:一对一课堂节奏完整,"找回项目→AI写提示词文档→逐个生成动作→去绿幕质检"全流程独立走通,彩虹猫的动作素材库初具规模
**学习态度**:延续给彩虹猫"办大事"的劲头,打字速度快,实操推进顺畅
**课堂氛围**:轻松专注,中秋调课按时到课,状态在线
## 各学生详细表现
### 李梓宁
**表现亮点:**
- 准时到课,先自己找回上节课的项目,让AI重新熟悉自己的萌宠,项目管理意识好
- 独立走完整条素材生产管线:让AI把待机、小跑、吃饭等动作的提示词写成文档,再照着文档在游戏工坊里逐个生成视频、去绿幕
- 打字速度快,批量生产动作素材效率高
- 素材质检有审美判断力:能看出哪张抠图不干净、哪个动作看起来不对劲,主动要求重做,对自己的作品有要求,正是"创作者"的样子
**待改进:**
- 生成视频等待的时候稍微欠缺耐心,可以趁等待时间先想好下一个动作怎么写,效率更高
**下阶段重点:** 下节课萌宠将真正"动起来"并进入"情绪状态机与喂食系统",先确认动作素材齐全;上次布置的萌宠"角色户口卡"(名字/性格/口头禅/最爱吃的食物)下节课带来
## 请假情况
无人请假(本班次为李梓宁一对一 15:00-16:30,中秋调课正常出勤)
## 下周建议
1. 课后请家长让孩子展示彩虹猫的动作素材,问问"为什么提示词里写绿色,AI就生成绿色背景"
2. 督促完成"角色户口卡"小任务(名字、性格、口头禅、最爱吃的食物),下节课要用
3. 中秋假期余额尚在,注意休息,下周五恢复原时段上课
---
**老师签名**:橙子

View File

@@ -1,127 +0,0 @@
# 学生画像 — 王子墨
> 创建日期:2026-03-27
> 最后更新:2026-09-05
> 班级:周六晚上1900AIAGENT03班
> 备注:2026秋季新学期确认在本班(原归档为转出学生,已随名单回到本班)
---
## 📋 基本信息
| 项目 | 内容 |
|------|------|
| 姓名 | 王子墨 |
| 年级 | 四年级 |
| 年龄 | 约10岁 |
| 性别 | 男 |
| 就读课程 | □ Kitten ✓ AIGC □ C++ |
| 入学时间 | |
---
## 🎯 用户画像类型
**主要类型**:积极提问型(自定义:机灵活跃型)
**具体表现**:
- 头脑灵活,新知识接受快(4分),逻辑思维能力好
- 课堂积极提问,思维活跃,愿意主动与老师互动
- 现在愿意打字,打字积极性和速度都有明显提升(3分)
- 话比较多,课堂上比较活跃,有时需要引导把握节奏
- 作品完成情况良好(3分),有能力但需要持续专注
**推荐评语风格**:**鼓励+引导型**(肯定积极提问,引导话多的能量)
- 大力肯定课堂积极提问和愿意打字的进步
- 引导将活跃的思维和话多的能量用于深入思考和作品创作
- 用具体目标引导专注力和表达效率
---
## 👤 性格特征
**性格关键词**:机灵、活跃、话多、积极提问、思维敏捷
**性格描述**:
- **性格倾向**:外向活跃型 — 精力旺盛,思维敏捷,课堂表现积极
- **社交表现**:非常活跃,喜欢提问和分享自己的想法,话比较多
- **情绪特点**:积极乐观,对打字不再抵触,愿意尝试和学习新事物
---
## 📚 学习状态
**学习阶段**:积极活跃,进步明显,正处于将能量转化为学习动力的阶段
**课堂表现**:
- **听课状态**:新知识接受快,思维活跃,积极参与课堂互动
- **提问情况**:积极提问,愿意主动分享想法,有时话比较多,需要引导节奏
- **完成任务情况**:作品完成情况良好,愿意打字表达想法,积极性很高
**作业/作品情况**:
- 完成质量:良好(有想法、有积极性,打字不再是障碍)
- 提交情况:能够积极完成,打字主动性明显提升
- 风格特点:想法活跃,表达欲强,需要引导把话说到点子上
---
## 💪 能力评估
| 能力维度 | 评分(1-5) | 说明 |
|----------|-----------|------|
| 逻辑思维 | ⭐⭐⭐⭐☆ (4) | 头脑灵活,逻辑思维好,理解能力强 |
| 学习接受 | ⭐⭐⭐⭐☆ (4) | 新知识接受速度快,学习能力强 |
| 作品完成 | ⭐⭐⭐☆☆ (3) | 作品完成情况良好,积极性明显提升 |
| 创意表达 | ⭐⭐⭐☆☆ (3) | 表达欲强,想法活跃,有提升空间 |
| 打字速度 | ⭐⭐⭐☆☆ (3) | 愿意打字,积极性和速度有明显进步 |
**优势能力**:逻辑思维、学习接受能力、积极提问、思维敏捷
**待提升能力**:表达效率、专注深度、话多节奏把控
---
## 🎨 应对策略
**沟通方式**:
- 肯定积极提问的态度 — "你愿意主动提问,这种学习态度很棒"
- 引导话多的能量用于深度思考 — "这个问题提得好,我们来深入聊聊"
- 赞赏打字进步 — "看到你愿意自己打字表达想法,进步很大!"
- 给予即时反馈,让其看到积极参与的效果
**评语风格选择**:
- **主要风格**:**鼓励+引导型**(肯定进步、引导方向)
- 善用"你提的这个问题很好..." — 肯定积极思考
- 如果能把想法说得更简洁,会更有效 — 引导表达效率
- "积极提问+专注思考=更优秀" — 引导方向
- **辅助风格**:激励型 — 用挑战激发深入思考
**激励机制**:
- 提问质量挑战:鼓励有深度的提问
- 表达效率引导:培养简洁表达习惯
- 打字进步认可:持续肯定打字积极性
- 即时反馈:好问题、好想法即时给予肯定
**注意事项**:
- 积极提问和思维活跃是最大优势,要大力肯定
- 话多是表达欲强的表现,不要压制,要引导节奏和效率
- 愿意打字是很大的进步,要持续鼓励和认可
- 引导"先思考再表达",培养深度思考习惯
---
## 📈 成长记录
### 2026-09-05 第01课观察
- 秋季第1课《3D跳一跳大作战》,需求文档设定大胆(平台间距3~8米、蓄力不限时),很有想象力
- 愿意主动把计划交给"严苛架构师"审核,正视"无限蓄力会失控""出界和连击规则需理顺"的反馈
- 建议耐心吸收审核意见,把蓄力上限、落点判定定得更准,让游戏又好玩又稳
### 2026-07-04 第18课观察
- 唯一被老师点名做现场演示的学生,主动上台介绍三个项目,讲解条理清晰
- 提到"遇到问题可以截图发给AI让它帮忙解决",展现对AI辅助调试的实用理解
- 项目最完整:5份需求/增量文档覆盖多维度,50点属性分配系统有创意
---
*持续更新,见证成长*

View File

@@ -0,0 +1,12 @@
# 请假记录
**授课日期**: 2026-09-20
**课程**: AIAGENT03-03《角色立绘与动作生产》(萌宠快速版)
**课次**: 第3课
梓皓家长好,本次课(第3课·《角色立绘与动作生产》)梓皓请假未到课。本节课我们走进游戏工坊,为萌宠生成待机、跑动、胜利等成套动作立绘,学习多动作素材的命名与管理规范,还认识了透明通道 PNG 在游戏中的妙用~梓皓缺席的内容会在后续合适的时候单独帮忙补齐,也欢迎家长跟老师沟通安排补课时间~期待梓皓下次课一起加入!🌸😊
---
**老师签名:橙子**

View File

@@ -0,0 +1,12 @@
# 请假记录
**授课日期**: 2026-09-27
**课程**: AIAGENT03-04《视频管线与 Sprite 拆帧动画》(萌宠快速版)
**课次**: 第4课
梓皓家长好,本次课(第4课·《视频管线与 Sprite 拆帧动画》)梓皓请假未到课。本节课我们学习了游戏动画的秘密——把跑步视频自动拆成一帧帧图片,再快速连播让萌宠真正"动起来",掌握了"视频生成→自动拆帧→SpriteSheet合成→游戏播放"的完整管线~梓皓缺席的内容会在后续合适的时候单独帮忙补齐,也欢迎家长跟老师沟通安排补课时间~期待梓皓下次课一起加入!🌸😊
---
**老师签名:橙子**

View File

@@ -1,8 +1,8 @@
# 学生画像 — 章梓皓
> 创建日期:2026-09(新学期)
> 最后更新:2026-09
> 班级:AIAGENT03橙子周日0845
> 最后更新:2026-09-27
> 班级:AIAGENT03橙子周日1045(一对一,11教室)
---
@@ -61,6 +61,7 @@
**注意事项**:
- 2026-09-06 第1课请假,第2课(2026-09-13)单独补上第1课内容
- ⚠️ 2026-09-20 第3课、09-27 第4课**连续请假**(萌宠单元的立绘+拆帧动画未学),已发请假记录;需尽快安排补课,第5课前主动联系家长了解情况
- 首次课即展现出很强专注力与独立打字能力,可放心加快节奏
- 下节课关注:能否主动提出自己的创意需求、独立操作熟练度
@@ -69,7 +70,7 @@
## 📝 成长记录
### 2026-09(画像创建)
- **新生入学**:2026秋季学期加入 AIAGENT03橙子周日0845 班,基础信息待上课后补充
- **新生入学**:2026秋季学期加入 AIAGENT03 班(初建时归在周日0845班目录,后确认本人为**周日1045一对一·十一教室**,09-27 已迁至 `AIAGENT03橙子周日1045/` 归档)
### 2026-09-13 第2课观察(补第1课《3D跳一跳大作战》)
- 第一次到课,全程专注不分神,需求与作品内容全部自己独立打字完成
@@ -77,6 +78,11 @@
- 通过"枪械伤害"类比理解数值设定,参与定下蓄力3秒上限、平台间距5-10米
- 完成首个作品《橙子跳一跳3D》:橙子角色、雪糕桶/圆桌/凳子/魔方多造型平台、蓄力压扁、空中前翻、靶心×2加分
### 2026-09-20 第3课 / 2026-09-27 第4课(连续请假)
- 第3课《角色立绘与动作生产》、第4课《视频管线与 Sprite 拆帧动画》均请假,已归档 `20260920_AIAGENT03-03(请假).md`、`20260927_AIAGENT03-04(请假).md`
- **缺课影响**:萌宠立绘规范与拆帧动画未学,第5课《情绪状态机与喂食系统》直接依赖前两课素材
- **补课方案(待安排)**:压缩为一次一对一,重点=生成萌宠成套动作立绘→视频拆帧→SpriteSheet 连播;补课后按补课规范归档
---
*持续更新,见证成长*

View File

@@ -0,0 +1,95 @@
# CSP00橙子周五1900 第4课班级反馈
**授课日期**:2026-09-24(周四,中秋调课)
**课程**:《破门而入:循环与攻击》(CSP00 秋季第4课)
**上课地点**:13教室
---
## 本周教学内容
- **课程主题**:《破门而入:循环与攻击》
- **调课说明**:原周五 9/25 为中秋节停课一次,本节课平移至周四 19:00,下周恢复周五原时段
- **核心知识点**:
1. 理解"前置指令":写在 while 循环前面的指令只执行一次(如先走到攻击位置)
2. 掌握"循环 + 攻击"套路:while(true) 循环里写 attack,英雄就能不停攻击目标
3. 巩固字符串参数规则:怪物名字要加双引号,如 attack("Door")
4. 理解循环体:花括号里可以放多条指令,每一轮按顺序反复执行
5. 培养审题与复核习惯:先圈题眼再作答、做对后主动复核
- **学生掌握情况**:到课 3 人全部 OJ 10/10 最终通过(连续第二周到课学生全员最终满分),循环+攻击套路全员听懂
## 学生表现概述
**整体表现**:优秀。到课 3 人课堂练习 10 题全部最终通过,当堂消化能力强
**学习态度**:订正积极,无一人需要老师盯着改;艺嘉还出现了"通过后主动复核"的严谨习惯
**课堂氛围**:中秋调课 3 人全部按时到课,状态在线
## 各学生详细表现
### 郭艺嘉
**表现亮点:**
- 课堂练习 10 道题全部一次通过(10次提交零失误),连续两周"零失误",本次课堂练习完成质量最高的作业之一
- 全站 38 份提交里有 20 人首错的"攻击大门"题(藏三个陷阱:不加引号、循环写法不完整、攻击写成移动),一眼锁定正确答案
- T9、T10 通过后主动各复核提交 1 次,严谨习惯初步成型
**待改进:**
- 下一步从"听得懂"走向"讲得出":下次课堂讲评兑现小讲师挑战,把思路讲给全班
**下阶段重点**:主动输出——提前选好题目,把"为什么选它、其他选项错在哪"讲给全班听
### 王晨语
**表现亮点:**
- 10 道题最终全部通过,共提交 14 次无一次放弃;3 道错题全部自己订正到位
- "循环里能放几条指令"一题连错 3 次仍稳住心态换思路,第 4 次自己找到正确答案,韧劲十足
**待改进:**
- 连错 3 次的题是靠"轮流试选项"试出来的,第一遍读题概念还没想透;"先想后选"(先合上选项用自己的话说答案)的方法待落地
- 上周布置的"提交前多看一遍"已在进步,继续保持
**下阶段重点**:追求"快而不错"——保持冲劲+放慢半拍,下次讲评用"先想后选"现场做一道题验证
### 彭煜腾
**表现亮点:**
- 10 道题全部通过,9 道一遍过;唯一失手的"攻击大门"第二次就自己改对,且是自己发现问题、主动从 D 换到 A,订正快准
- 连续两周全部题目最终通过,当堂消化能力越来越稳
**待改进:**
- 错题原因是下手前没先确认"题目要哪个动作"(把攻击选成移动),属审题习惯问题,不是概念不会;"先圈题眼"(圈出动作+对象两个词)口头提醒即可
**下阶段重点**:保持现状,把读题和检查变成肌肉记忆
### 陈圆振
**请假记录**:本周请假(中秋假期),第4课课堂练习待补;上次布置的第03课错题订正也需跟进
**下阶段重点**:下次课前优先补第4课练习 + 第03课错题订正,老师已安排单独提醒家长
## OJ 数据汇总(第4课 A包 · CSP00K04)
| 学生 | 出勤 | 完成 | 提交次数 | 一遍过 | 错题订正 |
|------|------|------|----------|--------|----------|
| 郭艺嘉 | ✅ | 10/10 | 14(含2次复核) | 10 | — |
| 王晨语 | ✅ | 10/10 | 14 | 6 | 全部自行订正通过 |
| 彭煜腾 | ✅ | 10/10 | 12 | 9 | T3 一次订正通过 |
| 陈圆振 | ⏸ 请假 | — | — | — | 待补 |
**共性观察**:全站错误率最高的 T3"攻击大门"(全站首次做错率 53%),班内仅煜腾、晨语首错且均一次订正通过;T4/T8"循环体能放几条指令"考点晨语各错一次,订正后概念闭环,第5课可少量变式题二次巩固。
## 共性问题与改进方向
1. **审题先确认"动作+对象"**(煜腾、晨语)→ "先圈题眼/先想后选",看清问什么再下手
2. **通过后复核习惯**(艺嘉已成型)→ 逐步推广到全班,把"做对再复核"变成小仪式
## 下周教学计划
- 恢复周五原时段上课;第4课"循环+攻击"套路将在新关卡实战中二次巩固
- 讲评时用 T3 做"找陷阱"示范(三个错误选项分别对应不加引号/循环写法不完整/动作张冠李戴)
- 艺嘉"小讲师"挑战兑现;晨语"先想后选"现场验证;圆振补第4课练习与第03课订正
## 家长沟通要点
- 中秋调课 3 人全部按时到课,到课学生课堂练习全部满分通过,状态很好
- 请督促孩子完成课后小任务:艺嘉在家彩排小讲师内容并仿出题;晨语给爸妈讲"循环的花括号能放几条指令";煜腾讲"为什么攻击指令放循环里、前置指令放前面"
- 圆振家长:请假内容(第4课课堂练习)请安排时间补做,老师下次课优先跟进
---
**老师签名**:橙子

View File

@@ -1,6 +1,7 @@
# 学生画像 — 张立坤
> 创建:2026-09-05 | 班级:CSP04橙子周六0830
> 状态:**已转出**(2026-09-27 确认非本班学生,档案归档)
> 说明:由 GESP集训/暑假项目转入本班,画像沿用归档档案,持续更新。
## 🎯 用户画像类型

View File

@@ -1,8 +1,10 @@
# 学生画像 — 王子墨
> 创建日期:2026-03-27
> 最后更新:2026-06-28
> 最后更新:2026-09-27
> 班级:周六晚上1900AIAGENT03班
> 状态:**已转出**(2026-09-23 确认转至其他老师班级,档案归档)
> 备注:2026-06 曾转出归档一次,2026 秋季回归本班,2026-09-23 再次转出
---
@@ -91,58 +93,30 @@
**评语风格选择**:
- **主要风格**:**鼓励+引导型**(肯定进步、引导方向)
- 善用"你提的这个问题很好..." — 肯定积极思考
- 用"如果能把想法说得更简洁..." — 引导表达效率
- 设定明确目标 — "这节课我们挑战'先想清楚再说"
- 指出"积极提问+专注思考=更优秀" — 让其看到提升方向
- 如果能把想法说得更简洁,会更有效 — 引导表达效率
- "积极提问+专注思考=更优秀" — 引导方向
- **辅助风格**:激励型 — 用挑战激发深入思考
**激励机制**:
- **提问质量挑战**:设定"好问题"挑战,鼓励有深度的提问
- **表达效率引导**:引导把话说到点子上,培养简洁表达习惯
- **打字进步认可**:持续肯定打字积极性和进步
- **即时反馈**:好问题、好想法即时给予肯定
- 提问质量挑战:鼓励有深度的提问
- 表达效率引导:培养简洁表达习惯
- 打字进步认可:持续肯定打字积极性
- 即时反馈:好问题、好想法即时给予肯定
**注意事项**:
- 积极提问和思维活跃是最大优势,要大力肯定
- 话多是表达欲强的表现,不要压制,要引导节奏和效率
- 愿意打字是很大的进步,要持续鼓励和认可
- 引导"先思考再表达",培养深度思考习惯
- 四年级是培养表达能力和思维深度的关键期
---
## 📝 典型评语示例
**开场白示例**:
- "子墨,你今天提的问题都很有想法,思维特别活跃!"
- "看到你愿意自己打字表达想法,进步真的很大!"
- "你这么积极提问,说明你在认真思考,继续保持!"
**优点肯定示例**:
- "你提的这个问题很有深度,说明你真的在动脑思考!"
- "愿意自己打字,而且打得越来越熟练,进步非常明显!"
- "课堂上积极分享想法,带动了整个班级的氛围,很棒!"
**建议指导示例**:
- "如果能先想清楚再说,把想法说得更简洁一点,会更有力量哦。"
- "我们来挑战一下:先把问题在脑子里组织好,再举手提问。"
- "你已经愿意打字了,接下来可以挑战打字再快一点点!"
- "把活跃的思维用在深入研究作品上,一定会做出让人惊艳的成果。"
**结束语示例**:
- "你的积极提问和思维活跃是最大的优势,继续保持,你会越来越优秀!"
- "看到你愿意打字的进步,老师真的很开心,继续加油!"
- "记住,积极思考+有效表达=超级厉害的你,老师看好你!🌟"
---
## 📈 成长记录
### 2026-07-04 第18课观察
- 唯一被老师点名做现场演示的学生,主动上台介绍三个项目,讲解条理清晰
- 提到"遇到问题可以截图发给AI让它帮忙解决",展现对AI辅助调试的实用理解
- 项目最完整:5份需求/增量文档覆盖多维度,50点属性分配系统有创意
- 83.5MB演示视频内容非常丰富,展现了认真细致的态度
### 2026-09-05 第01课观察
- 秋季第1课《3D跳一跳大作战》,需求文档设定大胆(平台间距3~8米、蓄力不限时),很有想象力
- 愿意主动把计划交给"严苛架构师"审核,正视"无限蓄力会失控""出界和连击规则需理顺"的反馈
- 建议耐心吸收审核意见,把蓄力上限、落点判定定得更准,让游戏又好玩又稳
### 2026-07-04 第18课观察
- 唯一被老师点名做现场演示的学生,主动上台介绍三个项目,讲解条理清晰

View File

@@ -3,6 +3,7 @@
> 创建日期:2026-03-27
> 最后更新:2026-06-28
> 班级:周日早上0845AIAGENT03班
> 状态:**已停课**(2026-09-23 确认,档案归档)
---

View File

@@ -27,10 +27,10 @@ type: skill
HTML 以 `samples/report-sample.html` 为样式基准,`pdf` 用 `scripts/mkpdf.mjs` 生成(单页 660px)。
4. **审核红线**(必须写进每次交付说明):报告是草稿、须教师审核;只写学习习惯不写人身评价;
代码/报错/错题选项只发对应家长、不进班级群;不做学生横向对比排名。
5. **存档结构改用新技能体系**(见下方「CSP 班(v2 存档结构)」):
`Class-2026-X/<班组>/<学生>/` + `Students/<学生>/profile.md`。
5. **存档结构(2026-09-26 统一)**:所有课程体系统一存档到
`.claude/memory/class/<班组>/<学生>/`,画像在 `.claude/memory/class/<班组>/<学生>/profile.md`。
> AIAGENT03 班、体验课 **不**适用本规则,仍按本技能原有流程与存档(`.claude/memory/class/...` + `output/课评汇总/`)执行。
> AIAGENT03 班、体验课**不**使用 OJ 报告三件套流程,但存档路径与下方通用规则相同。
>
> **快速触发**:对 AI 说「整理 XX 班的课堂反馈」或「引导我进行操作」即可调用该技能;其脚本自动读取仓库根 `.env`(已配置 OJ 凭据)。
@@ -764,20 +764,18 @@ python scripts/get_student_oj.py \
- 未上课:`YYYYMMDD_课程编号-课次(未到).md`
- 补课:正常文件名 `YYYYMMDD_课程编号-课次.md`,放在补课班级下的 `补课/` 目录中
### ⚠️ CSP 班(v2 存档结构 · 覆盖上方通用规则)
### ✅ 存档路径统一规则(2026-09-26 起,全部课程适用)
CSP00 / CSP04 课评**不**使用 `.claude/memory/class/...` 与 `output/课评汇总/` 路径,统一改用
`.claude/skills/class-feedback-report` 的归档体系(详见该技能 SKILL.md):
所有课评、家长版报告、班级汇总**统一存 `.claude/memory/class/` 对应班级目录**,
不再使用 `Class-2026-X/` 或 `output/课评汇总/`:
- **家长版三件套**(发给家长):`Class-2026-X/<班组>/<学生>/<姓名>-<班组>-<章节号>-反馈报告.{md,html,pdf}`
- 例:`Class-2026-C/克力周日0830CSP02/王凯平/王凯平-克力周日0830CSP02-03-反馈报告.md`
- `Class-2026-X`:A春 / B暑 / C秋 / D寒(2026秋季班用 `Class-2026-C`)
- **家长版三件套**(发给家长):`.claude/memory/class/<班级>/<学生>/<姓名>-<班级>-<课次>-反馈报告.{md,html,pdf}`
- 例:`.claude/memory/class/CSP04橙子周六1400/张雨禾/张雨禾-CSP04橙子周六1400-04-反馈报告.md`
- HTML 以 `samples/report-sample.html` 为样式基准;PDF 用 `scripts/mkpdf.mjs` 单页 660px 生成
- **内部课评正本**(校宝核查用):`Class-2026-X/<班组>/<学生>/feedback/YYYYMMDD_课程编号-课次.md`
- **学生画像**:`Students/<学生>/profile.md`(跨学期连续,按学生名扁平存放)
- **班级汇总**:`Class-2026-X/<班组>/summaries/<班组>-<章节号>-反馈汇总-<日期>.md`
> AIAGENT03 班、体验课仍按下方通用规则(`.claude/memory/class/...` + `output/课评汇总/`)保存。
- **内部课评正本**(校宝核查用):`.claude/memory/class/<班级>/<学生>/feedback/YYYYMMDD_课程编号-课次.md`
- **补课生**:`.claude/memory/class/<班级>/补课/<学生>/feedback/`(家长版报告同放该目录)
- **学生画像**:`.claude/memory/class/<班级>/<学生>/profile.md`(随班级存放,每次课评后更新成长记录)
- **班级汇总 / 上课通知 / 质检报告**:`.claude/memory/class/<班级>/summaries/YYYYMMDD_课程编号-课次_班级反馈.md`
### 1. 保存到学生个人单次课评文件(必须,用于自动化统计)
为每位学生生成单独的单次课评文件,这是课评完成率统计的依据:
@@ -799,7 +797,7 @@ CSP00 / CSP04 课评**不**使用 `.claude/memory/class/...` 与 `output/课评
### 2. 保存到统一周课评汇总(后写的放上面)
同时保存到统一的课评汇总目录,同一周的课评放在同一个文件里,新生成的放在最顶部:
**根目录**:`E:/cc/4work_project/ClassFeedback/output/课评汇总/`
**文件名规则**:`202X年第X周课评汇总.md`(比如「2026年第18周课评汇总.md」)
**文件名规则**:`202X年教学第X周课评汇总.md`(比如「2026年教学第18周课评汇总.md」)
**排序规则**:最新生成的课评放在文件的最前面,旧的课评在后面,倒序排列
**班级分组**:同一个班级的课评放在一起,按班级分组展示

View File

@@ -59,7 +59,7 @@
| 产物 | 路径 |
|------|------|
| 个人课评 | `.claude/memory/class/[班级]/[姓名]/feedback/YYYYMMDD_课程编号-课次.md` |
| 周汇总 | `output/课评汇总/202X年第X周课评汇总.md`(**新课评放最前**) |
| 周汇总 | `output/课评汇总/202X年教学第X周课评汇总.md`(**新课评放最前**) |
| 班级总结 | `.claude/memory/class/[班级]/summaries/YYYYMMDD_课程编号-课次_班级反馈.md` |
| 汇总网页 | `output/课评汇总/第X周课评汇总/第X课-课程名称-班级.html`(放入对应周文件夹,登记到该周 `总览.html`;已存在则跳过不覆盖;规范见 `output/课评汇总/README.md`) |
| 画像更新 | 只记录新发现/明显变化,格式 `**YYYY-MM-DD 第N课观察**:` |

View File

@@ -750,7 +750,7 @@ python scripts/get_student_oj.py \
### 2. 保存到统一周课评汇总(后写的放上面)
同时保存到统一的课评汇总目录,同一周的课评放在同一个文件里,新生成的放在最顶部:
**根目录**:`output/课评汇总/`(项目仓库内相对路径)
**文件名规则**:`202X年第X周课评汇总.md`(比如「2026年第18周课评汇总.md」)
**文件名规则**:`202X年教学第X周课评汇总.md`(比如「2026年教学第18周课评汇总.md」)
**排序规则**:最新生成的课评放在文件的最前面,旧的课评在后面,倒序排列
**班级分组**:同一个班级的课评放在一起,按班级分组展示

View File

@@ -1,7 +1,7 @@
{
"skills": [
"../.workbuddy/skills/课评生成",
"../.workbuddy/skills/课评质检",
"../.claude/skills/class-feedback-report"
"skills/课评生成",
"skills/课评质检",
"skills/class-feedback-report"
]
}
}

View File

@@ -0,0 +1,231 @@
---
name: class-feedback-report
description: 按班组整理 OJ 课堂反馈:自动定位课程与章节、拉取全班逐生逐次提交(代码+编译报错+状态),产出「第N次提交错在哪 → 整体分析 → 建议」的学生诊断报告草稿(MD+HTML+PDF),供带班教师审核后使用。老师说「引导我进行操作」「帮我处理本项目」「整理课堂反馈」「学生分析报告」时使用本技能;引导模式会带着老师一步步完成环境检查、账号配置与报告生成。
---
# Skill: 班级课堂反馈与提交诊断
按班级生成每位学生的提交诊断报告(第一次提交错在哪、第二次错在哪……整体分析、建议),
数据全部来自 HydroOJ 课程插件的只读 API,**评价与建议由 AI 起草、教师审核后才能发给学生/家长**。
关键词:`课堂反馈`、`提交诊断`、`错误分析`、`班级报告`、`学生分析`、`整理反馈`、`引导我进行操作`、`帮我处理本项目`
## 操作引导模式(老师第一次使用,或说「引导我进行操作」「帮我处理本项目」时从这里开始)
面向不熟悉命令行的老师:AI 按下面清单**逐步执行并代替老师敲命令**,每完成一步简短汇报再进行下一步。
老师只需要回答问题(用哪个站、账号密码、哪个班级)。
1. **仓库准备(第一次必做,老师只回答问题)**:问老师姓名/工号 → 仓库地址默认
`https://git.qonnwolf.com/<工号>/ClassFeedback`(**机构仓库名统一 ClassFeedback**,
git 服务 git.qonnwolf.com)。
- 已有本地克隆 → 进入仓库目录 `git pull`;
- 没有 → 引导老师在 git.qonnwolf.com 网页生成**访问令牌**(设置 → 应用 → 访问令牌,
勾选 repository 读写),令牌让老师填进仓库根 `.env` 的 `GIT_TOKEN`(见第 3 步),
然后 `git clone https://git.qonnwolf.com/<工号>/ClassFeedback`(公共克隆不需要令牌,
推送时才用),新老师还没有仓库 → 引导网页建仓(名字必须是 ClassFeedback)或
本地 `git init` + `remote add origin` + 首推;
- 结构自检:`.claude/memory/class/`、`skills/class-feedback-report/`、
`AGENTS.md`、`CLAUDE.md`、`.gitignore`、`.env` 缺失则按包内 `repo-template/` 补建
(`.env` 从 `.env.example` 复制,填好后永不入库)。
2. **环境自检**(自动执行,无需老师操作):`node -v` 需 ≥18;确认本 skill 的
`scripts/fetch-class-data.mjs`、`scripts/check-login.mjs`、`scripts/mkpdf.mjs` 存在;
Windows 确认 Edge 已安装(PDF 用)。有缺项先解决缺项再继续。
3. **配置凭据(.env,一次性;站点固定为 qonnwolf)**:脚本自动读取仓库根 `.env`,
请老师自行编辑填写以下字段(**推荐老师自己填,密码不经过对话**;老师愿意口述时
AI 可代填,填完提醒「.env 不入库」):
```ini
OJ_BASE_URL=https://oj.qonnwolf.com
OJ_USERNAME=你的OJ用户名
OJ_PASSWORD=你的OJ密码
GIT_USER=你的工号
GIT_TOKEN=你的访问令牌
GIT_REPO_URL=https://git.qonnwolf.com/你的工号/ClassFeedback
```
填好后运行 `node scripts/check-login.mjs`(脚本自动读 .env,无需命令行传凭据)验证;
输出 `OK|登录成功…` 才继续;失败按「异常处理」回应老师。
令牌的 git 配置一次性执行:
`git remote set-url origin https://<GIT_USER>:<GIT_TOKEN>@git.qonnwolf.com/<工号>/ClassFeedback`
(存在本地 .git/config,不入库),之后 `git push` 不再需要令牌。
4. **收集班级组名**:请老师提供完整班组名(如「克力周日0830CSP02」)。
老师不确定时:先跑 fetch(不带 --group 会报错,带 --group 才扫课程),或用
`GET /course/api/list` 列出课程标题让老师指认,再从课程页确认组名。
6. **确认章节与花名册(先取小组成员,再分析)**:跑 fetch 后,向老师展示并请其确认:
「班组-课次号」标识(如 克力周日0830CSP02-04)、章节名、**班组花名册(N 人 + 姓名列表)**,
以及班组花名册(N 人 + 姓名列表)。老师确认无误后才进入逐生分析写报告;成员有出入时先解决报名/分组问题。
⚠️ **报告编号用「课次号」(第几次课),不用 OJ 章节号**——章节号(章节标题前缀数字,如「03 二维数组」)
是教材进度,课次号是实际上课序数,两者常差 1~2,混用会与内部正本 `YYYYMMDD_课程编号-课次.md` 对不上。
7. **执行生成(每个学生五件事,缺一不可)**:
① 家长版报告 md/html → `.claude/memory/class/<班组>/<学生名>/<姓名>-<班组>-<课次号>-反馈报告.{md,html}`;
② PDF 同目录本地生成(git 忽略,不入库);
③ **内部课评正本** → 同目录 `feedback/YYYYMMDD_课程编号-课次.md`
(校宝核查口径:每位学生每次课有且仅有一个文件;请假加 `(请假)`、补课加 `(补课-去XX)`;
内容为简明事实:日期、班组、状态、本讲要点、订正情况);
④ **更新画像** → `.claude/memory/class/<班组>/<学生名>/profile.md`(追加本讲表现要点、刷新能力评估);
⑤ 班级汇总 → `.claude/memory/class/<班组>/summaries/YYYYMMDD_班组-课次号_班级反馈.md`。
8. **git 同步**:`git add .claude/memory/class .claude/skills docs`(*.pdf 被 .gitignore 自动排除)→
`git commit -m "课评: <班组>-<课次号> <日期>"` → `git push`;
推送失败(令牌过期/无权限)→ 引导老师重新生成令牌并更新凭据。
9. **交付**:汇报每个学生三件套的文件路径 + 内部正本 + 画像更新情况 + 班级汇总,
并**明确提醒:家长版报告是草稿,审核措辞后才能发学生/家长**。
异常处理(引导模式中随时可能触发):
- 登录失败 → 请老师核对账号密码;确认是教师账号或拥有该班成绩查看权限(普通学生账号不行)。
- 「没有找到包含班组的课程」→ 班组名不全或该班不在所选站;列出可见课程标题协助老师确认。
- analysis 响应慢 → 正常现象(全班粒度重接口),等待即可,不要并发重试。
## 前置条件(跳过引导、直接使用时自行满足)
- Node 18+(自带 fetch);出 PDF 需要 Edge 或 Chrome 浏览器;git(同步课评仓库)。
- **凭据统一放仓库根 `.env`**(从 `.env.example` 复制;已被 .gitignore 排除,绝不提交):
```ini
OJ_BASE_URL=https://oj.qonnwolf.com
OJ_USERNAME=你的OJ用户名
OJ_PASSWORD=你的OJ密码
GIT_USER=你的工号
GIT_TOKEN=你的访问令牌
GIT_REPO_URL=https://git.qonnwolf.com/你的工号/ClassFeedback
```
OJ 账号需要「教师或授权校区查看者」权限(普通学生账号只能看到自己的数据)。
脚本自动向上查找并加载 `.env`;环境变量 `COURSE_API_USERNAME/PASSWORD` 可临时覆盖。
- 凭据只在 `.env` 和 git 凭据里,**不得写进命令行参数、报告或日志**。
## 安装(项目级,随仓库走)
**方式 A(推荐)**:老师直接克隆自己的 ClassFeedback 仓库——新仓库模板已自带本技能
(`skills/class-feedback-report/`),克隆即用。
**方式 B(存量仓库补装)**:把 `class-feedback-report/` 文件夹复制到**项目仓库**的
`skills/` 目录下(与 `.claude/memory/class/` 同在 `.claude/` 内),并在仓库根的 `AGENTS.md` /
`CLAUDE.md` 写明「本项目技能在 skills/ 目录」。**不要装到用户级目录**(~/.zcode、~/.claude)——
技能必须随项目仓库走,老师换 agent、换电脑都只要拉仓库。
## API 使用速查
本 skill 全部基于课程插件的只读 JSON 接口(完整文档见 [docs/API.md](docs/API.md))。
鉴权方式:先 `POST /login`(JSON:`uname` + `password`)拿 `sid` Cookie,后续请求带
`Cookie: sid=...` 和 `Accept: application/json`;脚本自动从仓库根 `.env` 读取凭据。
| 接口 | 用途 | 权限 |
| --- | --- | --- |
| `GET /course/api/list?page=N` | 列出可见课程(定位班组所在课程) | 已登录 |
| `GET /course/api/detail/:cid` | 课程与章节结构 | 可访问该课程 |
| `GET /course/api/v1/courses/:cid/students?group=班组名` | 按班组拉花名册 | 教师或授权查看者 |
| `GET /course/api/v1/courses/:cid/sections/:csid/feedback/overview?group=` | 章节班级统计(完成率、首刷率) | 教师或授权查看者 |
| `GET /course/api/v1/courses/:cid/sections/:csid/feedback/students?group=&limit=100` | 逐生统计信号 | 教师或授权查看者 |
| `GET /course/api/v1/courses/:cid/sections/:csid/feedback/students/:uid` | 单生逐题证据(无代码) | 教师或授权查看者 |
| `GET /course/api/analysis/:cid/:csid?withCode=true&withHistory=true` | **全班提交历史+代码+编译报错**(重接口,每次运行只调一次) | 教师或授权查看者 |
| `GET /p/<pid>` | 客观题题干与选项(HTML,脚本已自动解析) | 可见该题 |
注意:`withHistory=true` 必须带上,否则 history 全空;响应为全章节全班粒度(数百 KB),按需使用。
## 使用流程
### 1. 抓取班级数据(脚本自动完成)
```bash
node "<skill目录>/scripts/fetch-class-data.mjs" \
--group="克力周日0830CSP02" \
--base-url="https://oj.qonnwolf.com" \
--out="F:\HydroOJ\artifacts\class-feedback\digest-<班级名>.json"
```
- 脚本自动:定位含该班组的课程(多门时优先「秋季」并在 stderr 提示)、选最后一个有提交活动的章节、
拉花名册、调 `analysis?withCode=true&withHistory=true` 一次性取全班提交历史;
**自动识别客观题**(提交内容是答案卷的题)并抓取题干与选项存入 `objective[pid].questions`
(每个问题含 `no/text/options[]`,katex 拆行已合并处理)。
- 可选参数:`--course=<cid>` 指定课程、`--section=<csid>` 指定章节、`--uid=<uid>` 只整理某个学生。
- 产出 digest JSON:每生 `{stats 信号, problems:[{pid,title,submissions:[{seq,status,score,errorHead,code}]}]}`。
### 2. 阅读原料,逐生写诊断
读 digest(大班可分生读取)。**一名学生一个 MD 文件 + 一个自包含 HTML 文件**(内嵌 CSS,可直接转发/打印)。
每个非 AC 提交都要给出**人话结论**,判定规则:
| 状态 | 判定方法 | 人话示例 |
| --- | --- | --- |
| CE | 直接读 `errorHead`(gcc 报错带行号) | 变量没有定义 / 少分号 / 函数名写错(print→printf)/ 重复定义 / 输入输出符号写反 |
| WA | 读 `code` 对照题意;有 AC 版时做 diff,差异处即病因 | 数组开小了 / 边界条件差一个等于号 / 输出少换行 / 变量没初始化 / 输出没按题意保留小数位 |
| TLE | 读 `code` 看循环 | 循环条件写错死循环(`1<=T` 恒真)/ 方向写反 / 漏读入起点 / 算法太慢 |
| RE | 读 `code` | 数组越界 / 除零 |
**多鼓励**:报告必须有「🌟 值得表扬的地方」卡片放在最前;一遍通过的题写「一遍通过,非常不错!」;
订正到底的写韧劲;AC 版代码写得好的点名夸(如「min 用得干脆利落」)。表扬必须基于事实,不许编造。
整体分析先扬后抑:亮点在前,习惯问题在后;建议用编号列表给可执行动作。
**客观题(选择/判断)特殊处理——不写提交历史,直接给错题+题目分析+选项**:
这类题学生只能提交对/错,会反复试答案,所以报告直接列出「答错的题」:
1. 取标准答案:用该题**全部学生 AC 卷交叉比对**(≥2 人一致即认定),无需教师提供答案。
2. 学生 WA 卷与标准答案逐题 diff → 得出每题「答错次数」和「答案轨迹」。
3. 题干与选项直接用 digest 的 `objective[pid].questions`(脚本已抓取);若缺失再手工
GET `<base-url>/p/<pid>` 提取。
4. 每道错题输出:题干原文 + **完整选项(逐项列出)** + 你的答案轨迹 + 正确答案 + 考点分析
(一段人话讲透为什么;选项里的陷阱项要点名,如「−1.2 是诱导你按小数除法算的」)。
5. 开头加一句提示:「客观题不建议反复提交试答案,错的就是没弄懂的知识点」。
**整体分析**要跨题目归纳习惯问题,可用的典型模式:
- 多题首刷全 CE → 没编译就直接提交,粗心;
- 变量未声明/未初始化反复出现 → 声明与初始化意识弱;
- WA 集中在边界/格式 → 审题不细,输出格式(换行、小数位)没对题面;
- 反复「交一发试试」→ 概念不清靠猜,订正态度好但方法不对;
- 大量提交后全部 AC → 订正能力强(要点名表扬的亮点);
- 一次通过率高 → 基础扎实(可建议进拓展)。
### 3. 按固定模板输出报告(一人一 MD + 一 HTML)
**MD 结构**(顺序固定):
```markdown
# 学生提交诊断报告 · <姓名>
> 班级/章节/日期/审核稿声明 + 📊 总览(进度、首刷%、提交次数)
## 🌟 值得表扬的地方 ← 放最前,2~4 条事实型表扬
## 💻 编程题逐题诊断 ← 每题一个小节:第一次提交…第N次提交:通过 + 📌复盘框
## 📝 选择题 · 错题分析 ← 只列答错的题:题干/答案轨迹/正确答案/考点分析
## 📝 判断题 · 错题分析 ← 同上
## 📖 整体分析 ← 先扬后抑
## ✅ 给<姓名>的建议 ← 3~4 条可执行动作
```
**HTML**:与 MD 同名 `.html`,自包含单文件(内嵌 CSS、无外部依赖、可打印)。**受众是家长**,设计以
「读起来舒服、看得懂」为先(v2 定稿规范,经用户确认):
- **样式参考(必须先读)**:`samples/report-sample.html` 与 `samples/report-sample.md`——
生成任何报告前先读样例,**完整复用其 CSS、卡片结构、徽章配色与文案语气,只替换内容**,
确保所有 AI 产出的报告观感一致。
- 暖色纸感背景(#faf8f4)+ 白卡片,基础字号 ≥16.5px、行距 ≥1.9;max-width 820px;移动端断点适配;
- 🌟表扬绿卡前置;📊完成情况用**进度条**可视化(课堂/作业/拓展),**不带图例行**;
- 编程题时间线的状态徽章用**家长能懂的话**:✍️ 写错语法(CE)/ 🔄 结果不对(WA)/ ⏱️ 运行超时(TLE)/ 🎉 通过(AC);
- 客观题错题卡:题干引用块 + **选项逐项格子**(正确选项绿框 ✓、孩子错选橙框)+ 答案轨迹 + 💡考点黄框;
- 结尾「📖 老师的整体评价」**先扬后抑**;「接下来要养的小习惯」**每个分点独立成行**(①②③各一段);
- **不要**「写给家长的话」导读卡、不要「在家可以这样帮孩子」模块、不要小图标图例(用户已确认去掉);
- 「教师审核稿」提示缩为一行小字置顶(不放大横幅),术语尽量翻译成生活语言;
- **PDF 导出(v2 定稿:单页长图式,标准宽 **660px**,桌面布局、单页无分页)**:`scripts/mkpdf.mjs <html> <pdf>`
两遍法——先用无头 Edge 在 660px 视口量内容真实高度,再以 `@page{size:660px <高度+120>px; margin:0}`
输出**一整页** PDF(零页边距、颜色保真、自动剔除悬浮按钮与审核稿行)。
用法:`node scripts/mkpdf.mjs 报告.html 报告.pdf`(中文路径已内置 ASCII 临时名处理)。
- **交付三件套与命名(用户定稿)**:每名学生 3 个文件、**统一命名**
`<姓名>-<班组>-<课次号>-反馈报告.{md,html,pdf}`,
例:`王凯平-克力周日0830CSP02-04-反馈报告.md / .html / .pdf`。
**「班组-课次号」(如 克力周日0830CSP02-04)必须同时出现在文件名和报告标题里**——它说明
是哪个班、**第几次课**;章节名(如「二维数组图形」)写在报告标题的副行。
⚠️ **课次号 = 本学期第几次课(与内部正本 `YYYYMMDD_课程编号-课次.md` 一致),不是 OJ 章节号**。
OJ 章节号(章节标题前缀数字)只可在报告内文提及(如「OJ 章节:03 二维数组」),不得用于文件名。
班级汇总命名 `<班组>-<课次号>-反馈汇总-<日期>.md`。
同时生成班级汇总 MD(整体表 + 共性问题 + 教师跟进优先级),命名
`<班级>-<章节>-反馈汇总-<日期>.md`;全部产物建议放同一个输出目录(如 `class-feedback\`),
三件套命名以「**姓名-课程阶段-章节-反馈报告**」为准。
### 4. 审核红线(必须写进每次交付说明)
- 报告是**草稿**,发送给学生/家长前必须由带班教师审核措辞;
- 诊断只写事实与学习习惯(变量没定义、没编译就交),**不写人身评价**(笨/懒/不认真听讲);
- 代码、编译报错、答错的具体选项属于教学敏感数据,报告不要发到学生群,只给教师本人;
- 一个学生的报告不要引用其他学生的成绩做对比排名。
## 依赖与已知边界
- 课程插件须 ≥ C2.3(feedback v1 + analysis withCode/withHistory),qonnwolf 已验证(2026-09-09)。
- `analysis` 是整章节全班粒度的重接口(可达数百 KB),一次运行只调一次,不要按学生循环调用。
- WA/TLE 的「题意对照」依赖 AI 读代码推断;拿不准的结论在报告中用「疑似」标注,由教师定夺。
- 测试点级别的输入输出细节 API 不提供,如需可让教师去 OJ 记录页(用首刷 `rid`)人工查看。

View File

@@ -0,0 +1,992 @@
{
"generatedAt": "2026-09-12T10:49:40.512Z",
"baseUrl": "https://oj.qonnwolf.com",
"course": {
"id": "6a826183bdde81887a2237b5",
"title": "2026 秋季班 CSP04"
},
"group": "橙子周六1400CSP04",
"section": {
"id": "6a826183bdde81887a2237ba",
"no": "02",
"name": "简单排序",
"title": "02 简单排序"
},
"progress": [
{
"title": "01 基础回顾",
"submitted": 5,
"started": 5,
"students": 5
},
{
"title": "02 简单排序",
"submitted": 2,
"started": 2,
"students": 5
},
{
"title": "03 二维数组",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "04 二维数组图形",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "05 二维数组综合",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "06 综合训练1",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "07 自定义函数进阶",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "08 sort基础",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "09 sort进阶",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "10 结构体基础",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "11 结构体进阶",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "12 综合训练2",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "13 递推算法 ",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "14 指针基础",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "15 指针进阶",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "16 文件操作与异常处理",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "17 综合训练3",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "18 真题实战1",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "19 真题实战2",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "20 期末考试",
"submitted": 0,
"started": 0,
"students": 5
}
],
"classSummary": {
"studentCount": 5,
"startedStudentCount": 2,
"submittedStudentCount": 2,
"completedStudentCount": 0,
"attentionStudentCount": 5,
"notStartedStudentCount": 3,
"recoveredStudentCount": 1,
"completionRate": 5.88,
"firstAttemptScoreRate": 70,
"finalScoreRate": 5.88,
"averageAttemptsPerStudent": 1.6,
"averageFirstAttemptDurationMs": 1649862
},
"perProblem": [
{
"name": "📝 课堂练习",
"title": "CSP04-02A",
"problems": [
{
"pid": 4262,
"title": "冒泡排序实现",
"submitted": 2,
"accepted": 2,
"firstAttemptScoreRate": 55,
"averageAttempts": 2
},
{
"pid": 4263,
"title": "选择排序实现",
"submitted": 2,
"accepted": 2,
"firstAttemptScoreRate": 100,
"averageAttempts": 1
},
{
"pid": 4264,
"title": "计算排序后的交换次数",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4265,
"title": "求第 K 小的数",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4266,
"title": "成绩排名(稳定排序)",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 6602,
"title": "简单排序 - 选择题",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 6603,
"title": "简单排序 - 判断题",
"submitted": 1,
"accepted": 1,
"firstAttemptScoreRate": 40,
"averageAttempts": 2
}
]
},
{
"name": "📋 课后作业",
"title": "CSP04-02B",
"problems": [
{
"pid": 4267,
"title": "数字排序(作业)",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4268,
"title": "找中位数",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4269,
"title": "判断排序方向",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
}
]
},
{
"name": "🚀 拓展练习",
"title": "CSP04-02C",
"problems": [
{
"pid": 4270,
"title": "计算逆序对数量",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4271,
"title": "鸡尾酒排序",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4272,
"title": "区间排序",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4273,
"title": "排序可视化(模拟输出)",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4274,
"title": "双关键字排序",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 8164,
"title": "部分排序",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 8165,
"title": "相邻差最小",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
}
]
}
],
"students": [
{
"uid": 202,
"name": "张雨禾",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 3,
"firstAttemptScoreRate": 80,
"finalScoreRate": 17.65,
"attemptCount": 4,
"signals": [
"尚未完成"
]
},
"problems": [
{
"tid": "tid1",
"pid": 4262,
"title": "冒泡排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f35025d632ee5c41c5dd",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint arr[10010];\nint n;\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\t\n\t\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t\tswap(arr[j],arr[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\t\n\t\n}\n"
}
]
},
{
"tid": "tid1",
"pid": 4263,
"title": "选择排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4fec425d632ee5c41d9f9",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint n;\nint arr[10010];\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tint maxx=arr[i];\n\t\tint idx=i;\n\t\tfor(int j=i+1;j<=n;j++){\n\t\t\tif(arr[j]>maxx){\n\t\t\t\tmaxx=arr[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(arr[idx],arr[i]);\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\t\n\treturn 0;\t\n}\n"
}
]
},
{
"tid": "tid1",
"pid": 6603,
"title": "简单排序 - 判断题",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 40,
"rid": "6aa4eb6425d632ee5c41bebb",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': A\n'4': B\n'5': A\n"
},
{
"seq": 2,
"status": "AC",
"score": 100,
"rid": "6aa4eb7425d632ee5c41bf02",
"lang": "_",
"errorHead": "",
"code": "'1': B\n'2': B\n'3': A\n'4': A\n'5': B\n"
}
]
}
]
},
{
"uid": 357,
"name": "苏俊宇",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 2,
"firstAttemptScoreRate": 55,
"finalScoreRate": 11.76,
"attemptCount": 4,
"signals": [
"尚未完成",
"首刷掌握不足",
"订正后提升明显"
]
},
"problems": [
{
"tid": "tid1",
"pid": 4262,
"title": "冒泡排序实现",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 10,
"rid": "6aa4f59825d632ee5c41c8e3",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std; \nint arr[1000];\nint main(){\n\tint n;\n\tcin>>n;\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\t\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]);\n\t\t\t int t=arr[j];\n\t\t\t arr[j]=arr[j+1];\n\t\t\t arr[j+1]=t;\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 2,
"status": "WA",
"score": 10,
"rid": "6aa4f5fb25d632ee5c41c943",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std; \nint arr[1000];\nint main(){\n\tint n;\n\tcin>>n;\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\t\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]);\n\t\t\t int t=arr[j];\n\t\t\t arr[j]=arr[j+1];\n\t\t\t arr[j+1]=t;\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 3,
"status": "AC",
"score": 100,
"rid": "6aa4f63e25d632ee5c41c99a",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std; \nint arr[1000];\nint main(){\n\tint n;\n\tcin>>n;\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\t\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t int t=arr[j];\n\t\t\t arr[j]=arr[j+1];\n\t\t\t arr[j+1]=t;\n\t\t\t}\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
}
]
},
{
"tid": "tid1",
"pid": 4263,
"title": "选择排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa5015825d632ee5c41e61c",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std; \nint arr[1000];\nint main(){\n\tint n;\n cin>>n;\n for(int i=1;i<=n;i++){\n \tcin>>arr[i];\n\t}\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tint maxx=arr[i];\n\t\tint idx=i;\n\t\tfor(int j=i+1;j<=n;j++){\n\t\t\tif(arr[j]>maxx){\n\t\t\t\tmaxx=arr[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(arr[idx],arr[i]);\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
}
]
}
]
},
{
"uid": 360,
"name": "郑子煜",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 0,
"firstAttemptScoreRate": null,
"finalScoreRate": 0,
"attemptCount": 0,
"signals": [
"尚未开始"
]
},
"problems": []
},
{
"uid": 370,
"name": "卢华琛",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 0,
"firstAttemptScoreRate": null,
"finalScoreRate": 0,
"attemptCount": 0,
"signals": [
"尚未开始"
]
},
"problems": []
},
{
"uid": 393,
"name": "鲍佳音",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 0,
"firstAttemptScoreRate": null,
"finalScoreRate": 0,
"attemptCount": 0,
"signals": [
"尚未开始"
]
},
"problems": []
},
{
"uid": 366,
"name": "王子芮",
"groups": [],
"makeup": true,
"stats": {
"assigned": 17,
"accepted": 2,
"firstAttemptScoreRate": 55,
"finalScoreRate": 11.76,
"attemptCount": 5,
"signals": [
"尚未完成",
"首刷掌握不足",
"订正后提升明显"
]
},
"problems": [
{
"tid": "tid1",
"pid": 4262,
"title": "冒泡排序实现",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 10,
"rid": "6aa4f64425d632ee5c41c9b6",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[1000];\nint main(){\n\tint n=0,a=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t\tswap(arr[j],arr[j+1]);\n\t\t\t\tint t=arr[j];\n\t\t\t\tarr[j]=arr[j+i];\n\t\t\t\tarr[j+1]=t;\n\t\t\t}\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 2,
"status": "AC",
"score": 100,
"rid": "6aa4fcd225d632ee5c41d61e",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[1000];\nint main(){\n\tint n=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t\tswap(arr[j],arr[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 3,
"status": "WA",
"score": 0,
"rid": "6aa4ffd425d632ee5c41dd5c",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[100100];\nint main(){\n\tint n=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tint maxx=arr[i];\n\t\tint idx=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(arr[j]>maxx){\n\t\t\t\tmaxx=arr[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(arr[idx],arr[i]);\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 4,
"status": "AC",
"score": 100,
"rid": "6aa5004825d632ee5c41df24",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[1000];\nint main(){\n\tint n=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t\tswap(arr[j],arr[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
}
]
},
{
"tid": "tid1",
"pid": 4263,
"title": "选择排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa5002725d632ee5c41de78",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[100100];\nint main(){\n\tint n=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tint maxx=arr[i];\n\t\tint idx=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(arr[j]>maxx){\n\t\t\t\tmaxx=arr[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(arr[idx],arr[i]);\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}\n"
}
]
}
]
},
{
"uid": 364,
"name": "李若瑜",
"groups": [],
"makeup": true,
"stats": {
"assigned": 17,
"accepted": 0,
"firstAttemptScoreRate": 30,
"finalScoreRate": 1.76,
"attemptCount": 3,
"signals": [
"尚未完成",
"首刷掌握不足",
"反复尝试仍未通过"
]
},
"problems": [
{
"tid": "tid1",
"pid": 4263,
"title": "选择排序实现",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 30,
"rid": "6aa5001c25d632ee5c41de3f",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint r[100100];\nint main(){\n\tint n=0;\n\tcin >> n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin >> r[i];\n\t}for(int i=1;i<=n;i++){\n\t\tint m=r[i];\n\t\tint d=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(r[j]>m){\n\t\t\t\tm=r[j];\n\t\t\t\td=j;\n\t\t\t}\n\t\t\tswap(r[d],r[i]);\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout << r[i] << \" \";\n\t}\t\n\treturn 0;\n} "
},
{
"seq": 2,
"status": "WA",
"score": 30,
"rid": "6aa5005c25d632ee5c41df73",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint r[100100];\nint main(){\n\tint n=0;\n\tcin >> n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin >> r[i];\n\t}for(int i=1;i<=n;i++){\n\t\tint m=r[i];\n\t\tint d=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(r[j]>m){\n\t\t\t\tm=r[j];\n\t\t\t\td=j;\n\t\t\t}\n\t\t\tswap(r[d],r[i]);\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout << r[i] << \" \";\n\t}\t\n\treturn 0;\n} \n"
},
{
"seq": 3,
"status": "WA",
"score": 30,
"rid": "6aa501bf25d632ee5c41e96f",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint r[100100];\nint main(){\n\tint n=0;\n\tcin >> n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin >> r[i];\n\t}for(int i=1;i<=n;i++){\n\t\tint m=r[i];\n\t\tint d=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(r[j]>m){\n\t\t\t\tm=r[j];\n\t\t\t\td=j;\n\t\t\t}\n\tswap(r[d],r[i]);\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout << r[i] << \" \";\n\t}\t\n\treturn 0;\n} \n"
}
]
}
]
},
{
"uid": 352,
"name": "张立坤",
"groups": [],
"makeup": true,
"stats": {
"assigned": 17,
"accepted": 6,
"firstAttemptScoreRate": 83.33,
"finalScoreRate": 35.29,
"attemptCount": 9,
"signals": [
"尚未完成"
]
},
"problems": [
{
"tid": "tid1",
"pid": 4262,
"title": "冒泡排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f3be25d632ee5c41c68c",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include <bits/stdc++.h>\nusing namespace std;\nint a[1010];\nint n;\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>a[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(a[j]>a[j+1]){\n\t\t\t\tswap(a[j],a[j+1]);\n\t\t\t}\n\t\t} \n\t\t\n\t\t\n\t} \n\tfor(int i=1;i<=n;i++){\n\t\tcout<<a[i]<<\" \";\n\t}\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
]
},
{
"tid": "tid1",
"pid": 4263,
"title": "选择排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f40625d632ee5c41c700",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include <bits/stdc++.h>\nusing namespace std;\nint a[1010];\nint n;\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>a[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(a[j]<a[j+1]){\n\t\t\t\tswap(a[j],a[j+1]);\n\t\t\t}\n\t\t} \n\t\t\n\t\t\n\t} \n\tfor(int i=1;i<=n;i++){\n\t\tcout<<a[i]<<\" \";\n\t}\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
]
},
{
"tid": "tid1",
"pid": 4264,
"title": "计算排序后的交换次数",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f47c25d632ee5c41c7da",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include <bits/stdc++.h>\nusing namespace std;\nint a[1010];\nint n,s;\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>a[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(a[j]>a[j+1]){\n\t\t\t\tswap(a[j],a[j+1]);\n\t\t\t\ts++;\n\t\t\t}\n\t\t} \n\t\t\n\t\t\n\t} \n\tfor(int i=1;i<=n;i++){\n\t\tcout<<a[i]<<\" \";\n\t}\n\tcout<<endl<<s;\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
]
},
{
"tid": "tid1",
"pid": 4265,
"title": "求第 K 小的数",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f55b25d632ee5c41c883",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include <bits/stdc++.h>\nusing namespace std;\nint a[1010];\nint n,s;\nint main(){\n\tcin>>n>>s;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>a[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(a[j]>a[j+1]){\n\t\t\t\tswap(a[j],a[j+1]);\n\t\t\t}\n\t\t} \n\t\t\n\t\t\n\t} \n\tfor(int i=1;i<=n;i++){\n\t\tcout<<a[s]<<\" \";\n\t\treturn 0;\n\t}\n\tcout<<endl<<s;\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
]
},
{
"tid": "tid1",
"pid": 6602,
"title": "简单排序 - 选择题",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 40,
"rid": "6aa500c325d632ee5c41e31d",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': A\n'4': B\n'5': A\n"
},
{
"seq": 2,
"status": "WA",
"score": 40,
"rid": "6aa500d425d632ee5c41e397",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': D\n'4': A\n'5': C\n"
},
{
"seq": 3,
"status": "AC",
"score": 100,
"rid": "6aa500e325d632ee5c41e3c8",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': C\n'4': C\n'5': B\n"
}
]
},
{
"tid": "tid1",
"pid": 6603,
"title": "简单排序 - 判断题",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 60,
"rid": "6aa501a425d632ee5c41e7e8",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': A\n'4': A\n'5': A\n"
},
{
"seq": 2,
"status": "AC",
"score": 100,
"rid": "6aa501ad25d632ee5c41e7ff",
"lang": "_",
"errorHead": "",
"code": "'1': B\n'2': B\n'3': A\n'4': A\n'5': B\n"
}
]
}
]
},
{
"uid": 365,
"name": "潘沐辰",
"groups": [],
"makeup": true,
"stats": {
"assigned": 17,
"accepted": 2,
"firstAttemptScoreRate": 50,
"finalScoreRate": 11.76,
"attemptCount": 4,
"signals": [
"尚未完成",
"首刷掌握不足",
"订正后提升明显"
]
},
"problems": [
{
"tid": "tid1",
"pid": 4262,
"title": "冒泡排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f4f925d632ee5c41c833",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint ar[1010],n;\nint main(){\n\tcin >> n;\n\tfor (int i=1;i<=n;i++){\n\t\tcin >> ar[i];\n\t}\n\tfor (int i=1;i<=n-1;i++){\n\t\tfor (int j=1;j<=n-i;j++){\n\t\t\tif (ar[j]>ar[j+1]){\n\t\t\t\tswap(ar[j],ar[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tcout << ar[i] << ' ';\n\t}\n\treturn 0;\n}\n"
}
]
},
{
"tid": "tid1",
"pid": 4263,
"title": "选择排序实现",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 0,
"rid": "6aa4fc4d25d632ee5c41d51f",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint ar[1010],n;\nint main(){\n\tcin >> n;\n\tfor (int i=1;i<=n;i++){\n\t\tcin >> ar[i];\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tfor (int j=1;j<=n-i;j++){\n\t\t\tif (ar[j]>ar[j+1]){\n\t\t\t\tswap(ar[j],ar[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tcout << ar[i] << ' ';\n\t}\n\treturn 0;\n}\n"
},
{
"seq": 2,
"status": "WA",
"score": 10,
"rid": "6aa4fe6925d632ee5c41d8d0",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint ar[1010],n;\nint main(){\n\tcin >> n;\n\tfor (int i=1;i<=n;i++){\n\t\tcin >> ar[i];\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tint maxx=INT_MIN;\n\t\tint idx;\n\t\t\n\t\tfor (int j=1+i;j<=n;j++){\n\t\t\tif (ar[j]>maxx){\n\t\t\t\tmaxx=ar[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(ar[idx],ar[i]);\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tcout << ar[i] << ' ';\n\t}\n\treturn 0;\n}\n"
},
{
"seq": 3,
"status": "AC",
"score": 100,
"rid": "6aa4fec525d632ee5c41da01",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint ar[1010],n;\nint main(){\n\tcin >> n;\n\tfor (int i=1;i<=n;i++){\n\t\tcin >> ar[i];\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tint maxx=ar[i];\n\t\tint idx=i;\n\t\t\n\t\tfor (int j=1+i;j<=n;j++){\n\t\t\tif (ar[j]>maxx){\n\t\t\t\tmaxx=ar[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(ar[idx],ar[i]);\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tcout << ar[i] << ' ';\n\t}\n\treturn 0;\n}\n"
}
]
}
]
}
],
"objective": {
"6602": {
"title": "简单排序 - 选择题 - 题目详情 - 穹狼科创",
"questions": [
{
"no": 1,
"text": "【202503】对数组 arr[]={5, 3, 8, 1} 进行升序排序,执行第一轮冒泡排序后数组 arr 中的内容为( )。",
"options": [
"3, 5, 1, 8",
"3, 1, 5, 8",
"3, 5, 8, 1",
"5, 3, 8, 1"
]
},
{
"no": 2,
"text": "【202506】小杨在整理一副扑克牌的所有红心扑克牌,使其从小到大排列。他的做法是:最开始抓到第1张扑克牌被认为已经排好序;然后抓第2张扑克牌,将其插入至有序部分的正确位置;不断循环步骤,每次将新抓到扑克牌插入至有序部分,直至抓完所有扑克牌,这样抓牌结束时就完成了扑克牌的排序。小杨这种整理扑克牌的方式与( )排序的方式最接近。",
"options": [
"冒泡排序",
"插入排序",
"选择排序",
"直接排序"
]
},
{
"no": 3,
"text": "【202509】关于排序算法的稳定性,以下说法错误的是( )。",
"options": [
"稳定的排序算法不改变相等元素的相对位置",
"冒泡排序是稳定的排序算法",
"选择排序是稳定的排序算法",
"插入排序是稳定的排序算法"
]
},
{
"no": 4,
"text": "【202606】下面代码使用某种排序算法,将数组中的元素按从小到大排序。这段代码使用的排序算法是( )。 void mystery_sort(double arr[], int n) { for (int i = 0; i < n - 1; i++) { int minPos = i; for (int j = i + 1; j < n; j++) { if (arr[j] < arr[minPos]) { minPos = j; } } double temp = arr[i]; arr[i] = arr[minPos]; arr[minPos] = temp; } }",
"options": [
"冒泡排序",
"插入排序",
"选择排序",
"非典型排序"
]
},
{
"no": 5,
"text": "【202509】关于插入排序的时间复杂度,下列说法正确的是( )。",
"options": [
"最好情况和最坏情况的时间复杂度都是",
"O",
"(",
"n",
"2",
")",
"最好情况是",
"O",
"(",
"n",
")",
",最坏情况是",
"O",
"(",
"n",
"2",
")",
"最好情况是",
"O",
"(",
"n",
")",
",最坏情况是",
"O",
"(",
"2",
"n",
")",
"最好情况是",
"O",
"(",
"n",
"2",
")",
",最坏情况是",
"O",
"(",
"2",
"n",
")"
]
}
]
},
"6603": {
"title": "简单排序 - 判断题 - 题目详情 - 穹狼科创",
"questions": [
{
"no": 1,
"text": "【202509】对整数数组 {4, 1, 3, 1, 5, 2} 进行冒泡排序(将最大元素放到最后),执行一轮之后是 {4, 1, 3, 1, 2, 5} 。",
"options": [
"正确",
"错误"
]
},
{
"no": 2,
"text": "【202503】对数组 arr[]={4, 3, 1, 5, 2} 进行升序排序,执行第一轮选择排序后数组arr中的内容是 {1, 4, 3, 5, 2} 。",
"options": [
"正确",
"错误"
]
},
{
"no": 3,
"text": "【202512】冒泡排序和插入排序都是稳定排序算法。",
"options": [
"正确",
"错误"
]
},
{
"no": 4,
"text": "【202606】如果使用带 flag 的冒泡排序,且待排序数组一开始就是有序的,那么算法只需一轮扫描即可结束,时间复杂度为 O ( n ) 。",
"options": [
"正确",
"错误"
]
},
{
"no": 5,
"text": "【202603】由于选择排序和插入排序的时间复杂度均为 O ( n 2 ) ,在任何实际场景下两者的性能表现几乎相同,可以互相替代。( )",
"options": [
"正确",
"错误"
]
}
]
}
}
}

View File

@@ -0,0 +1,342 @@
{
"students": [
{
"uid": 366,
"name": "王子芮",
"groups": [],
"stats": {
"assigned": 17,
"accepted": 2,
"firstAttemptScoreRate": 55,
"finalScoreRate": 11.76,
"attemptCount": 5,
"signals": [
"尚未完成",
"首刷掌握不足",
"订正后提升明显"
]
},
"problems": [
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 10,
"rid": "6aa4f64425d632ee5c41c9b6",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[1000];\nint main(){\n\tint n=0,a=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t\tswap(arr[j],arr[j+1]);\n\t\t\t\tint t=arr[j];\n\t\t\t\tarr[j]=arr[j+i];\n\t\t\t\tarr[j+1]=t;\n\t\t\t}\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 2,
"status": "AC",
"score": 100,
"rid": "6aa4fcd225d632ee5c41d61e",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[1000];\nint main(){\n\tint n=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t\tswap(arr[j],arr[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 3,
"status": "WA",
"score": 0,
"rid": "6aa4ffd425d632ee5c41dd5c",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[100100];\nint main(){\n\tint n=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tint maxx=arr[i];\n\t\tint idx=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(arr[j]>maxx){\n\t\t\t\tmaxx=arr[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(arr[idx],arr[i]);\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 4,
"status": "AC",
"score": 100,
"rid": "6aa5004825d632ee5c41df24",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[1000];\nint main(){\n\tint n=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t\tswap(arr[j],arr[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
}
]
},
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa5002725d632ee5c41de78",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint arr[100100];\nint main(){\n\tint n=0;\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tint maxx=arr[i];\n\t\tint idx=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(arr[j]>maxx){\n\t\t\t\tmaxx=arr[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(arr[idx],arr[i]);\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}\n"
}
]
}
],
"makeup": true
},
{
"uid": 364,
"name": "李若瑜",
"groups": [],
"stats": {
"assigned": 17,
"accepted": 0,
"firstAttemptScoreRate": 30,
"finalScoreRate": 1.76,
"attemptCount": 3,
"signals": [
"尚未完成",
"首刷掌握不足",
"反复尝试仍未通过"
]
},
"problems": [
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 30,
"rid": "6aa5001c25d632ee5c41de3f",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint r[100100];\nint main(){\n\tint n=0;\n\tcin >> n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin >> r[i];\n\t}for(int i=1;i<=n;i++){\n\t\tint m=r[i];\n\t\tint d=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(r[j]>m){\n\t\t\t\tm=r[j];\n\t\t\t\td=j;\n\t\t\t}\n\t\t\tswap(r[d],r[i]);\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout << r[i] << \" \";\n\t}\t\n\treturn 0;\n} "
},
{
"seq": 2,
"status": "WA",
"score": 30,
"rid": "6aa5005c25d632ee5c41df73",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint r[100100];\nint main(){\n\tint n=0;\n\tcin >> n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin >> r[i];\n\t}for(int i=1;i<=n;i++){\n\t\tint m=r[i];\n\t\tint d=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(r[j]>m){\n\t\t\t\tm=r[j];\n\t\t\t\td=j;\n\t\t\t}\n\t\t\tswap(r[d],r[i]);\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout << r[i] << \" \";\n\t}\t\n\treturn 0;\n} \n"
},
{
"seq": 3,
"status": "WA",
"score": 30,
"rid": "6aa501bf25d632ee5c41e96f",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint r[100100];\nint main(){\n\tint n=0;\n\tcin >> n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin >> r[i];\n\t}for(int i=1;i<=n;i++){\n\t\tint m=r[i];\n\t\tint d=i;\n\t\tfor(int j=1+i;j<=n;j++){\n\t\t\tif(r[j]>m){\n\t\t\t\tm=r[j];\n\t\t\t\td=j;\n\t\t\t}\n\tswap(r[d],r[i]);\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout << r[i] << \" \";\n\t}\t\n\treturn 0;\n} \n"
}
]
}
],
"makeup": true
},
{
"uid": 352,
"name": "张立坤",
"groups": [],
"stats": {
"assigned": 17,
"accepted": 6,
"firstAttemptScoreRate": 83.33,
"finalScoreRate": 35.29,
"attemptCount": 9,
"signals": [
"尚未完成"
]
},
"problems": [
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f3be25d632ee5c41c68c",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include <bits/stdc++.h>\nusing namespace std;\nint a[1010];\nint n;\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>a[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(a[j]>a[j+1]){\n\t\t\t\tswap(a[j],a[j+1]);\n\t\t\t}\n\t\t} \n\t\t\n\t\t\n\t} \n\tfor(int i=1;i<=n;i++){\n\t\tcout<<a[i]<<\" \";\n\t}\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
]
},
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f40625d632ee5c41c700",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include <bits/stdc++.h>\nusing namespace std;\nint a[1010];\nint n;\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>a[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(a[j]<a[j+1]){\n\t\t\t\tswap(a[j],a[j+1]);\n\t\t\t}\n\t\t} \n\t\t\n\t\t\n\t} \n\tfor(int i=1;i<=n;i++){\n\t\tcout<<a[i]<<\" \";\n\t}\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
]
},
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f47c25d632ee5c41c7da",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include <bits/stdc++.h>\nusing namespace std;\nint a[1010];\nint n,s;\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>a[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(a[j]>a[j+1]){\n\t\t\t\tswap(a[j],a[j+1]);\n\t\t\t\ts++;\n\t\t\t}\n\t\t} \n\t\t\n\t\t\n\t} \n\tfor(int i=1;i<=n;i++){\n\t\tcout<<a[i]<<\" \";\n\t}\n\tcout<<endl<<s;\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
]
},
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f55b25d632ee5c41c883",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include <bits/stdc++.h>\nusing namespace std;\nint a[1010];\nint n,s;\nint main(){\n\tcin>>n>>s;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>a[i];\n\t}\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(a[j]>a[j+1]){\n\t\t\t\tswap(a[j],a[j+1]);\n\t\t\t}\n\t\t} \n\t\t\n\t\t\n\t} \n\tfor(int i=1;i<=n;i++){\n\t\tcout<<a[s]<<\" \";\n\t\treturn 0;\n\t}\n\tcout<<endl<<s;\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n\t\n}\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
}
]
},
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 40,
"rid": "6aa500c325d632ee5c41e31d",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': A\n'4': B\n'5': A\n"
},
{
"seq": 2,
"status": "WA",
"score": 40,
"rid": "6aa500d425d632ee5c41e397",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': D\n'4': A\n'5': C\n"
},
{
"seq": 3,
"status": "AC",
"score": 100,
"rid": "6aa500e325d632ee5c41e3c8",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': C\n'4': C\n'5': B\n"
}
]
},
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 60,
"rid": "6aa501a425d632ee5c41e7e8",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': A\n'4': A\n'5': A\n"
},
{
"seq": 2,
"status": "AC",
"score": 100,
"rid": "6aa501ad25d632ee5c41e7ff",
"lang": "_",
"errorHead": "",
"code": "'1': B\n'2': B\n'3': A\n'4': A\n'5': B\n"
}
]
}
],
"makeup": true
},
{
"uid": 365,
"name": "潘沐辰",
"groups": [],
"stats": {
"assigned": 17,
"accepted": 2,
"firstAttemptScoreRate": 50,
"finalScoreRate": 11.76,
"attemptCount": 4,
"signals": [
"尚未完成",
"首刷掌握不足",
"订正后提升明显"
]
},
"problems": [
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f4f925d632ee5c41c833",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint ar[1010],n;\nint main(){\n\tcin >> n;\n\tfor (int i=1;i<=n;i++){\n\t\tcin >> ar[i];\n\t}\n\tfor (int i=1;i<=n-1;i++){\n\t\tfor (int j=1;j<=n-i;j++){\n\t\t\tif (ar[j]>ar[j+1]){\n\t\t\t\tswap(ar[j],ar[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tcout << ar[i] << ' ';\n\t}\n\treturn 0;\n}\n"
}
]
},
{
"tid": "tid1",
"title": "",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 0,
"rid": "6aa4fc4d25d632ee5c41d51f",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint ar[1010],n;\nint main(){\n\tcin >> n;\n\tfor (int i=1;i<=n;i++){\n\t\tcin >> ar[i];\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tfor (int j=1;j<=n-i;j++){\n\t\t\tif (ar[j]>ar[j+1]){\n\t\t\t\tswap(ar[j],ar[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tcout << ar[i] << ' ';\n\t}\n\treturn 0;\n}\n"
},
{
"seq": 2,
"status": "WA",
"score": 10,
"rid": "6aa4fe6925d632ee5c41d8d0",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint ar[1010],n;\nint main(){\n\tcin >> n;\n\tfor (int i=1;i<=n;i++){\n\t\tcin >> ar[i];\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tint maxx=INT_MIN;\n\t\tint idx;\n\t\t\n\t\tfor (int j=1+i;j<=n;j++){\n\t\t\tif (ar[j]>maxx){\n\t\t\t\tmaxx=ar[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(ar[idx],ar[i]);\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tcout << ar[i] << ' ';\n\t}\n\treturn 0;\n}\n"
},
{
"seq": 3,
"status": "AC",
"score": 100,
"rid": "6aa4fec525d632ee5c41da01",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h> \nusing namespace std;\nint ar[1010],n;\nint main(){\n\tcin >> n;\n\tfor (int i=1;i<=n;i++){\n\t\tcin >> ar[i];\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tint maxx=ar[i];\n\t\tint idx=i;\n\t\t\n\t\tfor (int j=1+i;j<=n;j++){\n\t\t\tif (ar[j]>maxx){\n\t\t\t\tmaxx=ar[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(ar[idx],ar[i]);\n\t}\n\tfor (int i=1;i<=n;i++){\n\t\tcout << ar[i] << ' ';\n\t}\n\treturn 0;\n}\n"
}
]
}
],
"makeup": true
}
],
"objective": {
"undefined": {
"questions": []
}
}
}

View File

@@ -0,0 +1,557 @@
{
"generatedAt": "2026-09-12T10:44:08.975Z",
"baseUrl": "https://oj.qonnwolf.com",
"course": {
"id": "6a826183bdde81887a2237b5",
"title": "2026 秋季班 CSP04"
},
"group": "橙子周六1400CSP04",
"section": {
"id": "6a826183bdde81887a2237ba",
"no": "02",
"name": "简单排序",
"title": "02 简单排序"
},
"progress": [
{
"title": "01 基础回顾",
"submitted": 5,
"started": 5,
"students": 5
},
{
"title": "02 简单排序",
"submitted": 2,
"started": 2,
"students": 5
},
{
"title": "03 二维数组",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "04 二维数组图形",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "05 二维数组综合",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "06 综合训练1",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "07 自定义函数进阶",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "08 sort基础",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "09 sort进阶",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "10 结构体基础",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "11 结构体进阶",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "12 综合训练2",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "13 递推算法 ",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "14 指针基础",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "15 指针进阶",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "16 文件操作与异常处理",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "17 综合训练3",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "18 真题实战1",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "19 真题实战2",
"submitted": 0,
"started": 0,
"students": 5
},
{
"title": "20 期末考试",
"submitted": 0,
"started": 0,
"students": 5
}
],
"classSummary": {
"studentCount": 5,
"startedStudentCount": 2,
"submittedStudentCount": 2,
"completedStudentCount": 0,
"attentionStudentCount": 5,
"notStartedStudentCount": 3,
"recoveredStudentCount": 1,
"completionRate": 5.88,
"firstAttemptScoreRate": 70,
"finalScoreRate": 5.88,
"averageAttemptsPerStudent": 1.6,
"averageFirstAttemptDurationMs": 1649862
},
"perProblem": [
{
"name": "📝 课堂练习",
"title": "CSP04-02A",
"problems": [
{
"pid": 4262,
"title": "冒泡排序实现",
"submitted": 2,
"accepted": 2,
"firstAttemptScoreRate": 55,
"averageAttempts": 2
},
{
"pid": 4263,
"title": "选择排序实现",
"submitted": 2,
"accepted": 2,
"firstAttemptScoreRate": 100,
"averageAttempts": 1
},
{
"pid": 4264,
"title": "计算排序后的交换次数",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4265,
"title": "求第 K 小的数",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4266,
"title": "成绩排名(稳定排序)",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 6602,
"title": "简单排序 - 选择题",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 6603,
"title": "简单排序 - 判断题",
"submitted": 1,
"accepted": 1,
"firstAttemptScoreRate": 40,
"averageAttempts": 2
}
]
},
{
"name": "📋 课后作业",
"title": "CSP04-02B",
"problems": [
{
"pid": 4267,
"title": "数字排序(作业)",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4268,
"title": "找中位数",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4269,
"title": "判断排序方向",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
}
]
},
{
"name": "🚀 拓展练习",
"title": "CSP04-02C",
"problems": [
{
"pid": 4270,
"title": "计算逆序对数量",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4271,
"title": "鸡尾酒排序",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4272,
"title": "区间排序",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4273,
"title": "排序可视化(模拟输出)",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 4274,
"title": "双关键字排序",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 8164,
"title": "部分排序",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
},
{
"pid": 8165,
"title": "相邻差最小",
"submitted": 0,
"accepted": 0,
"firstAttemptScoreRate": null,
"averageAttempts": null
}
]
}
],
"students": [
{
"uid": 202,
"name": "张雨禾",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 3,
"firstAttemptScoreRate": 80,
"finalScoreRate": 17.65,
"attemptCount": 4,
"signals": [
"尚未完成"
]
},
"problems": [
{
"tid": "tid1",
"pid": 4262,
"title": "冒泡排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4f35025d632ee5c41c5dd",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint arr[10010];\nint n;\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\t\n\t\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t\tswap(arr[j],arr[j+1]);\n\t\t\t}\n\t\t}\n\t}\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\t\n\t\n}\n"
}
]
},
{
"tid": "tid1",
"pid": 4263,
"title": "选择排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa4fec425d632ee5c41d9f9",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std;\nint n;\nint arr[10010];\nint main(){\n\tcin>>n;\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tint maxx=arr[i];\n\t\tint idx=i;\n\t\tfor(int j=i+1;j<=n;j++){\n\t\t\tif(arr[j]>maxx){\n\t\t\t\tmaxx=arr[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(arr[idx],arr[i]);\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\t\n\treturn 0;\t\n}\n"
}
]
},
{
"tid": "tid1",
"pid": 6603,
"title": "简单排序 - 判断题",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 40,
"rid": "6aa4eb6425d632ee5c41bebb",
"lang": "_",
"errorHead": "",
"code": "'1': A\n'2': B\n'3': A\n'4': B\n'5': A\n"
},
{
"seq": 2,
"status": "AC",
"score": 100,
"rid": "6aa4eb7425d632ee5c41bf02",
"lang": "_",
"errorHead": "",
"code": "'1': B\n'2': B\n'3': A\n'4': A\n'5': B\n"
}
]
}
]
},
{
"uid": 357,
"name": "苏俊宇",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 2,
"firstAttemptScoreRate": 55,
"finalScoreRate": 11.76,
"attemptCount": 4,
"signals": [
"尚未完成",
"首刷掌握不足",
"订正后提升明显"
]
},
"problems": [
{
"tid": "tid1",
"pid": 4262,
"title": "冒泡排序实现",
"submissions": [
{
"seq": 1,
"status": "WA",
"score": 10,
"rid": "6aa4f59825d632ee5c41c8e3",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std; \nint arr[1000];\nint main(){\n\tint n;\n\tcin>>n;\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\t\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]);\n\t\t\t int t=arr[j];\n\t\t\t arr[j]=arr[j+1];\n\t\t\t arr[j+1]=t;\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 2,
"status": "WA",
"score": 10,
"rid": "6aa4f5fb25d632ee5c41c943",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std; \nint arr[1000];\nint main(){\n\tint n;\n\tcin>>n;\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\t\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]);\n\t\t\t int t=arr[j];\n\t\t\t arr[j]=arr[j+1];\n\t\t\t arr[j+1]=t;\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
},
{
"seq": 3,
"status": "AC",
"score": 100,
"rid": "6aa4f63e25d632ee5c41c99a",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std; \nint arr[1000];\nint main(){\n\tint n;\n\tcin>>n;\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tcin>>arr[i];\n\t}\n\t\n\tfor(int i=1;i<=n-1;i++){\n\t\tfor(int j=1;j<=n-i;j++){\n\t\t\tif(arr[j]>arr[j+1]){\n\t\t\t int t=arr[j];\n\t\t\t arr[j]=arr[j+1];\n\t\t\t arr[j+1]=t;\n\t\t\t}\n\t\t}\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
}
]
},
{
"tid": "tid1",
"pid": 4263,
"title": "选择排序实现",
"submissions": [
{
"seq": 1,
"status": "AC",
"score": 100,
"rid": "6aa5015825d632ee5c41e61c",
"lang": "cc.cc14o2",
"errorHead": "",
"code": "#include<bits/stdc++.h>\nusing namespace std; \nint arr[1000];\nint main(){\n\tint n;\n cin>>n;\n for(int i=1;i<=n;i++){\n \tcin>>arr[i];\n\t}\n\t\n\tfor(int i=1;i<=n;i++){\n\t\tint maxx=arr[i];\n\t\tint idx=i;\n\t\tfor(int j=i+1;j<=n;j++){\n\t\t\tif(arr[j]>maxx){\n\t\t\t\tmaxx=arr[j];\n\t\t\t\tidx=j;\n\t\t\t}\n\t\t}\n\t\tswap(arr[idx],arr[i]);\n\t}\n\tfor(int i=1;i<=n;i++){\n\t\tcout<<arr[i]<<\" \";\n\t}\n\treturn 0;\n}"
}
]
}
]
},
{
"uid": 360,
"name": "郑子煜",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 0,
"firstAttemptScoreRate": null,
"finalScoreRate": 0,
"attemptCount": 0,
"signals": [
"尚未开始"
]
},
"problems": []
},
{
"uid": 370,
"name": "卢华琛",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 0,
"firstAttemptScoreRate": null,
"finalScoreRate": 0,
"attemptCount": 0,
"signals": [
"尚未开始"
]
},
"problems": []
},
{
"uid": 393,
"name": "鲍佳音",
"groups": [
"橙子周六1400CSP04"
],
"stats": {
"assigned": 17,
"accepted": 0,
"firstAttemptScoreRate": null,
"finalScoreRate": 0,
"attemptCount": 0,
"signals": [
"尚未开始"
]
},
"problems": []
}
],
"objective": {
"6603": {
"title": "简单排序 - 判断题 - 题目详情 - 穹狼科创",
"questions": [
{
"no": 1,
"text": "【202509】对整数数组 {4, 1, 3, 1, 5, 2} 进行冒泡排序(将最大元素放到最后),执行一轮之后是 {4, 1, 3, 1, 2, 5} 。",
"options": [
"正确",
"错误"
]
},
{
"no": 2,
"text": "【202503】对数组 arr[]={4, 3, 1, 5, 2} 进行升序排序,执行第一轮选择排序后数组arr中的内容是 {1, 4, 3, 5, 2} 。",
"options": [
"正确",
"错误"
]
},
{
"no": 3,
"text": "【202512】冒泡排序和插入排序都是稳定排序算法。",
"options": [
"正确",
"错误"
]
},
{
"no": 4,
"text": "【202606】如果使用带 flag 的冒泡排序,且待排序数组一开始就是有序的,那么算法只需一轮扫描即可结束,时间复杂度为 O ( n ) 。",
"options": [
"正确",
"错误"
]
},
{
"no": 5,
"text": "【202603】由于选择排序和插入排序的时间复杂度均为 O ( n 2 ) ,在任何实际场景下两者的性能表现几乎相同,可以互相替代。( )",
"options": [
"正确",
"错误"
]
}
]
}
}
}

View File

@@ -0,0 +1,374 @@
# HydroOJ 课程插件 API 使用文档
本文档覆盖 课程插件(hydrooj-course) 当前源码注册的 JSON API,包括兼容查询、课程页面内部展示、教学反馈、学生周报和首刷写入接口。
API 只输出课程与学习事实,不自动生成评价或发送消息。面向家长或学生的文字必须由上层工具生成并由教师审核。
## 1. 接口总览
| 方法 | 路径 | 用途 | 主要权限 | 稳定性 |
| --- | --- | --- | --- | --- |
| `GET` | `/course/api/list` | 查询当前账号可见课程 | 已登录用户 | 兼容接口 |
| `GET` | `/course/api/detail/:cid` | 查询课程与章节结构 | 可访问该课程 | 兼容接口 |
| `GET` | `/course/api/analysis/:cid/:csid` | 查询章节成绩、首刷和最终结果 | 教师或授权校区查看者 | 敏感兼容接口 |
| `GET` | `/course/api/v1/courses/:cid/summary` | 查询当前查看学生的课程进度摘要 | 可访问该课程 | 页面内部接口 |
| `GET` | `/course/api/v1/courses/:cid/sections/:csid/view` | 按需查询一个章节的授权展示数据 | 可访问该课程 | 页面内部接口 |
| `GET` | `/course/api/v1/courses/:cid/students` | 分页搜索授权范围学生 | 教师或授权校区查看者 | 页面内部接口 |
| `GET` | `/course/api/v1/courses/:cid/sections/:csid/feedback/overview` | 章节概览与逐题统计 | 教师或授权校区查看者 | v1 |
| `GET` | `/course/api/v1/courses/:cid/sections/:csid/feedback/students` | 分页筛选学生反馈事实 | 教师或授权校区查看者 | v1 |
| `GET` | `/course/api/v1/courses/:cid/sections/:csid/feedback/students/:uid` | 单生逐题反馈证据 | 教师或授权校区查看者 | v1 |
| `GET` | `/course/api/v1/weekly-report/students` | 搜索授权范围内的周报学生 | 教师或授权校区查看者 | v1 |
| `GET` | `/course/api/v1/weekly-report/students/:uid` | 查询单生一周课程与提交事实 | 教师或授权校区查看者 | v1 |
| `POST` | `/course/:cid/s/:csid/practice/:tid/:pid/start` | 开启或重启首刷计时 | 已登录且满足课程规则 | 页面内部接口 |
页面内部展示接口只返回授权后的摘要、章节 HTML 和公开用户渲染字段,均设置 `Cache-Control: private, no-store`。
## 2. 认证、域路径与安全边界
- 所有接口使用当前 HydroOJ 登录会话,不接受通用管理员 Token。
- 主域直接使用表格中的路径;非主域在前面加 `/d/:domainId`。
- 调用时使用 `Accept: application/json`,跨页面请求保留同源 Cookie。
- 不要把真实 Cookie、账号密码、学生姓名、代码或响应原文写入仓库、聊天记录和公开日志。
- `analysis` 可能返回代码、编译错误、测试点和提交历史,只能在受控教师工具中按需开启。
- 教学反馈 v1 不返回邮箱、手机号、IP、源代码、完整提交历史、编译器原文或测试点详情,并设置 `Cache-Control: private, no-store` 与 `X-Content-Type-Options: nosniff`。
浏览器调用示例:
```js
const response = await fetch('/course/api/list', {
credentials: 'same-origin',
headers: { Accept: 'application/json' },
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = await response.json();
```
命令行调试示例:
```bash
curl -H "Accept: application/json" \
-H "Cookie: sid=<authorized-session-cookie>" \
"https://oj.example.com/d/example/course/api/list"
```
### 2.1 老师快速使用
老师通常按下面的顺序取数:
1. 浏览器登录 OJ 后访问 `/course/api/list`,取得课程 `id`。
2. 访问 `/course/api/detail/:cid`,取得章节 `id` 和关联作业结构。
3. 查看班级整体情况时调用反馈 `overview`;筛选学生时调用反馈 `students`;需要逐题证据时再调用单生详情。
4. 生成一周学习报告时先调用 `/course/api/v1/weekly-report/students?q=...` 找到学生,再按返回的 `uid` 调用周报详情。
课程页面上的进度摘要、章节 HTML 和人员选择属于内部展示接口。外部报表优先使用反馈与周报 API,避免依赖 HTML 字段。
仓库提供只读验收脚本,密码通过环境变量传入,结果只输出 HTTP、响应结构、耗时与并发错误数:
```bash
COURSE_API_USERNAME="teacher" COURSE_API_PASSWORD="..." \
node scripts/verify-course-api-live.mjs \
--base-url="https://oj.example.com" \
--concurrency=30
```
## 3. 课程列表
```http
GET /course/api/list?page=1&q=CSP
```
| 参数 | 默认值 | 说明 |
| --- | --- | --- |
| `page` | `1` | 正整数页码;每页数量读取系统设置 `pagination.course` |
| `q` | 空 | 按课程标题搜索;少于 2 个字符时按标题前缀匹配 |
普通用户只会看到自己拥有、班级被分配或未限制班级的课程;原生教师按教师权限查看。
```json
{
"courses": [
{
"id": "<cid>",
"title": "CSP-J 基础",
"tag": ["循环", "数组"],
"group": "CSP-J",
"cover": "/file/course-cover.webp",
"attend": 32,
"sectionCount": 12,
"beginAt": "2026-08-01T00:00:00.000Z",
"penaltySince": null
}
]
}
```
## 4. 课程详情
```http
GET /course/api/detail/:cid
```
用于读取课程基本信息、章节顺序和每个章节关联的三类作业。章节中的 `homeworks` 按 `tid1`、`tid2`、`tid3` 组织;考试章节通常只使用 `tid1`。
```json
{
"course": {
"id": "<cid>",
"title": "CSP-J 基础",
"tag": ["循环", "数组"],
"attend": 32
},
"sections": [
{
"id": "<csid>",
"title": "循环结构",
"pin": 1,
"type": "normal",
"homeworks": {
"tid1": {
"id": "<tid>",
"title": "📝 课堂练习",
"problemCount": 6
}
}
}
]
}
```
已删除、缺失或当前账号无权读取的题目不会计入 `problemCount`。
## 5. 页面轻量展示 API
这三条接口供课程详情页局部更新使用,均返回 `Cache-Control: private, no-store`。浏览器端只在当前页面会话中使用 15~60 秒的内存缓存,权限判断不会跨请求缓存。
### 5.1 课程进度摘要
```http
GET /course/api/v1/courses/:cid/summary
GET /course/api/v1/courses/:cid/summary?uid=123
```
`uid` 省略时查询自己。教师只能查询授权范围内学生。响应中的 `sections[]` 包含 `csid`、`total`、`done`、`visible` 和 `percent`;成绩未公开时 `done`、`percent` 为 `null`。
### 5.2 单章节展示
```http
GET /course/api/v1/courses/:cid/sections/:csid/view
GET /course/api/v1/courses/:cid/sections/:csid/view?uid=123
```
响应包含授权后的章节 `html`、首刷控件数据 `practice`、当前章节 `summary` 和是否存在待评测记录的 `pending`。本接口只读取当前章节及解锁所需前置条件。
### 5.3 课程人员分页
```http
GET /course/api/v1/courses/:cid/students?group=班级组名&page=1&q=学生名
```
| 参数 | 默认值 | 说明 |
| --- | --- | --- |
| `group` | 空 | 当前账号可查看的小组;课程页面要求老师先选组再请求 |
| `page` | `1` | 正整数页码,每页固定 50 人 |
| `q` | 空 | 在所选组内按用户名、显示名或 UID 搜索,最长 100 字符 |
返回 `students[]`、`page`、`pageSize` 和 `hasMore`。课程页面滚动到底时才请求下一页,切换小组会清空原姓名搜索。
## 6. 章节成绩分析(敏感兼容接口)
```http
GET /course/api/analysis/:cid/:csid
GET /course/api/analysis/:cid/:csid?withCode=true
GET /course/api/analysis/:cid/:csid?withHistory=true&withCode=true
```
| 参数 | 默认值 | 说明 |
| --- | --- | --- |
| `withCode` | `false` | 返回最终采用记录的代码、语言、编译错误和测试点摘要 |
| `withHistory` | `false` | 返回全部尝试历史;单次最多读取 5000 条记录 |
权限与限制:
- 原生教师和授权校区查看者可以读取授权范围内的成绩。
- 只有原生教师可以真正启用 `withCode`、`withHistory`;校区查看者传入后仍会被强制关闭。
- 单次最多读取 500 名报名学生。
- `historyTruncated=true` 表示提交历史达到 5000 条上限,调用方不得把响应描述为完整历史。
- 学生、班级、校区、记录 ID、代码和测试点均属于敏感教学数据。
```json
{
"course": { "title": "CSP-J 基础" },
"section": { "id": "<csid>", "title": "循环结构" },
"homeworks": [],
"students": [],
"campuses": [],
"campusGroups": [],
"historyTruncated": false,
"generatedAt": "2026-08-25T00:00:00.000Z"
}
```
每名学生的 `homeworks.*.problems` 可能包含:
- `firstAttempt`:首刷用时、得分、满分、状态、记录 ID 和提交时间;
- 当前最终 `status`、`score`、`maxScore`、`scorePercent`、`submitCount`、`bestRid`;
- `withCode=true` 时的 `code`、`lang`、`error`、`testCases`;
- `withHistory=true` 时的 `history`。
新工具优先使用下面的教学反馈 v1。只有需要代码或完整提交诊断时才调用本接口。
## 7. 教学反馈 API v1
基础路径:
```text
/course/api/v1/courses/:cid/sections/:csid/feedback
```
### 7.1 通用约定
- `schemaVersion` 当前为 `1.0`;v1 内只增加可选字段,不改变已有字段含义。
- 比率以百分数返回,例如 `72.5` 表示 `72.5%`。
- 没有有效分母时比率为 `null`,不会把“没有数据”伪装成 `0`。
- 时间使用 ISO 8601,用时使用毫秒。
- 缺失或无权查看的题目不进入题数、完成率和反馈统计。
- 单次最多分析 1000 名授权范围内的报名学生。`meta.enrollmentTruncated=true` 时不得表述为完整全班统计。
```json
{
"generatedAt": "2026-08-25T00:00:00.000Z",
"enrollmentLimit": 1000,
"enrollmentTruncated": false,
"analyzedStudentCount": 32,
"rateUnit": "percent",
"thresholds": {
"lowFirstAttemptRate": 60,
"recoveryGain": 30,
"repeatedUnsolvedAttempts": 3
}
}
```
### 7.2 章节反馈概览
```http
GET /course/api/v1/courses/:cid/sections/:csid/feedback/overview
GET /course/api/v1/courses/:cid/sections/:csid/feedback/overview?group=班级组名
```
主要返回:
- `summary`:学生数、开做数、提交数、完成人数、待关注人数、完成率、首刷得分率、最终得分率、平均尝试次数和平均首刷用时;
- `homeworks[].problems[]`:逐题开做率、提交率、通过率、平均尝试次数、首刷覆盖率和得分率;
- `groups`、`campuses`:当前账号可筛选的范围,不返回成员 UID 列表。
`group` 只能使用当前账号可查看的课程班级组名。
### 7.3 学生反馈列表
```http
GET /course/api/v1/courses/:cid/sections/:csid/feedback/students
```
| 参数 | 默认值 | 限制 | 说明 |
| --- | --- | --- | --- |
| `page` | `1` | 正整数 | 页码 |
| `limit` | `50` | 最大 `100` | 每页人数 |
| `group` | 空 | 当前账号授权组名 | 只统计该班级/组 |
| `signal` | 空 | 见标签表 | 只返回具有该标签的学生 |
| `q` | 空 | 最长 100 字符 | 按用户名或 UID 搜索 |
响应包含 `summary`、`homeworks`、`students`、`pagination`、`filters` 和 `meta`。列表中的 `homeworks` 只返回每类作业的题数与完成计数,不展开逐题证据。
### 7.4 单个学生反馈详情
```http
GET /course/api/v1/courses/:cid/sections/:csid/feedback/students/:uid
```
只有该学生已报名当前课程且位于调用者授权范围内时才返回。`student.homeworks.*.problems` 展开逐题首刷与当前最终结果,但仍不返回代码、完整历史或用户隐私字段。
若 Hydro 作业状态尚未异步写回但首刷快照已存在,`final.source` 为 `firstAttemptFallback`;正常读取作业状态时为 `contestStatus`。
### 7.5 确定性反馈标签
| code | 含义 | 判定口径 |
| --- | --- | --- |
| `NOT_STARTED` | 尚未开始 | 已布置题目但没有首刷或提交 |
| `INCOMPLETE` | 尚未完成 | 已开始但没有通过全部题目 |
| `LOW_FIRST_ATTEMPT` | 首刷掌握不足 | 有记录的首刷总得分率低于 60% |
| `REPEATED_UNSOLVED` | 反复尝试仍未通过 | 至少一题提交 3 次仍未通过 |
| `RECOVERED_AFTER_PRACTICE` | 订正后提升明显 | 同一批有首刷记录的题,最终得分率比首刷提高至少 30 个百分点 |
| `COMPLETED` | 已完成全部题目 | 所有有效题目均已通过 |
标签携带中文 `evidence`,只能作为教师复核线索,不能直接当作对学生的自动评价。
推荐调用顺序:
1. 请求 `overview`,确认统计范围、人数与 `enrollmentTruncated`。
2. 请求 `students?signal=...` 筛出需要关注或明显进步的学生。
3. 只对需要写反馈的学生请求单人详情。
4. AI 根据事实起草文字;最终反馈必须由教师审核。
## 8. 学生周报 API v1
```http
GET /course/api/v1/weekly-report/students?q=学生名&limit=20
GET /course/api/v1/weekly-report/students/:uid?start=2026-09-01&end=2026-09-08
```
搜索接口返回授权范围学生的 `uid`、名称、小组和可见课程数。详情接口返回指定自然周的课程、章节、作业、提交事实、首次提交通过率、课程首刷通过率和训练候选。
`start`、`end` 使用 `YYYY-MM-DD`,`end` 不包含在统计范围内,最长 31 天。`includeCode=true` 只允许原生教师,并会返回敏感源代码;普通数据访问不要开启。完整字段和统计口径见 [`API_WEEKLY_REPORT.md`](./API_WEEKLY_REPORT.md)。
## 9. 首刷开始(页面内部写接口)
```http
POST /course/:cid/s/:csid/practice/:tid/:pid/start
```
请求体为空。成功响应:
```json
{
"ok": true,
"problemUrl": "/p/1001?tid=<tid>",
"state": {}
}
```
业务拒绝通常仍返回 HTTP `200`:
```json
{
"ok": false,
"message": "请先完成前一类练习。"
}
```
该接口会参加关联作业并写入首刷进度,不是通用第三方 API。调用方必须同时检查 HTTP 状态与 `ok`,且不得用 GET、预加载或批量探测触发它。
服务端依次校验:登录、课程可见性、学生报名、章节归属、普通 homework、题目归属、三槽解锁和作业时间。教师仍需满足本人前一槽完成条件,但不受学生报名和课程开放时间限制。
## 10. 错误与完整性判断
| HTTP 状态 | 常见原因 |
| --- | --- |
| `400` | 参数格式错误、未知反馈标签、查询文本过长 |
| `403` | 未登录、没有成绩权限、越权访问课程、班级或学生 |
| `404` | 路由未部署,或课程、章节不存在,或章节不属于课程 |
调用方必须检查:
- HTTP 状态码和 `Content-Type`;
- 首刷接口的 `ok`;
- 反馈 v1 的 `meta.enrollmentTruncated`;
- 旧 `analysis` 的 `historyTruncated`。
仅返回 JSON 不代表业务成功,也不能用登录跳转或静态路由检查代替真实授权账号验收。
## 11. 版本与现网核验
- 本文档以当前工作区源码路由为准。
- 某个部署环境是否包含全部接口,应通过登录后的真实 HTTP 请求逐项核验。
- 2026-08-25 的历史 qonnwolf 核验结果见 [`API_CHECK_REPORT_2026-08-25.md`](./API_CHECK_REPORT_2026-08-25.md);每次发布以当次登录态验收结果为准。

View File

@@ -0,0 +1,12 @@
# ===== 课评项目凭据配置 =====
# 把本文件复制为 .env 后填写;.env 已被 .gitignore 排除,绝不提交到仓库。
# OJ 站点与账号(穹狼站)
OJ_BASE_URL=https://oj.qonnwolf.com
OJ_USERNAME=你的OJ用户名
OJ_PASSWORD=你的OJ密码
# 课评仓库 ClassFeedback(git.qonnwolf.com → 设置 → 应用 → 访问令牌,勾选 repository 读写)
GIT_USER=你的工号
GIT_TOKEN=你的访问令牌
GIT_REPO_URL=https://git.qonnwolf.com/你的工号/ClassFeedback

View File

@@ -0,0 +1,13 @@
# 凭据与环境变量(绝不提交)
.env
# 中间产物(抓取数据包)不入库
digest*.json
# 家长版 PDF 只留老师本地,不入库
*.pdf
# 系统杂项
Thumbs.db
.DS_Store
desktop.ini

View File

@@ -0,0 +1,39 @@
# ClassFeedback 课评仓库 · AI 协作须知
> 任何 AI agent(Claude Code / ZCode / 其他)进入本仓库,**先读完本文件再动手**。
## 本仓库是什么
老师的课评与学员档案仓库:AI 按班组从 OJ 拉取提交数据,逐生生成课堂反馈报告
(MD + HTML + PDF),并维护学生画像。
## 目录结构
```
.claude/memory/class/<班组>/summaries/ 班级汇总 / 群发文案
.claude/memory/class/<班组>/补课/<学生名>/feedback/ 外班来补课学生
.claude/memory/class/<班组>/<学生名>/ 学生课评(家长版报告 + feedback/ 内部正本 + profile.md 画像)
skills/class-feedback-report/ 课评技能(AI 按 SKILL.md 执行)
docs/ 机构规范文档
```
> 全部课评统一存 `.claude/memory/class/`,按「班组 → 学生 → feedback」组织;
> 学生画像 `profile.md` 随班级学生目录存放,不设独立 Students/ 根目录。
## 老师说这些话时该做什么
- 「引导我进行操作」「帮我处理本项目」→ 按
`skills/class-feedback-report/SKILL.md` 的**操作引导模式**九步清单执行
(仓库准备 → 环境 → 站点/账号 → 班级/花名册 → 生成 → git 同步 → 交付)。
- 「整理 XX 班的课堂反馈」「给某某出反馈报告」→ 同上,跳过已确认的步骤。
## 铁律
1. 家长版报告是**草稿**,教师审核措辞后才能发学生/家长;只写学习习惯,不写人身评价。
2. **先 OJ 拉班组花名册给老师确认,再逐生分析。**
3. 每个学生每次课五件事缺一不可:家长版报告 md/html、PDF(本地)、内部课评正本
`feedback/YYYYMMDD_课程编号-课次.md`(校宝核查口径)、画像更新 `<学生名>/profile.md`、
班级汇总 `summaries/`。
4. `*.pdf` 不入库(.gitignore 已排除);生成后 `git add` + commit + push。
5. 客观题不写提交历史,直接给错题 + 选项 + 考点分析;学生答案轨迹只与本人生成的单子呈现。
6. 仓库名统一 ClassFeedback;远端在 git.qonnwolf.com。

View File

@@ -0,0 +1,39 @@
# ClassFeedback 课评仓库 · AI 协作须知
> 任何 AI agent(Claude Code / ZCode / 其他)进入本仓库,**先读完本文件再动手**。
## 本仓库是什么
老师的课评与学员档案仓库:AI 按班组从 OJ 拉取提交数据,逐生生成课堂反馈报告
(MD + HTML + PDF),并维护学生画像。
## 目录结构
```
.claude/memory/class/<班组>/summaries/ 班级汇总 / 群发文案
.claude/memory/class/<班组>/补课/<学生名>/feedback/ 外班来补课学生
.claude/memory/class/<班组>/<学生名>/ 学生课评(家长版报告 + feedback/ 内部正本 + profile.md 画像)
skills/class-feedback-report/ 课评技能(AI 按 SKILL.md 执行)
docs/ 机构规范文档
```
> 全部课评统一存 `.claude/memory/class/`,按「班组 → 学生 → feedback」组织;
> 学生画像 `profile.md` 随班级学生目录存放,不设独立 Students/ 根目录。
## 老师说这些话时该做什么
- 「引导我进行操作」「帮我处理本项目」→ 按
`skills/class-feedback-report/SKILL.md` 的**操作引导模式**九步清单执行
(仓库准备 → 环境 → 站点/账号 → 班级/花名册 → 生成 → git 同步 → 交付)。
- 「整理 XX 班的课堂反馈」「给某某出反馈报告」→ 同上,跳过已确认的步骤。
## 铁律
1. 家长版报告是**草稿**,教师审核措辞后才能发学生/家长;只写学习习惯,不写人身评价。
2. **先 OJ 拉班组花名册给老师确认,再逐生分析。**
3. 每个学生每次课五件事缺一不可:家长版报告 md/html、PDF(本地)、内部课评正本
`feedback/YYYYMMDD_课程编号-课次.md`(校宝核查口径)、画像更新 `<学生名>/profile.md`、
班级汇总 `summaries/`。
4. `*.pdf` 不入库(.gitignore 已排除);生成后 `git add` + commit + push。
5. 客观题不写提交历史,直接给错题 + 选项 + 考点分析;学生答案轨迹只与本人生成的单子呈现。
6. 仓库名统一 ClassFeedback;远端在 git.qonnwolf.com。

View File

@@ -0,0 +1,194 @@
# 课评写入决策规则
## 场景总览
| 场景 | 说明 | 写入位置 |
|------|------|---------|
| 正常上课 | 固定班级固定时间,学生正常到课 | 本班学生 feedback/ |
| 正常请假 | 固定班级固定时间,学生请假 | 本班学生 feedback/(请假) |
| 外班来补课 | 其他班的学生来本班上课 | 本班 补课/学生名/feedback/ |
| 本班临时调时间 | 固定班级但本次课改了时间 | 本班学生 feedback/,课评中注明实际时间 |
| 临时凑班 | 不属于任何固定班级的一次性排课 | 建临时班级目录或按补课处理 |
## 场景1:本班正常到课
- 位置:`班级目录/学生名/feedback/YYYYMMDD_课程编号-课次.md`
- 操作:在学生 feedback 目录下新增课评文件
- 学生目录已存在 → 直接写
- 学生目录不存在 → 先创建学生目录和 feedback 子目录
## 场景2:本班请假
- 位置:`班级目录/学生名/feedback/YYYYMMDD_课程编号-课次(请假).md`
- 操作:在学生 feedback 目录下新增请假记录文件
- 请假记录也要写,保证每位学生每次课都有对应文件
## 场景3:外班来补课
- 位置:`班级目录/补课/学生名/feedback/YYYYMMDD_课程编号-课次.md`
- 操作:
1. 检查 `班级目录/补课/学生名/` 是否已存在
2. 已存在 → 直接在 feedback 下新增课评文件
3. 不存在 → 创建 `补课/学生名/feedback/` 目录,再写课评
- 补课学生不需要 profile.md
## 场景4:本班临时调时间
**核心原则:写回原班级,不新建目录。** 班级目录名中的时间是常规标签,不是精确到每次课的约束。
### 老师操作流程
1. 确认是哪个固定班级的课(比如 CSP01六六周六1045)
2. 正常在该班级目录下为每个学生写课评
3. 课评文件中**加一行注明实际时间**:
```markdown
# 课程名称:CSP01-10 变量与运算
**授课日期**: 2026-05-10
**实际时间**: 16:00-18:00(临时调整,原定 10:45-12:45)
**课评内容**:
...
```
### 三种学生的处理
| 学生状态 | 操作 |
|---------|------|
| 到课 | 和场景1一样,在学生 feedback/ 下写课评,注明实际时间 |
| 请假 | 和场景2一样,写请假记录 |
| 外班来补课 | 和场景3一样,在补课/ 下写课评 |
### 为什么不新建临时目录
1. 目录会越积越多,长期仓库很乱
2. 学生课评会被拆到两个目录,历史不连续
3. 老师不需要纠结写哪个目录,班级目录就那几个
4. 课评文件名已有日期精确标识,目录名只是标签
## 场景5:临时凑班
不属于任何固定班级的一次性排课(如集训、体验课等):
- 如果有对应的固定班级 → 按场景4处理,写回固定班级
- 如果完全无对应 → 建临时班级目录(如 `CSP01六六集训0510`),按场景1/2/3处理
- 临时班级目录用完后不删除,保留历史记录
## 查找课评的反向逻辑
统计课评完成度时,只在排课老师T的仓库中查找(谁上课谁写课评),从最精确到最模糊逐级查找,每一级找到即停:
```
校宝记录:学生S 在日期D 到课,排课老师T,课程编号B,上课时间TIME
第1级(精确匹配):课程编号B + 时间TIME + 老师T
1a. 在T仓库找 目录名含B 且 含TIME 的班级目录
→ 在该目录的 S/feedback/ 中找日期D的课评
→ 找到 → 结束
1b. 未找到 → 在该目录的 补课/S/feedback/ 中找日期D的课评
→ 找到 → 结束
→ 未找到 → 进入第2级
第2级(放宽时间):课程编号B + 老师T,时间不限
2a. 在T仓库找 目录名含B 的所有其他班级目录(排除第1级已查的)
→ 排除非常规班(目录名含"集训"、"体验"、"临时"等)
→ 在这些目录的 S/feedback/ 中找日期D的课评
→ 找到 → 结束
2b. 未找到 → 在这些目录的 补课/S/feedback/ 中找日期D的课评
→ 找到 → 结束
→ 未找到 → 标记缺失
```
**核心原则:谁上课谁写课评,只查排课老师的仓库。** 不需要跨老师查找,别的老师上的课不会出现在自己仓库里。
**覆盖的4种情况**:
| 查找 | 含义 |
|------|------|
| 1a. 精确班级学生目录 | 固定班固定时间,本班学生写的课评 |
| 1b. 精确班级补课目录 | 固定班固定时间,补课学生写的课评 |
| 2a. 同阶段不同时间学生目录 | 临时调了时间,写在了另一个同编号班级目录下 |
| 2b. 同阶段不同时间补课目录 | 临时调了时间,补课学生的课评在另一个同编号班级的补课目录 |
**关键过滤规则**:
- **全程限定课程编号B**:缺B补B,不跨课程编号
- 第2级排除"集训/体验/临时"等非常规班目录名
- 每一步找到就停,不重复计数
## 关键原则
1. **以学生为中心**:查找时先找学生名,再检查日期
2. **课程编号是全程硬约束**:只在课程编号B范围内查找,缺B补B
3. **谁上课谁写课评**:只查排课老师T的仓库,不跨老师
4. **每位学生每次课必须有文件**:到课写课评,请假写请假记录,不能遗漏
5. **补课学生按实际补课班级归类**:去哪个班补课,课评就写在那个班的补课目录下
6. **补课目录可复用**:同一个补课学生多次来同一个班补课,目录已存在就不再创建
7. **临时调时间写回原班级**:不新建目录,课评内容中注明实际时间即可
## 两种查找模式
老师仓库是独立的,不同场景需要不同的查找范围:
| 目的 | 查找范围 | 约束 |
|------|---------|------|
| 课评完成度统计 | 只查排课老师T的仓库 | 限定课程编号B,逐级查找 |
| 写阶段总结 | 遍历所有老师仓库(15个) | 不限课程编号,按学生名收集全部课评,按时间排序 |
**阶段总结查找逻辑**:
```
目标:为学生S 生成阶段总结
1. 遍历所有老师仓库的 .claude/memory/class/ 下所有班级目录
2. 在每个班级目录中查找 S/feedback/ 和 补课/S/feedback/
3. 收集所有 YYYYMMDD_*.md 文件
4. 按日期排序,汇总输出
```
学生可能换班换老师(如CSP01升CSP02换了老师),课评分散在多个仓库,只能全扫。
## 学生索引机制
### 目的
教学督导(可读所有仓库)每周定时扫描15个老师仓库,生成统一的学生索引文件,避免后续查询反复全扫。
### 索引结构
```
.claude/memory/student_index/
├── 刘毅潇.md
├── 张祺琪.md
└── ...
```
每个索引文件:
```markdown
# 刘毅潇
## 当前班级
- CSP05克力周六1600
## 课评记录
| 日期 | 老师 | 班级 | 路径 |
|------|------|------|------|
| 2026-05-10 | 克力 | CSP05克力周六1600 | keli_ClassFeedback/.../feedback/20260510_CSP05-10.md |
| 2026-05-03 | 克力 | CSP05克力周六1600 | keli_ClassFeedback/.../feedback/20260503_CSP05-09.md |
| 2026-04-19 | 六六 | CSP01六六周六1400 | liuliu_ClassFeedback/.../feedback/20260419_CSP01-08.md |
```
### 更新方式
- **定时扫描**:每周执行课评整理时自动扫描所有仓库,更新索引
- **增量更新**:只追加新发现的课评,不删除历史记录
- **升班/换老师**:索引中追加新班级记录,"当前班级"取最新一条
### 索引的好处
1. **老师仓库不动**:写入逻辑完全不变
2. **课评完成度统计**:读索引即可,不用全扫15个仓库
3. **阶段总结**:直接读索引文件,按日期排序就完事
4. **升班/换老师**:索引里追加记录,学生历史自然连续
5. **统一视图**:教学督导和所有协作者都能看到学生完整课评轨迹

View File

@@ -0,0 +1,397 @@
---
name: keping-dir-standardize
description: 将课评目录迁移到标准结构。当用户说"规范目录"、"整理目录"、"目录规范化"、"初始化目录"、"初始化项目"时触发。自动识别当前目录范式,创建标准 .claude/memory/class/ 结构,迁移现有数据(不删除原文件),补建缺失目录,配置课程大纲同步。如果是全新仓库,参考标准仓库创建项目。
---
# 课评目录规范化 Skill
## 功能概述
将老师仓库中的课评数据迁移到统一标准目录结构。
- 自动识别 4 种现有目录范式
- 创建标准 `.claude/memory/class/` 结构
- 迁移现有课评和画像文件(移动,不删除)
- 补建缺失的 `feedback/`、`profile.md`、`summary/`、`补课/` 目录
- 配置课程大纲同步(从独立仓库同步,不提交到本仓库)
- 支持"全新项目"场景(参考标准仓库创建)
- 生成迁移报告
## 触发条件
用户说出以下任意表达时触发:
- "规范目录"
- "整理目录"
- "目录规范化"
- "初始化目录"
- "初始化项目"
- "标准化目录"
- "迁移目录"
## 安全原则
1. **绝不删除文件** — 只移动(mv)到新位置,原位置的文件迁移后不再保留副本
2. **绝不修改文件内容** — 只改变文件路径和文件名
3. **先报告再执行** — 必须先向用户展示迁移计划,确认后再执行
4. **遇到不确定的情况就停下问** — 不要猜测
## 参考仓库(标准范例)
**克力老师的仓库**是最完整的标准范例:
`https://git.qonnwolf.com/keli/ClassFeedback`
新老师或需要补充项目的老师,克隆这个仓库来参考目录结构和配置,但**不是照抄**——只参照结构,数据用自己的。
## 目标结构
```
.claude/
├── memory/
│ ├── class/ # 【核心 - 所有班级课评数据】
│ │ ├── CSP05克力周六1600/ # 班级名 = 课程编号+老师+星期+时间
│ │ │ ├── summaries/ # 班级总结/群发文案
│ │ │ │ ├── YYYYMMDD_CSP05-07_班级反馈.md
│ │ │ │ └── YYYYMMDD_CSP05-07_微信群.txt
│ │ │ ├── 张三/ # 本班学生
│ │ │ │ ├── feedback/ # 个人课评目录
│ │ │ │ │ ├── YYYYMMDD_CSP05-07.md # 正常课评
│ │ │ │ │ ├── YYYYMMDD_CSP05-07(请假).md # 请假记录
│ │ │ │ │ ├── YYYYMMDD_CSP05-07(补课-去AI03茄子周六1900).md # 补课追踪
│ │ │ │ │ └── ...
│ │ │ │ ├── profile.md # 学生画像
│ │ │ │ └── summary/ # 阶段性总结
│ │ │ │ └── 2026-05_月度总结.md
│ │ │ ├── 李四/
│ │ │ │ └── ...
│ │ │ └── 补课/ # 补课学生专用目录
│ │ │ └── 王五/ # 来自其他班级的补课学生
│ │ │ └── feedback/
│ │ │ └── YYYYMMDD_CSP05-07.md
│ │ ├── AICODE03菠萝周六1600/
│ │ │ └── ...(结构同上)
│ │ ├── SPIKE02小Q周六1400/
│ │ │ └── ...(结构同上)
│ │ └── KITTEN04洋芋周六1600/
│ │ └── ...(结构同上)
│ ├── lesson/ # 课程大纲(从独立仓库同步,不提交)
│ │ ├── README.md
│ │ ├── CSP/ ← 信息学奥赛课
│ │ │ ├── CSP01/
│ │ │ └── ...
│ │ ├── AICODE/ ← AI人工智能课
│ │ │ ├── AICODE01/
│ │ │ └── ...
│ │ ├── SPIKE/ ← 乐高搭建课
│ │ ├── KITTEN/ ← 图形化编程课
│ │ ├── VEXIQ/ ← VEX机器人课
│ │ └── GESP/ ← 竞赛项目课
│ └── oj/ # OJ数据分析(仅 CSP 班级,可选)
│ └── analysis/
└── skills/ # 技能脚本(可选)
```
### 班级命名规则
格式:`课程编号+老师+星期+时间`
| 类目 | 前缀 | 示例班级名 |
|------|------|-----------|
| 信息学奥赛课 | CSP | `CSP05克力周六1600`、`CSP01六六周六1045` |
| AI人工智能课 | AICODE、AIMAKE | `AICODE03菠萝周六1600`、`AIMAKE02东东周五1630` |
| 乐高搭建课 | SPIKE、WEDO、FAXIAN 等 | `SPIKE02菠萝周六1400`、`WEDO01小Q周六1030` |
| 图形化编程课 | KITTEN、SCRATCH | `KITTEN04洋芋周六1600`、`SCRATCH03橙子周五1900` |
| VEX机器人课 | VEXIQ、VEXGO 等 | `VEXIQ01菠萝周六1400` |
| 竞赛项目课 | GESP、ENJOYAI 等 | `GESP03克力周日0900`、`ENJOYAI01东东周六1400` |
### 课程类目与编号前缀
用于从课程编号前缀识别课程类目,规范班级命名和分类:
| 类目 | 课程前缀(不含数字) |
|------|---------------------|
| 乐高搭建课 | YISHI、HUOCHE、MATATA、FAXIAN、FAMING、WEDO、ROCKET、SPIKE |
| 图形化编程课 | KITTEN、SCRATCH |
| VEX机器人课 | VEXGO、VEXPRE、VEXIQ、V5RC |
| AI人工智能课 | AICODE、AIMAKE |
| 信息学奥赛课 | CSP |
| 竞赛项目课 | ENJOYAI、BOTBALL、ROBORAVE、GOC、GESP、CSP-J、NCT、CSP-S、INFOR、LABOR、FSHH |
| 杂项类目课 | XITI、CUSTOM、FESTIVAL |
### 考勤状态说明
每次课后,每位学生必须有且仅有一条 feedback 文件:
| 状态 | 文件名 | 说明 |
|------|--------|------|
| 正常 | `YYYYMMDD_课程编号.md` | 完整课评 |
| 请假 | `YYYYMMDD_课程编号(请假).md` | 简要记录 |
| 补课 | `YYYYMMDD_课程编号(补课).md` | 记录补课 |
### 补课双向追踪
**1) 接收补课(外班学生来本班)**:
- 存放在 `补课/学生名/feedback/YYYYMMDD_课程编号.md`
- 不建 `profile.md` 和 `summary/`
- 课评开头注明来源:`(补课,来自 CSP05克力周六1600)`
**2) 外出补课(本班学生去别班)**:
- 存放在学生自己的 `feedback/YYYYMMDD_课程编号(补课).md`
- AI 读取后知道该学生当天的课评在补课班级
### 课程大纲同步
`.claude/memory/lesson/` 从独立仓库同步,**不提交到老师自己的仓库**:
| 目录 | 类目 | 来源 |
|------|------|------|
| `lesson/CSP/` | 信息学奥赛课 | `https://git.qonnwolf.com/keli/CSP2026` |
| `lesson/AICODE/` | AI人工智能课 | `https://git.qonnwolf.com/keli/AICODE2026` |
| `lesson/GESP/` | 竞赛项目课 | 按实际仓库配置 |
| 其他前缀目录 | 对应类目 | 按实际仓库配置 |
需在 `.gitignore` 中添加:`.claude/memory/lesson/`
## 执行流程
### 场景判断
先判断属于哪种场景:
| 场景 | 判断条件 | 处理方式 |
|------|---------|---------|
| **全新项目** | 没有 `.claude/memory/class/` 或任何课评数据 | 参考标准仓库创建 |
| **已有项目** | 有课评数据但结构不标准 | 识别范式后迁移 |
### ===== 场景一:全新项目 =====
适用于:刚加入协作的老师,或者还没有建立 ClassFeedback 仓库的老师。
#### 第 1 步:确认老师信息
向用户询问:
1. 老师昵称/真名
2. 手机号(用于远端仓库地址)
3. 负责的班级列表(课程编号+上课时间)
4. 每个班级的学生名单
#### 第 2 步:参考标准仓库创建结构
克隆标准仓库作为参考:
```bash
git clone https://git.qonnwolf.com/keli/ClassFeedback /tmp/standard-ref
```
**从标准仓库中参考的部分**(只参考结构,不复制数据):
- `.claude/memory/class/` 的目录组织方式
- `.claude/memory/class/班级/学生/feedback/` + `profile.md` + `summary/`
- `.claude/memory/class/班级/summaries/` 班级总结目录
- `.claude/memory/class/班级/补课/` 补课目录
- `.claude/memory/lesson/README.md` 大纲来源说明
- `.gitignore` 中的忽略规则
**不需要参考的部分**(每个老师自己维护):
- `.claude/memory/class/` 下的实际学生数据
- `.claude/memory/oj/` OJ 数据(仅 CSP 老师需要)
- `.claude/rules/` 规则文件(各老师可能有不同风格)
- `.claude/skills/` 技能文件
#### 第 3 步:创建目录结构
```bash
# 为每个班级创建结构(示例覆盖不同课程类目)
for class in "CSP05克力周六1600" "AICODE03菠萝周六1600" "SPIKE02小Q周六1400" "KITTEN04洋芋周六1600"; do
mkdir -p ".claude/memory/class/${class}/summaries"
mkdir -p ".claude/memory/class/${class}/补课"
# 为每个学生创建结构
for student in 张三 李四 王五; do
mkdir -p ".claude/memory/class/${class}/${student}/feedback"
mkdir -p ".claude/memory/class/${class}/${student}/summary"
# 创建画像模板
cp profile_template.md ".claude/memory/class/${class}/${student}/profile.md"
done
done
# 创建课程大纲目录(按实际需要的课程前缀创建)
mkdir -p ".claude/memory/lesson/CSP"
mkdir -p ".claude/memory/lesson/AICODE"
mkdir -p ".claude/memory/lesson/GESP"
# 其他课程前缀按需创建:SPIKE、KITTEN、VEXIQ 等
```
#### 第 4 步:创建基础文件
1. **创建 `.gitignore`**:
```gitignore
.claude/
!.claude/memory/
!.claude/memory/class/
!.claude/memory/lesson/README.md
.claude/memory/lesson/*/
```
2. **创建 lesson/README.md**(记录大纲来源)
3. **同步课程大纲**(如果网络可用)
4. **创建 CLAUDE.md**(可选,记录本仓库的基本信息)
### ===== 场景二:已有项目迁移 =====
#### 第 1 步:识别当前目录范式
扫描当前仓库,判断属于哪种范式:
| 范式 | 特征 |
|------|------|
| **A: 标准型** | `.claude/memory/class/` 下有班级目录 |
| **B: 三件套型** | `memory/student/` 或 `memory/学生/`,每学生"画像+素材+历史课评" |
| **C: 分离式** | 课评在 `.claude/课评/`,画像在 `.claude/memory/用户画像/` |
| **D: 散落型** | `课堂记录/`、`ClassFeedback/` 或根目录级 |
**识别方法**(按优先级检测):
1. 存在 `.claude/memory/class/` → 范式 A
2. 存在 `memory/student/` 或 `memory/学生/` → 范式 B
3. 存在 `.claude/课评/` → 范式 C
4. 存在 `课堂记录/` 或 `ClassFeedback/` → 范式 D
5. 以上都不存在 → 按场景一(全新项目)处理
#### 第 2 步:收集班级和学生信息
**从目录结构中提取**:
- 扫描现有目录,列出所有班级名和学生名
**从 CLAUDE.md 或 README.md 补充**:
- 读取本仓库的 CLAUDE.md,查找班级/课程信息
**与用户确认**:
- 如果班级名缺少"星期+时间"(如只有 `AICODE03班`),询问用户补全
- 格式参考:`CSP05克力周六1600`
#### 第 3 步:生成迁移计划
向用户展示迁移计划,包含:
1. 范式识别结果
2. 将创建的目录结构预览
3. 文件迁移清单(原路径 → 新路径)
4. 不迁移的文件(保留原位)
**必须等用户确认后再执行。**
#### 第 4 步:执行迁移
用户确认后,按计划执行:
**范式 A**(已接近标准,微调即可):
- 重命名班级目录(如果名称不规范)
- 确保每个学生有 feedback/、profile.md、summary/
- 创建 summaries/ 和 补课/ 目录
**范式 B**(三件套型):
- 创建标准 `.claude/memory/class/` 结构
- `用户画像.md` → `profile.md`
- `历史课评记录.md` → `summary/历史课评记录.md`
- `成长素材.md` → `summary/成长素材.md`
- 单次课程记录 → `feedback/YYYYMMDD_课程编号.md`
**范式 C**(分离式):
- 创建标准结构
- 从集中画像目录迁移到各班级下
- 课评文件迁移到 feedback/
**范式 D**(散落型):
- 创建标准结构
- 全班课评汇总 → `summaries/`
- 从校宝 API 或人员名单获取学生列表,创建个人目录
#### 第 5 步:补建缺失内容
1. **profile.md 模板** — 对没有画像的学生创建空模板
2. **补课目录** — 每个班级下创建 `补课/`
3. **summaries 目录** — 每个班级下确保有 `summaries/`
#### 第 6 步:配置课程大纲同步
1. 创建 `lesson/` 目录和子目录
2. 创建 `lesson/README.md`(记录来源仓库)
3. 更新 `.gitignore`,添加 `.claude/memory/lesson/*/`(忽略所有课程大纲子目录)
4. 如果网络可用,克隆并同步大纲
#### 第 7 步:更新 CLAUDE.md
更新仓库的 CLAUDE.md(如果存在):
- 更新目录结构说明
- 添加课程大纲同步说明
- 添加考勤状态记录说明(请假/补课)
#### 第 8 步:生成迁移报告
输出迁移报告,包含:
- 仓库信息(老师、范式变化)
- 迁移统计(班级数、学生数、文件数)
- 班级结构表
- 后续建议
## profile.md 空模板
```markdown
# {学生姓名} - 画像
## 基本信息
- 班级:{班级名}
- 入班时间:
- 年龄/年级:
## 性格特点
(待观察填写)
## 学习风格
(待观察填写)
## 课堂表现
(待观察填写)
## 编程能力
- 理解力:
- 动手能力:
- 创造力:
- 调试能力:
## 家长沟通
(待记录)
```
## 请假记录模板
```markdown
# 请假记录
**日期**: {YYYY-MM-DD}
**课程**: {课程编号}
**学生**: {学生姓名}
**状态**: 请假
**原因**: (如有)
```
## 补课追踪模板(原班级侧)
```markdown
# 补课记录
**日期**: {YYYY-MM-DD}
**原课程**: {原课程编号}
**学生**: {学生姓名}
**状态**: 补课
**补课班级**: {目标班级名}
**补课老师**: {目标老师}
```
## 注意事项
1. **处理所有课程类型** — 按课程类目表覆盖全部前缀(乐高搭建、图形化编程、VEX机器人、AI人工智能、信息学奥赛、竞赛项目、杂项),全部统一规范
2. **CSP 特殊处理** — CSP 班级可能有 `oj/` 数据目录,保持不动
3. **文件名中的课程编号** — 统一用 `课程编号-课次` 格式(如 `CSP05-07`、`AICODE03-02`、`SPIKE02-05`、`KITTEN04-03`)
4. **补课学生** — 在补课班级只有 feedback/,不建 profile.md 和 summary/
5. **全班课评** — 范式 D 的全班课评放到 summaries/ 下,不强行拆分为个人课评
6. **不确定就问** — 如果班级时间信息缺失、学生归属不明,停下来问用户
7. **不碰 .claude/rules/ 和 .claude/skills/** — 这些是配置文件,不在迁移范围内
8. **lesson 不提交** — 课程大纲目录加入 .gitignore,大纲从独立仓库同步

View File

@@ -0,0 +1,211 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- 样式参考样例:AI 生成报告时,完整复用本文件的 CSS、卡片结构与文案风格,仅替换内容 -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>学习反馈单 · 王小明</title>
<style>
:root{
--ink:#334155; --strong:#1e293b; --sub:#64748b;
--paper:#faf8f4; --card:#ffffff; --line:#e8e4dc;
--green:#059669; --green-soft:#ecfdf5; --green-line:#a7f3d0;
--amber:#b45309; --amber-soft:#fffbeb; --amber-line:#fde68a;
--orange:#c2410c; --orange-soft:#fff7ed;
--blue:#2563eb; --blue-soft:#eff6ff;
--violet:#6d28d9; --violet-soft:#f5f3ff;
}
*{box-sizing:border-box;margin:0;padding:0}
body{
font-family:"PingFang SC","Microsoft YaHei",system-ui,sans-serif;
color:var(--ink); background:var(--paper);
line-height:1.95; font-size:16.5px; padding:20px 12px 40px;
}
.wrap{max-width:820px;margin:0 auto}
.draft{
text-align:center;color:#a8a29e;font-size:12px;margin-bottom:10px;
}
.hero{
background:linear-gradient(135deg,#0f766e 0%,#0e7490 55%,#4f46e5 130%);
color:#fff;border-radius:20px;padding:30px 30px 24px;margin-bottom:18px;
}
.hero .hello{font-size:14px;opacity:.85;letter-spacing:2px}
.hero h1{font-size:27px;font-weight:700;margin-top:2px}
.hero .sub{opacity:.9;font-size:14px;margin-top:6px}
.chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:16px}
.chip{
background:rgba(255,255,255,.15);border:1px solid rgba(255,255,255,.28);
border-radius:999px;padding:4px 14px;font-size:13.5px;
}
.chip b{font-size:14.5px}
.card{
background:var(--card);border:1px solid var(--line);border-radius:16px;
padding:24px 26px;margin-bottom:18px;
}
.card h2{font-size:20px;color:var(--strong);margin-bottom:14px}
.praise{background:var(--green-soft);border:1.5px solid var(--green-line)}
.praise h2{color:var(--green)}
.praise li{margin:8px 0 8px 18px}
.praise b{color:var(--green)}
.bars{display:flex;flex-direction:column;gap:12px;margin-top:4px}
.bar-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.bar-label{flex:none;width:88px;font-size:15px;color:var(--strong)}
.bar{flex:1;min-width:180px;height:14px;background:#eee9e0;border-radius:999px;overflow:hidden}
.bar i{display:block;height:100%;border-radius:999px}
.bar-num{flex:none;width:56px;font-size:14.5px;color:var(--sub);text-align:right}
.prob{
border:1px solid var(--line);border-radius:14px;
padding:18px 20px;margin:14px 0;background:#fffdf9;
}
.prob .phead{display:flex;justify-content:space-between;align-items:baseline;flex-wrap:wrap;gap:6px}
.prob .pname{font-weight:700;font-size:16.5px;color:var(--strong)}
.prob .pmeta{color:var(--sub);font-size:13px}
.tl{list-style:none;margin-top:10px}
.tl li{
display:flex;gap:10px;align-items:flex-start;
padding:8px 0;border-top:1px dashed var(--line);font-size:15.5px;
}
.tl li:first-child{border-top:none}
.pill{
flex:none;min-width:104px;text-align:center;border-radius:999px;
font-size:13px;font-weight:600;padding:3px 10px;margin-top:3px;white-space:nowrap;
}
.pill.ce{background:var(--amber-soft);color:var(--amber);border:1px solid var(--amber-line)}
.pill.wa{background:var(--orange-soft);color:var(--orange);border:1px solid #fed7aa}
.pill.tle{background:#fef2f2;color:#b91c1c;border:1px solid #fecaca}
.pill.ac{background:var(--green-soft);color:var(--green);border:1px solid var(--green-line)}
.note{
background:var(--blue-soft);border-left:4px solid var(--blue);
border-radius:0 12px 12px 0;padding:12px 16px;margin-top:12px;
font-size:14.5px;color:#1e40af;
}
.obj-intro{
background:var(--violet-soft);border:1px solid #ddd6fe;border-radius:12px;
padding:12px 16px;font-size:15px;color:#5b21b6;margin-bottom:16px;
}
.summary p{margin:9px 0;font-size:16px}
.footer{
text-align:center;color:#a8a29e;font-size:12.5px;margin-top:8px;line-height:2;
}
@media (max-width:640px){
body{font-size:15.5px;padding:12px 8px 30px}
.card{padding:18px}
.hero{padding:22px 20px}
.hero h1{font-size:23px}
.bar-label{width:74px;font-size:14px}
.tl li{flex-direction:column;gap:4px}
.pill{min-width:0;align-self:flex-start}
}
@media print{
body{background:#fff;padding:0;font-size:14px;-webkit-print-color-adjust:exact;print-color-adjust:exact}
.card,.hero{box-shadow:none;border-radius:10px;break-inside:avoid}
.hero{-webkit-print-color-adjust:exact;print-color-adjust:exact}
.export-btn{display:none}
.draft{display:none}
}
.export-btn{
position:fixed;right:18px;bottom:20px;z-index:9;
border:none;background:#0f766e;color:#fff;cursor:pointer;
border-radius:999px;padding:11px 20px;font-size:15px;font-family:inherit;
box-shadow:0 6px 18px rgba(15,118,110,.35);
}
.export-btn:hover{background:#115e59}
.export-btn:active{transform:scale(.97)}
</style>
</head>
<body>
<div class="wrap">
<div class="draft">教师审核稿 · 审阅后转发家长</div>
<button class="export-btn" onclick="window.print()">🖨️ 导出 PDF</button>
<div class="hero">
<div class="hello">学 习 反 馈 单</div>
<h1>王小明 同学 · 克力周日0830CSP02-01「基础回顾」</h1>
<div class="sub">克力周日0830CSP02 班 | 2026-09-10 | 本讲共 17 题(课堂 7 + 作业 3 + 拓展 7)</div>
<div class="chips">
<div class="chip">🎉 动过的 3 道题 <b>全部订正通过</b></div>
<div class="chip">提交 <b>9</b> 次 · <b>零放弃</b></div>
<div class="chip">解题思路 <b>全部正确</b></div>
</div>
</div>
<div class="card praise">
<h2>🌟 老师的表扬</h2>
<ul>
<li><b>三道题最终全部订正通过,9 次提交没有一次放弃</b>——这股不搞定不罢休的劲头,非常了不起!</li>
<li><b>看得懂编译器的报错</b>:每次报错后都朝着正确的方向修,思路一步都没乱。</li>
<li><b>死循环是自己找到的</b>:把 <code>1&lt;=T</code> 改成 <code>i&lt;=T</code>,说明循环三要素真的理解了。</li>
<li>三道题的<b>解题思路最终都是对的</b>——差的只是「把代码写规范」这一层,这层最容易补!</li>
</ul>
</div>
<div class="card">
<h2>📊 本讲完成情况</h2>
<div class="bars">
<div class="bar-row"><span class="bar-label">课堂练习</span><span class="bar"><i style="width:43%;background:linear-gradient(90deg,#fbbf24,#f59e0b)"></i></span><span class="bar-num">3/7</span></div>
<div class="bar-row"><span class="bar-label">课后作业</span><span class="bar"><i style="width:0%;background:#cbd5e1"></i></span><span class="bar-num">0/3</span></div>
<div class="bar-row"><span class="bar-label">拓展练习</span><span class="bar"><i style="width:0%;background:#cbd5e1"></i></span><span class="bar-num">0/7</span></div>
</div>
</div>
<div class="card">
<h2>💻 编程题:每一次提交都看过了</h2>
<div class="prob">
<div class="phead"><span class="pname">🛍️ 商店折扣</span><span class="pmeta">4 次提交</span></div>
<ul class="tl">
<li><span class="pill ce">✍️ 第 1 次</span><span>变量没有定义——x、y、n、p 直接拿来用,忘了先声明</span></li>
<li><span class="pill ce">✍️ 第 2 次</span><span>补了一半——x y n p 都声明了,但 m1 还是漏了</span></li>
<li><span class="pill ce">✍️ 第 3 次</span><span>变量重复定义——补 m1 的时候没注意 m2 之前已经声明过了</span></li>
<li><span class="pill ac">🎉 第 4 次</span><span><b>通过!</b>声明整理干净,逻辑一点没改就对了</span></li>
</ul>
<div class="note">📌 三次编译错误其实都是同一件事——「<b>先声明、再使用</b>」。第四次你把声明排得整整齐齐,代码马上就通了,说明你完全有能力一次写好!</div>
</div>
<div class="prob">
<div class="phead"><span class="pname">🚀 小杨的爱心快递</span><span class="pmeta">2 次提交</span></div>
<ul class="tl">
<li><span class="pill ce">✍️ 第 1 次</span><span>语法混入了其他写法——cin V 少了 &gt;&gt;、把 if 当成公式赋值、用了 C++ 里不存在的 print()</span></li>
<li><span class="pill ac">🎉 第 2 次</span><span><b>通过!</b>一次把三处全部改对</span></li>
</ul>
<div class="note">📌 第一次的写法像是把解题思路直接「翻译」成了代码——<b>思路其实是对的!</b>第二次一口气改对三处,理解力没问题。接下来练的就是「落笔就用 C++ 的标准写法」。</div>
</div>
<div class="prob">
<div class="phead"><span class="pname">🔋 手机电量显示</span><span class="pmeta">3 次提交</span></div>
<ul class="tl">
<li><span class="pill ce">✍️ 第 1 次</span><span>函数名写错——又用了 print()(C++ 里是 cout)</span></li>
<li><span class="pill tle">⏱️ 第 2 次</span><span>运行超时——循环条件写成 1 &lt;= T(永远成立,程序停不下来),应该是 i &lt;= T</span></li>
<li><span class="pill ac">🎉 第 3 次</span><span><b>通过!</b>循环条件和输出全部修正</span></li>
</ul>
<div class="note">📌 超时不可怕,它说明程序已经在「跑」了——而且是你自己把 1&lt;=T 找出来改成 i&lt;=T 的,<b>循环三要素你是懂的</b>,下次落笔前默念一遍就行。</div>
</div>
<div class="prob">
<div class="phead"><span class="pname">📝 选择题 / 判断题</span><span class="pmeta">还没开始</span></div>
<ul class="tl">
<li><span class="pill tle">小提醒</span><span>本节课的客观题还没有开始做。<b>不着急,先把编程补上就是很大的进步。</b>做到的时候记得:错题直接看讲解,不要反复试答案。</span></li>
</ul>
</div>
</div>
<div class="card summary">
<h2>📖 老师的整体评价</h2>
<p>王小明同学本节课可以概括为:<b>逻辑没问题,规范要跟上</b>。</p>
<p>💪 <b>值得肯定的</b>:三道题 9 次提交全部坚持订正到通过;报错读得懂、修改方向一直是对的;三题的解题逻辑最终全对——「会不会」的问题不存在,纯粹是「怎么把代码写规范」的问题。</p>
<p>🔧 <b>接下来要养的三个小习惯</b>:</p>
<p style="margin:6px 0 6px 12px">① <b>先编译、后提交</b>——编译器说 0 error 才点提交,这一条就能把本次 6 次错误全部消灭;</p>
<p style="margin:6px 0 6px 12px">② <b>动笔前先列变量清单</b>——名字、类型、初值三样写齐再写逻辑(漏声明、重复声明都是这么防住的);</p>
<p style="margin:6px 0 6px 12px">③ <b>C++ 标准写法对照一遍</b>——输出 cout &lt;&lt;、输入 cin &gt;&gt;、条件只写成语句,把第一讲的代码抄一遍当字帖;循环写完默跑一圈三个数字(i=1、i&lt;=T、i++)。</p>
</div>
<div class="footer">
数据来源:OJ 课程反馈接口(教师视角,只读)| 生成:2026-09-10<br>
本反馈由授课教师审核后发放;内容只描述学习习惯与方法,与孩子的人格评价无关。
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,69 @@
# 学生反馈报告 · 王小明(克力周日0830CSP02-01 基础回顾)【样式与结构参考样例】
> 班级:克力周日0830CSP02(2026 秋季班 CSP02)| 章节:01 基础回顾
> 生成日期:2026-09-10 | 数据来源:OJ 课程反馈接口(教师视角)
> **本报告为教师审核稿,发送给学生/家长前请先审阅措辞**
📊 **总览**:课堂练习 3/7 | 课后作业 0/3 | 拓展练习 0/7 | 首刷通过率 0% | **最终 3 道题全部订正通过** | 提交 9 次
---
## 🌟 值得表扬的地方
1. **三道题最终全部订正通过,9 次提交没有一次放弃**——这股不搞定不罢休的劲头,非常了不起!
2. **看得懂编译器的报错**:每次报错后都朝着正确的方向修——先补上了 x、y、n、p 的声明,再补 m1,思路一步都没乱。
3. **死循环是自己找到的**:循环条件 `1<=T` 改成 `i<=T`,说明循环三要素真的理解了。
4. 三道题的**解题思路最终都是对的**——折扣比较、爱心快递的选择判断、电量分段显示,逻辑全对,差的只是「把代码写规范」这一层。
---
## 💻 编程题逐题诊断
### 商店折扣(4 次提交)
- 第 1 次提交:**变量没有定义**——`x y n p` 直接拿来用,忘了先声明
- 第 2 次提交:**补了一半**——x y n p 都声明了,但 `m1` 还是漏了
- 第 3 次提交:**变量重复定义**——补 m1 的时候没注意 `m2` 之前已经声明过了
- 第 4 次提交:✅ **通过!** 声明整理干净,逻辑一点没改就对了
> 📌 复盘:三次编译错误其实都是同一件事——「先声明、再使用」。第四次你把声明排得整整齐齐,代码马上就通了,说明你完全有能力一次写好!
### 小杨的爱心快递(2 次提交)
- 第 1 次提交:**语法混入了其他写法**——`cin V` 少了 `>>`、把 `if` 当成公式赋值给变量、用了 C++ 里不存在的 `print()`
- 第 2 次提交:✅ **通过!** 一次把三处全部改对
> 📌 复盘:第一次的写法像是把解题思路直接「翻译」成了代码——思路其实是对的!第二次一口气改对三处,理解力没问题。接下来练的就是「落笔就用 C++ 的标准写法」。
### 手机电量显示(3 次提交)
- 第 1 次提交:**函数名写错**——又用了 `print()`(C++ 里是 `cout`)
- 第 2 次提交:**运行超时**——循环条件写成了 `1 <= T`(永远成立,程序停不下来),应该是 `i <= T`
- 第 3 次提交:✅ **通过!** 循环条件和输出全部修正
> 📌 复盘:超时不可怕,它说明程序已经在「跑」了——而且是你自己把 `1<=T` 找出来改成 `i<=T` 的,循环三要素(从几开始、到几结束、怎么走)你是懂的,下次落笔前默念一遍就行。
---
## 📝 选择题 / 判断题
本节课的客观题你还没有开始做(课堂后 4 题里的选择题、判断题),**不着急,先把编程补上就是很大的进步**。等做到的时候记得:错题直接看讲解,不要反复试答案。
---
## 📖 整体分析
王小明同学本节课可以概括为:**逻辑没问题,规范要跟上**。
- 💪 **亮点**:三道题 9 次提交全部坚持订正到通过;报错读得懂、修改方向一直是对的;三题的解题逻辑最终全对——「会不会」的问题不存在,纯粹是「怎么把代码写规范」的问题。
- 🔧 **问题一:变量「先声明、再使用」的习惯还没建立**。三题里两次栽在声明上(漏声明、重复声明),这是本次最集中的失分点,也是最容易改的。
- 🔧 **问题二:写完没有先编译就提交**。6 次编译错误全部可以用「提交前本地编译一遍」拦住。
- 🔧 **问题三:语法混用了别的写法**(`print()`、`if` 当公式)。C++ 的标准表达需要一点时间适应,练两节课就会顺。
## ✅ 给王小明的建议
1. **立一条铁规矩:先编译、后提交**——编译器说 0 error 才点提交,这一条就能把本次 6 次错误全部消灭。
2. **动笔前先列变量清单**:用到的变量写三样——名字、类型、初值,声明写齐再写逻辑。
3. **C++ 标准写法对照**:输出用 `cout <<`,输入 `cin >> a >> b`,条件只能写成语句——把第一讲的代码抄写一遍当字帖。
4. **循环写完默跑一圈**:从几开始(i=1)、到几结束(i<=T)、怎么走(i++),三个数字对了再交。
5. 把课堂后 4 题和课后作业补完——你的订正能力已经证明「补上就能会」,老师等着你的好消息!💪

View File

@@ -0,0 +1,161 @@
---
name: parallel-feedback
description: 多班级并行写课评调度器。当用户要同时给2个及以上班级写课评,说「并行写课评」「多班课评」「开窗格同时写课评」「三个班一起写」时使用。通过 Herdr 分窗格启动多个 pi 助手,每个助手写一个班的课评;调度员(主会话)负责开窗格、派任务、转发提问、统一合并周汇总、验收汇报。要求 HERDR_ENV=1 环境。
type: skill
---
# 🚦 多班课评并行调度技能
## 用途
橙子手上有多份课评要写时,不再逐个班串行等待,而是:
```
┌──────────┬──────────────┐
│ 🤖 调度员 │ 🤖 助手A:班1 │
│ (主会话) ├──────────────┤
│ │ 🤖 助手B:班2 │
│ ├──────────────┤
│ │ 🤖 助手C:班3 │
└──────────┴──────────────┘
```
- 每个助手独立运行完整的「课评生成」技能流程(含质检、归档)
- 中途助手提问时进入 `blocked` 状态,**调度员负责把问题带回来、把答案传过去**,橙子无需切窗口
- 共享文件(周汇总、汇总网页)由调度员最后统一处理,避免多助手写同一文件冲突
## 第0步:环境检查(必须)
```bash
test "${HERDR_ENV:-}" = 1
```
- **通过** → 继续本技能流程。
- **失败**(不在 Herdr 中运行):告知橙子「当前不在 Herdr 环境里,没法开窗格并行」,退回**单班串行模式**:在当前会话里按「课评生成」技能逐个班顺序写。
## 第1步:收集各班信息
向橙子收集每个班的一组信息(可一次性问完):
| 项目 | 说明 | 示例 |
|------|------|------|
| 班级全名 | 课程编号+老师+星期时间 | `CSP04橙子周六0830` |
| 授课日期 | 必须与校宝 teaching_date 一致 | `2026-10-25` |
| 课次 | 第几课 | `05` |
| 补充材料 | 录音转写 docx 位置 / AIAGENT 作品文件夹路径 / 其他特殊要求 | 可选 |
> 出勤无需问——「课评生成」技能会自动调校宝 API。
> CSP 班按 v2 规则走 `class-feedback-report` 提交诊断流程,脚本自动读 `.env` 凭据。
## 第2步:开窗格
布局规则:**宽屏**第 1 个窗格 `right`(向右分),后续依次对前一个新窗格 `down`(在右列向下堆叠);**窄屏**全部 `down`。避免切出过窄的列。
```bash
# 第1个窗格(从当前会话向右分)
herdr pane split --current --direction right --cwd "$PWD" --no-focus
# 从 .result.pane.pane_id 拿到新窗格ID,如 w5:p2
# 第2个窗格(对第1个新窗格向下分)
herdr pane split <第1个新窗格ID> --direction down --cwd "$PWD" --no-focus
# 第3个窗格(对第2个新窗格向下分)
herdr pane split <第2个新窗格ID> --direction down --cwd "$PWD" --no-focus
```
⚠️ 必须带 `--cwd "$PWD"`(保证助手在项目目录启动,能加载项目技能)和 `--no-focus`(不抢橙子的屏幕焦点)。
## 第3步:启动 pi 助手
在每个新窗格里启动一个 pi 实例:
```bash
herdr agent start <助手名> --kind pi --pane <窗格ID>
```
- **助手命名规则**:`[a-z][a-z0-9_-]{0,31}`,建议带上班级缩写便于记忆,如 `keping-csp04am`、`keping-csp04pm`、`keping-ai03sun`
- 启动默认 30 秒超时;返回 `agent_not_ready` 时不要慌,用 `herdr agent get <助手名>` 轮询,等状态变为 `idle` 再派任务
- 新 pi 会自动加载本项目 `.pi/skills/` 下的技能(含课评生成)
## 第4步:派发任务
对每个助手发送任务(`--wait` 等到它进入 `idle`/`done`/`blocked`):
```bash
herdr agent prompt <助手名> "<任务文本>" --wait --timeout 120000
```
**任务文本模板**(必须完整包含以下要素):
```
请使用「课评生成」技能,为【班级全名】写【日期】第【N】课的课评。
补充材料:【录音文件位置/作品文件夹/其他要求,没有就写"按技能默认流程获取"】
【并行模式特别约束——必须遵守】
1. 只写本班自己的文件:个人课评、请假/未到记录、班级总结、学生画像更新。
2. 【禁止】写任何共享文件:周课评汇总(output/课评汇总/ 或 E:/cc 下的汇总)、
课评汇总网页、E:/cc/3笔记 —— 这些由调度员统一处理,你跳过即可。
3. 全程自动执行(出勤API、质检、归档),不要中途停下来问我确认。
4. 遇到必须人类回答的问题时,直接清晰列出问题后停住等待。
5. 完成后输出「完成报告」:逐条列出本次保存的所有文件路径。
```
- 提交成功≠开始干活,`--wait` 会等到第一个稳定状态
- 返回 `blocked` → 进入第 5 步问答转发
- 返回 `timeout`/`stalled` → **不要盲目重发**!先 `herdr agent get` + `herdr agent read` 检查实际状态
## 第5步:问答转发(核心服务)
助手中途提问(`blocked`)时的标准动作:
```bash
# 1. 看状态和问题内容
herdr agent get <助手名>
herdr agent read <助手名> --source recent-unwrapped --lines 120
# 2. 把问题用人话转述给橙子(多个助手同时 blocked 就一起列出,编号区分)
# 3. 橙子回答后,把答案传回对应助手
herdr agent prompt <助手名> "<橙子的回答>" --wait --timeout 120000
```
注意事项:
- 橙子也可能**自己点进窗格手动回答**——如果发现状态已变 `working`/`idle`,说明他已亲自处理,跳过转发,别重复发送
- 一次只给一个助手发一条 prompt;发过就没必要再发同样的内容
## 第6步:验收与统一汇总
所有助手都到 `done`/`idle` 后:
1. **读完成报告**:`herdr agent read <助手名> --source recent-unwrapped --lines 150`,核对每个班保存的文件清单
2. **抽查课评**:随机读 1-2 个刚保存的课评文件,确认格式正常(固定开头5知识点、署名等)
3. **统一写共享文件**(调度员亲自做,只有调度员写):
- 更新周课评汇总:把本次所有新课评按「最新的放最前面」合并进当周汇总文件
- 课评汇总网页:按「课评生成」技能的网页规则判断是否需要生成/跳过
4. **向橙子汇报**:逐班列出「✅ 已保存文件 + 📋 质检结论 + ⚠️ 需人工复核点」
5. **询问是否关闭窗格**:这些窗格是本技能创建的,经橙子同意后逐个关闭:
```bash
herdr pane close <窗格ID>
```
> 💡 也可以先不关,让橙子自己点进各窗格浏览课评原文,看完再说「关掉吧」。
## 🚨 故障处理速查
| 现象 | 处理 |
|------|------|
| `agent_not_ready` | 用 `agent get` 轮询等 `idle`,别急着 prompt |
| `agent_prompt_stalled` | 先 `agent read` 看实际状态,确认没收到再考虑重发 |
| `timeout` | `agent get` 看状态;还在 `working` 就 `herdr agent wait <名> --timeout 180000` 继续等 |
| `agent_blocked` | 走第 5 步问答转发;**看不懂它卡在什么 UI 时先问橙子,别替他乱按** |
| 助手进程挂了 | 窗格里 shell 还在,重新 `agent start`(可复用原名)再派任务;已保存的文件不受影响 |
| 两个助手写同一文件 | 不应发生(任务模板已禁止);若发生,以先保存者为准,让橙子核对 |
## 核心原则
1. **调度员不写课评,只做协调**:开窗格、传话、合并共享文件、汇报。
2. **共享文件只由调度员写**:周汇总、汇总网页、笔记文件,多助手一律跳过。
3. **不抢焦点**:所有 split 用 `--no-focus`,橙子想看哪个窗格自己点。
4. **转发提问要保真**:把助手的原问题完整带给橙子,把橙子的回答完整带回去,不自己编答案。
5. **课评发出前必须橙子人工过目**:汇报时明确提醒「发家长前请逐条核对」。

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,102 @@
# 交互式课评生成示例
## 场景演示:从笼统到具体的课评生成过程
### 初始信息(不够具体)
```
学生:嘉博
班级:周六晚上1900AI03班
课程:个人网页完善
课次:第8课
表现:超棒、很专注、有创意
```
### 交互式提问过程
#### 第一次提问(获取具体行为)
> **AI**:您提到嘉博表现"超棒",能具体说说他在哪个环节表现最突出吗?
**用户回复**:他在修改网页颜色和添加小花的时候特别用心,主动调整了好几次才满意。
#### 第二次提问(获取细节)
> **AI**:能描述一下他修改网页的具体过程吗?比如遇到了什么问题,怎么解决的?
**用户回复**:他说"我觉得颜色太暗了",然后尝试了3种颜色方案,最后选了一个淡紫色的背景。添加小花的时候,他调整了花的大小和位置,说"要让小花看起来更自然"。
#### 第三次提问(获取成长信息)
> **AI**:相比上节课,嘉博在哪些方面有明显进步?
**用户回复**:上节课他还需要老师提醒才记得保存,这节课主动保存了好几次。打字速度也有进步,能更流畅地表达自己的想法了。
#### 第四次提问(获取家庭配合建议)
> **AI**:家长最关心孩子哪方面的能力?在家可以做什么配合?
**用户回复**:家长希望培养孩子的设计思维,可以多观察生活中的好设计。在家可以让孩子尝试设计其他网页内容。
### 生成的高质量课评(基于具体信息)
# 课程名称:AI大作家(下)
**授课日期**:2026-05-03
**课评内容**:
嘉博今天对自己的个人网页特别用心,上课很开心~看到原始页面觉得颜色太暗,主动尝试了3种颜色方案,最终选择了淡紫色背景,还仔细调整了小花的大小和位置,追求"看起来更自然"的效果~这种对细节的执着和审美意识让老师很惊喜!
相比上节课,嘉博明显进步了——记得主动保存文件多次,打字速度也更流畅,能更清楚地表达自己的创意想法。能详细地把自己的兴趣爱好、梦想告诉AI,表达得很清楚!
你对网页细节的关注说明你很有设计眼光,继续发挥创意,你的网页会越来越精彩的!
---
## 📋 家长视角(本期重点)
**🎯 本节课核心知识**
- 网页设计基础:掌握HTML/CSS的基本结构,能独立修改网页样式
- 创意表达:能将自己的创意通过代码实现,培养设计思维
- 人机协作:学会用AI辅助创作,提高表达效率
**📚 必学内容清单**
- **基础技能**:能独立创建个人网页,包含文字、图片和样式
- **设计能力**:能运用色彩搭配和布局原则,设计美观的界面
- **技术掌握**:理解HTML标签和CSS样式的作用,能进行简单修改
**🏠 家庭配合建议**
1. **每日练习**(15分钟):鼓励孩子继续完善个人网页,可以添加更多内容如家庭照片、爱好介绍等
2. **能力培养**:重点关注孩子的设计思维和审美能力,鼓励多观察生活中的优秀设计
3. **亲子互动**:和孩子一起浏览优秀网页,讨论"为什么这个网页好看",培养审美鉴赏能力
**📝 课后作业要求**
- **必做**:完善个人网页,添加至少3个新内容板块(如家庭介绍、兴趣展示、未来计划)
- **选做**:尝试添加动画效果或交互功能,让网页更生动有趣
- **提交**:下周上课前完成,家长可以和孩子一起欣赏作品,讨论改进方向
---
## 📈 孩子成长亮点
### 已达成的进步
✅ **设计意识**:嘉博展现出良好的审美和设计思维,能主动调整页面效果
✅ **自主学习**:能主动保存文件,减少对老师的依赖
✅ **表达能力**:能更流畅地表达自己的想法,与AI沟通更高效
### 值得关注的潜力
🎯 **技术深度**:可以学习更多网页高级功能,如JavaScript交互
🎯 **创作广度**:可以将设计思维应用到其他创作项目中
### 长期发展建议
- 建议未来可以学习JavaScript,让网页具有更多交互功能
- 可以参加网页设计比赛,将兴趣转化为成就感
- 继续培养审美能力,这对未来的任何创作都有帮助
---
## 💬 给家长的话
嘉博在个人网页设计中展现出了很好的创作天赋。他对颜色和布局的敏感度表明他有很强的设计潜力。建议家长:
1. **多提供创作机会**:让孩子参与家庭网页设计,如电子相册、家庭介绍页面等
2. **培养观察力**:引导孩子观察生活中的优秀设计,分析为什么设计得好
3. **鼓励尝试**:支持孩子尝试新的设计元素和技术,不怕犯错
嘉博的进步让我们看到了他在创意设计方面的潜力,继续保持这份热情,他会在编程创作领域走得更远。

View File

@@ -0,0 +1,54 @@
# 学生画像模板
> 填写指南:根据学生的实际表现选择对应的类型,主要从性格特点、学习状态、能力水平三个维度判断
---
## 🌱 鼓励型学生
### 内向谨慎型
- **表现**:安静、敏感、害怕出错
- **语言**:很少主动说话、声音小、问"对不对"
- **策略**:多鼓励、创造低压力环境
### 信心不足型
- **表现**:常说"不会"、"做不到"
- **行为**:遇到问题先放弃、需要引导
- **策略**:分解任务、创造小成功体验
### 新手入门型
- **表现**:刚接触编程、充满好奇
- **问题**:表达不清晰、易被bug卡住
- **策略**:放慢节奏、及时肯定每个小进步
---
## 🔥 激励型学生
### 聪明浮躁型
- **表现**:反应快、但不够深入
- **语言**:"我会了"、"太简单"
- **策略**:给挑战、追求极致
### 潜力待挖型
- **表现**:能完成任务但缺乏探索
- **心理**:容易被满足、缺乏内驱力
- **策略**:展示更高可能性、激发向往
### 容易满足型
- **表现**:做完基本要求就停了
- **心态**:"够用了"、不想更进
- **策略**:对比激发、挑战胜负欲
---
## 📝 快速判断
| 课堂表现 | 学生类型 | 推荐风格 |
|----------|----------|----------|
| 不敢说话、害怕出错 | 内向谨慎型 | 鼓励型 |
| "我不会"、"我做不好" | 信心不足型 | 鼓励型 |
| 第一次学、什么都新鲜 | 新手入门型 | 鼓励型 |
| "我会了"但不深入 | 聪明浮躁型 | 激励型 |
| 能完成但不探索 | 潜力待挖型 | 激励型 |
| "够用了"、不想更进 | 容易满足型 | 激励型 |

View File

@@ -0,0 +1,274 @@
# 课程记录文档模板
这是批量生成课评时,用户需要提供的课程记录文档模板。
## 使用说明
1. 复制本模板,修改周次、日期范围和学生信息
2. 按班级分组,记录每个学生的课堂表现
3. 保存为 md 文件后提供给 AI,即可批量生成课评
---
# 第X周课程记录
**日期范围**:2026-04-17 至 2026-04-19
---
## 【周五下午 1700 AI03班】(1人上课)
### 李梓宁
- **课程**:AI大作家(下)
- **日期**:2026-04-17
- **课次**:第7课
- **表现**:对自己的小说特别上心,不断调试修改,主动要求更好的效果,精益求精
- **状态**:✅ 出勤
---
## 【周五晚上 1900 K4班】(4人上课)
### 陈圆振
- **课程**:彩虹生成器
- **日期**:2026-04-17
- **课次**:第7课
- **表现**:思维敏捷,掌握分支嵌套知识点,认真完成作品,课堂积极性高
- **状态**:✅ 出勤
### 彭煜腾
- **课程**:彩虹生成器
- **日期**:2026-04-17
- **课次**:第7课
- **表现**:掌握循环嵌套结构,迅速完成作品,出现 bug 能主动拉着老师讨论
- **状态**:✅ 出勤
### 郭艺嘉
- **课程**:彩虹生成器
- **日期**:2026-04-17
- **课次**:第7课
- **表现**:掌握分支嵌套知识点,反应超快,认真完成作品,课堂热情活泼
- **状态**:✅ 出勤
### 王晨语
- **课程**:彩虹生成器
- **日期**:2026-04-17
- **课次**:第7课
- **表现**:迅速完成基础内容,主动添加"火球乱飞"创意效果,想法天马行空
- **状态**:✅ 出勤
---
## 【周六早上 0830 CSP03班】(5人上课)
### 杨林轩
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:状态在线,表现积极,对字符串知识掌握不错
- **状态**:✅ 出勤
### 欧俊宇
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:状态在线,能和同桌积极讨论问题,帮助同桌找错误
- **状态**:✅ 出勤
### 汪子杰
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:早早到校,一进教室就先打开题目准备做题,学习主动性强
- **状态**:✅ 出勤
### 谭锦程
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:状态在线,能和同桌互相纠错,对之前知识点还有印象
- **状态**:✅ 出勤
### 谢明泓
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:状态在线,能发现 string::npos 的具体含义,善于观察和思考
- **状态**:✅ 出勤
---
## 【周六下午 1400 CSP03班】(4人上课,1人请假)
### 张雨禾
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:上课对知识掌握不错,下课积极完成作业,但过去七天很多知识点不太记得
- **状态**:✅ 出勤
### 魏铭轩
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:状态在线,对字符串知识掌握很棒,课堂分神次数明显下降
- **状态**:✅ 出勤
### 苏俊宇
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:状态在线,能了解字符串语法,上课认真,紧跟老师节奏
- **状态**:✅ 出勤
### 廖梓琪
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:状态在线,对数组知识能迅速反应,理解力强,但注意力还需要加强
- **状态**:✅ 出勤
### 郑子煜
- **课程**:字符串处理
- **日期**:2026-04-18
- **课次**:第7课
- **状态**:⏸ 请假
- **备注**:请家长督促在家复习本周字符串相关知识点,包括 getline()、substr()、size()、find() 函数
---
## 【周六晚上 1900 AI03班】(4人上课,1人请假)
### 王子墨
- **课程**:AI大作家插图生成
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:上课特别积极,遇到问题主动请教,和 AI 围绕"红狼"角色进行有趣辩论,不放弃直到达成目标
- **状态**:✅ 出勤
### 谭俊研
- **课程**:AI大作家插图生成
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:安静专注完成任务,能独立写提示词生成图片,作品完成度高
- **状态**:✅ 出勤
### 黄彦棋
- **课程**:AI大作家插图生成
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:状态超棒,生成插图速度快,只看演示一次就能独立完成,学习效率超高
- **状态**:✅ 出勤
### 李承泽
- **课程**:AI大作家插图生成
- **日期**:2026-04-18
- **课次**:第7课
- **表现**:顺利完成插图生成,和同学们热烈讨论小说情节,但聊小说时有点过于兴奋
- **状态**:✅ 出勤
### 陈嘉博
- **课程**:AI大作家插图生成
- **日期**:2026-04-18
- **课次**:第7课
- **状态**:⏸ 请假
- **备注**:请家长安排时间,督促在家了解本周小说插图生成相关知识点
---
## 【周日早上 0845 AI03班】(3人上课,1人缺勤)
### 卢皓霖
- **课程**:AI大作家插图生成
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:紧跟老师完成插图生成,插图精美,对风格有自己的主见,主动要求换成中式插图
- **状态**:✅ 出勤
### 杨翊弘
- **课程**:AI大作家插图生成
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:紧跟老师完成插图生成,认真听讲,一步一步跟着操作,大方表达自己的想法
- **状态**:✅ 出勤
### 朱浩铭
- **课程**:AI大作家插图生成
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:没有迟到,早早到课室,紧跟老师节奏,遇到版权问题时主动问老师并自己解决
- **状态**:✅ 出勤
### 黄俊博
- **课程**:AI大作家插图生成
- **日期**:2026-04-19
- **课次**:第7课
- **状态**:❌ 未上课
- **备注**:去其他老师班级上课,未到本班上课,请家长确认课程安排
---
## 【周日早上 1030 CSP03班】(3人上课)
### 王佳琳
- **课程**:字符串处理
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:状态在线,表现积极,但对之前学过的知识有些遗忘,课后复习需要加强
- **状态**:✅ 出勤
### 卢华琛
- **课程**:字符串处理
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:状态在线,表现积极,状态愈加改善,已能完全进入学习状态
- **状态**:✅ 出勤
### 唐钎宸
- **课程**:字符串处理
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:状态在线,对知识点有了解,但课堂上容易开小差,注意力不太能集中
- **状态**:✅ 出勤
---
## 【周日下午 1400 AI03班】(4人上课)
### 贺楚悦
- **课程**:AI大作家插图生成
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:完成得非常不错,生成的插图和作品风格很相似,贴合度特别高,一开始不太明白流程,教导几次后就能熟练掌握
- **状态**:✅ 出勤
### 林俊宇
- **课程**:AI大作家插图生成
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:一直跟着老师节奏完成任务,完美生成所有图片,主动重新修改封面,对作品有要求
- **状态**:✅ 出勤
### 余浩宸
- **课程**:AI大作家插图生成
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:能够把自己的任务做出来,前面一直跟着老师节奏,还会转过身认真听课,后面状态稍有下滑但整体完成
- **状态**:✅ 出勤
### 吴浩睿
- **课程**:AI大作家插图生成
- **日期**:2026-04-19
- **课次**:第7课
- **表现**:生成的插图十分恐怖,和小说风格十分合适,氛围感拉满,对生图、插图、标注知识点都掌握得不错
- **状态**:✅ 出勤
---
## 状态说明
| 状态符号 | 含义 |
|---------|------|
| ✅ 出勤 | 学生正常上课 |
| ⏸ 请假 | 学生请假 |
| ❌ 未上课 | 学生未上课(缺勤/调班等) |

View File

@@ -0,0 +1,95 @@
# 课评示例
## 示例1:Kitten课程 - 鼓励型
**学生**:小明 | **班级**:三年级A班 | **课次**:第3课
小明今天虽然是第一次接触循环积木,但我看到了你眼里的好奇,这就是最好的开始。你的故事很有想象力,"小猫去太空探险"这个创意太棒了!虽然积木用得还不太熟练,但你能说清楚自己想要什么效果,这就是编程思维的开始。程序没跑通没关系,重要的是你愿意一次次调整积木,这份坚持最珍贵。下次我们可以试着先把故事在纸上画出来,再一块块搭积木,这样会更有条理。记住,每一款伟大的游戏都是从第一个积木开始的,继续创造吧!
---
## 📋 家长视角(本期重点)
**🎯 本节课核心知识**
- 循环积木:掌握重复执行的基本概念,能独立完成简单动画
- 条件判断:理解如果...就...的逻辑,能制作简单的交互效果
- 创意表达:培养创意思维,能把自己的想法通过积木实现
**📚 必学内容清单**
- **基础操作**:熟练使用重复积木完成连续动作
- **创意设计**:能设计简单的动画故事或游戏
- **问题解决**:遇到积木错误能尝试不同的解决方案
**🏠 家庭配合建议**
1. **每日练习**(15分钟):用积木搭建一个简单的动画,比如小猫走路或花儿开放
2. **能力培养**:重点关注孩子的创意表达,鼓励自由发挥,没有对错之分
3. **亲子互动**:和孩子一起玩"编程猜谜"游戏,描述一个动作让孩子用积木实现
**📝 课后作业要求**
- **必做**:完成"小猫探险"作品,包含至少3个场景和简单交互
- **选做**:给作品添加音效或者背景故事,让作品更生动
- **提交**:下周上课前完成,可以和孩子一起欣赏他的创作成果
---
## 示例2:AIGC课程 - 激励型
**学生**:小红 | **班级**:四年级B班 | **课次**:第5课
小红,以你的聪明程度,今天这个AI绘画应该20分钟搞定,咱们来挑战一下?你的反应超快,老师刚说需求你就能组织出清晰的Prompt,这种表达能力是天赋。这个页面的动画效果很惊艳,你偷偷研究了不少技巧吧,审美在线!但别只满足于实现功能,去问问AI"这段代码还能怎么优化",追求极致性能。你的天花板远不止于此,别让"够用"成为你的绊脚石!
---
## 📋 家长视角(本期重点)
**🎯 本节课核心知识**
- Prompt工程:掌握清晰描述需求的方法,能写出高质量的提示词
- AI绘画:理解AI绘画的基本原理,能独立创作创意图片
- 动画设计:学会制作简单动画效果,培养审美和创意能力
**📚 必学内容清单**
- **基础技能**:能独立编写有效的Prompt,准确表达创意想法
- **技术掌握**:熟悉AI工具的使用方法,能解决常见问题
- **创新应用**:能结合多种技术创作出完整的作品
**🏠 家庭配合建议**
1. **每日练习**(15分钟):让孩子用AI工具完成一个小创作,可以是写故事、设计图片或解决问题
2. **能力培养**:重点关注孩子的语言表达能力和创意思维,鼓励多描述自己的想法
3. **亲子互动**:和孩子讨论AI生成的内容,问问他"为什么AI会这样回答"培养批判性思维
**📝 课后作业要求**
- **必做**:完成"我的梦想世界"AI绘画作品,包含至少3个场景和简单动画
- **选做**:尝试使用不同的AI工具,比如文字生成、音乐创作等
- **提交**:通过班级群提交作品,家长可以一起欣赏和讨论
---
## 示例3:CPP课程 - 鼓励型
**学生**:小李 | **班级**:五年级C班 | **课次**:第8课
小李今天虽然是第一次接触递归,但我看到了你眼里的好奇,这就是最好的开始。你很善于倾听,老师讲的时候你眼睛一直跟着屏幕,这种专注是学好编程的基石。虽然代码还有bug,但你的思路是对的,下一步就是把它表达出来。遇到不懂的地方会标记下来,而不是跳过去,这种处理方式很务实。下次我们可以试着把思路先画在纸上,再写代码,这样会更顺畅。老师相信,按这个节奏下去,你很快就会找到编程的感觉。
---
## 📋 家长视角(本期重点)
**🎯 本节课核心知识**
- 递归概念:理解函数调用自身的基本原理,能写出简单的递归程序
- 边界条件:掌握递归的终止条件,避免无限循环
- 算法思维:培养分治思想,学会将复杂问题分解为简单子问题
**📚 必学内容清单**
- **语法规范**:掌握递归函数的正确写法,包括函数定义和调用
- **算法理解**:理解递归的执行过程,能跟踪函数调用栈
- **调试能力**:能独立排查递归中的常见错误,如栈溢出
**🏠 家庭配合建议**
1. **每日练习**(20分钟):在OJ系统练习递归题目,重点关注边界条件
2. **能力培养**:培养孩子的耐心和细致,鼓励在写代码前先画递归树
3. **亲子互动**:和孩子讨论生活中的递归例子, like 俄罗斯套娃、分形图案等
**📝 课后作业要求**
- **必做**:完成OJ系统的递归练习题3道,代码必须包含详细注释
- **选做**:尝试用递归解决实际问题,如汉诺塔、斐波那契数列等
- **提交**:通过OJ系统提交,截止日期前完成,家长可查看提交记录和得分情况

View File

@@ -0,0 +1,61 @@
# 课评示例 - 家长视角版
## 示例:AI03课程 - 温暖鼓励型
**学生**:嘉博 | **班级**:周六晚上1900AI03班 | **课次**:第8课
嘉博今天对自己的个人网页特别用心,上课很开心~能够详细地把自己的兴趣爱好、梦想告诉AI,表达得很清楚!看到页面觉得颜色不太好看,就主动修改卡片颜色,还给背景添加了小花,这种根据自己的审美进行优化的意识很棒~你对网页细节的关注说明你很有设计眼光,继续发挥创意,你的网页会越来越精彩的!
---
## 📋 家长视角(本期重点)
**🎯 本节课核心知识**
- 网页设计基础:掌握HTML/CSS的基本结构,能独立修改网页样式
- 创意表达:能将自己的创意通过代码实现,培养设计思维
- 人机协作:学会用AI辅助创作,提高表达效率
**📚 必学内容清单**
- **基础技能**:能独立创建个人网页,包含文字、图片和样式
- **设计能力**:能运用色彩搭配和布局原则,设计美观的界面
- **技术掌握**:理解HTML标签和CSS样式的作用,能进行简单修改
**🏠 家庭配合建议**
1. **每日练习**(15分钟):鼓励孩子继续完善个人网页,可以添加更多内容如家庭照片、爱好介绍等
2. **能力培养**:重点关注孩子的设计思维和审美能力,鼓励多观察生活中的优秀设计
3. **亲子互动**:和孩子一起浏览优秀网页,讨论"为什么这个网页好看",培养审美鉴赏能力
**📝 课后作业要求**
- **必做**:完善个人网页,添加至少3个新内容板块(如家庭介绍、兴趣展示、未来计划)
- **选做**:尝试添加动画效果或交互功能,让网页更生动有趣
- **提交**:下周上课前完成,家长可以和孩子一起欣赏作品,讨论改进方向
---
## 📈 孩子成长亮点(家长期望达成情况)
### 已达成的进步
✅ **创意表达能力**:嘉博能清晰表达自己的想法,并能通过网页实现
✅ **审美能力**:主动优化颜色和布局,展现出良好的设计意识
✅ **专注力**:能长时间投入创作,体现了对编程的兴趣
### 值得关注的潜力
🎯 **技术深度**:可以进一步学习更复杂的网页功能,如JavaScript交互
🎯 **创作思维**:鼓励将网页设计应用到其他项目,如电子相册、小游戏等
### 长期发展建议
- 建议未来可以学习JavaScript,让网页具有更多交互功能
- 可以参加网页设计比赛,将兴趣转化为成就感
- 继续培养审美能力,这对未来任何创作都有帮助
---
## 💬 给家长的话
嘉博在AI03课程中展现出了很好的创作天赋和学习态度。他对个人网页的用心程度表明他有很强的表达欲望和审美能力。建议家长:
1. **多鼓励创作**:嘉博喜欢把想法变成现实,可以提供更多创作机会
2. **关注设计思维**:嘉博已经展现出设计眼光,可以引导他观察生活中的优秀设计
3. **保持兴趣**:他对编程的兴趣是最好的老师,保持这份热情比追求技术更重要
通过家校配合,嘉博的创意表达能力会得到更好的发展,这对他未来的学习和工作都有重要价值。

View File

@@ -0,0 +1,133 @@
---
name: feedback-checker
description: 对已有课评进行质量检查,输出质检报告和修订稿,支持自动触发和手动触发
type: skill
---
# 课评质检技能
## 🌟 功能说明
本技能为课评提供质量检查,确保课评达到"准确、具体、有温度、有行动"的标准,可以放心发给家长。
✅ 支持班级群反馈和个人课评
✅ 9个专业质检Agent各司其职、互相校验
✅ 自动输出质检报告 + 修订稿
✅ 三档放行:直接发/修订后发/必须重写
## 📋 触发方式
### 方式1:课评生成流程中自动触发
在课评生成技能中,生成完课评后会自动调用本技能进行质检,无需手动操作。
### 方式2:手动触发
对AI说:
```
用课评质检系统检查这份课评:
[粘贴课评内容]
```
或
```
质检这份课评:[粘贴课评内容]
```
## 🔧 执行流程
### 第1步:并行调用核心质检Agent(5个)
同时调用以下Agent(并行执行):
| Agent | 职责 | 输出 |
|-------|------|------|
| 课评证据审计员 | 事实核对 | 数据准确性结论 |
| 课评质量评审员 | 100分制打分 + 硬伤检查 | 评分 + 硬伤结论 |
| 家长-忙碌实用型 | 手机阅读体验 | 长度/重点/行动建议 |
| 家长-结果导向型 | 信息完整性 | 信息缺口 + 行动清单 |
| 家长-细节核对型 | 文内一致性 | 错别字/术语/格式问题 |
### 第2步:并行调用剩余家长Agent(2个)
同时调用以下Agent(并行执行):
| Agent | 职责 | 输出 |
|-------|------|------|
| 家长-焦虑保护型 | 情绪风险 | 刺痛点 + 建议改法 |
| 家长-成长陪伴型 | 成长性 | 陪伴感建议 |
### 第3步:汇总所有反馈
将7个Agent的输出汇总为一份完整的质检意见。
### 第4步:调用终稿编辑
调用**课评终稿编辑**,合并所有意见,产出修订稿。
### 第5步:三档放行判断
| 条件 | 结论 | 处理 |
|------|------|------|
| 触发任一硬伤 或 总分<70 | 必须重写 | 返回修订稿,建议重写 |
| 无硬伤 且 70-84分 | 修订后发 | 使用终稿编辑的修订稿 |
| ≥85分 且 无硬伤 | 直接发 | 保持原稿,附质检报告 |
## 📊 质检报告格式
```markdown
📋 课评质检报告
【总分】XX / 100
【结论】直接发送 / 修订后发送 / 必须重写
【一、证据审计】
- 已核实:...
- 存疑/风险:...
【二、硬伤检查】
- 触发:无 / 第X项(说明)
【三、主要问题】(按严重程度排)
1. ...
2. ...
【四、修订稿】
(若结论为"修订后发送"或"必须重写",给出完整修订后的课评)
【五、修改说明】
- 改了什么、为什么改
```
## ⚠️ 核心原则
1. **事实以证据审计员为准**:家长视角的数字意见一律忽略
2. **不做学生横向比较**:揪出"最高/最快/分水岭/紧随XX"等比较词
3. **术语家长能懂**:OLE/CE/WA/SJF/AC这类缩写要解释或换成白话
4. **结合学生性格**:完美主义型先肯定韧性再谈方法;佛系型正向收尾不施压
5. **老师是最终决策者**:你给建议和修订稿,老师决定用不用
## 🚀 快速模式
如果用户只想快速检查(如个人课评),可以只调用:
- 证据审计员 + 质量评审员(跳过5位家长)
- 输出简化版质检报告
## 📝 7个硬伤(一票否决项)
1. **没有数据**:全文只有"表现不错"等空话
2. **学生高度重复**:换名字就能复用
3. **没有个体差异**:分不出不同学生
4. **只夸不批**:全是"很好""继续保持"
5. **只批不夸**:通篇问题,像批评报告
6. **没有后续建议**:家长不知道下一步做什么
7. **专业误判**:把语法错误说成算法差、把多次提交说成态度差
## 📝 三段式检查
每个被点评的学生必须同时有:
- **数据表现**:完成题数/提交次数/AC/WA情况
- **能力判断**:从数据推断出什么能力卡点
- **下一步建议**:回家具体做什么

View File

@@ -1,5 +1,5 @@
---
name: 课评检查
name: feedback-review
description: 检查指定课次的学生课评完成情况、班级总结完成情况、学生画像完整性。支持API出勤记录与本地课评交叉核对,自动发现时间/课程编号/学生不一致问题。
type: skill
---

View File

@@ -1,5 +1,5 @@
---
name: 课评生成
name: feedback-generator
description: 快速生成个性化课评,你只需提供学生本节课的表现,自动匹配班级风格生成高质量课评
type: skill
---
@@ -27,10 +27,10 @@ type: skill
HTML 以 `samples/report-sample.html` 为样式基准,`pdf` 用 `scripts/mkpdf.mjs` 生成(单页 660px)。
4. **审核红线**(必须写进每次交付说明):报告是草稿、须教师审核;只写学习习惯不写人身评价;
代码/报错/错题选项只发对应家长、不进班级群;不做学生横向对比排名。
5. **存档结构改用新技能体系**(见下方「CSP 班(v2 存档结构)」):
`Class-2026-X/<班组>/<学生>/` + `Students/<学生>/profile.md`。
5. **存档结构(2026-09-26 统一)**:所有课程体系统一存档到
`.claude/memory/class/<班组>/<学生>/`,画像在 `.claude/memory/class/<班组>/<学生>/profile.md`。
> AIAGENT03 班、体验课 **不**适用本规则,仍按本技能原有流程与存档(`.claude/memory/class/...` + `output/课评汇总/`)执行。
> AIAGENT03 班、体验课**不**使用 OJ 报告三件套流程,但存档路径与下方通用规则相同。
>
> **快速触发**:对 AI 说「整理 XX 班的课堂反馈」或「引导我进行操作」即可调用该技能;其脚本自动读取仓库根 `.env`(已配置 OJ 凭据)。
@@ -58,18 +58,19 @@ type: skill
```
📝 问题1:这次写哪个班?(列出当前所有班级选项)
AIAGENT03班:周五下午1700、周六晚上1900、周日早上0845、周日下午1400
AIAGENT03班:周五下午1500、周五下午1630、周六晚上1900、周日早上0845、周日早上1045、周日下午1400
CSP04班:周六早上0830、周六下午1400
CSP00班:周五晚上1900(2课时)
CSP01班:周六下午1610(一对一,随机补课)
体验课
📝 问题2(AIAGENT03班):作品文件夹路径是什么?
📝 问题3(CSP00/CSP04班):OJ题目的token是什么?
📝 问题4:本节课出勤情况如何?(来了哪些学生,谁请假)
```
⚠️ **出勤情况自动获取,无需你提供!** 我会调用校宝API自动查询,详见下方规则。
你回答完所有问题,我就会自动完成整个课评生成流程!
---
@@ -79,12 +80,13 @@ type: skill
你提供信息后,我会自动完成:
### 第1阶段:课评准备
1. 使用python-docx读取录音转写文件
2. AI分析录音文本,识别"发言人1,2,3"对应的学生
3. **AIAGENT班**:查看作品文件夹,分析每个学生作品的创意和亮点
4. 读取课程计划,获取5个知识点
5. 读取每个学生的画像
6. **CSP00/CSP04班**:使用token查询OJ做题数据
1. **🎯 自动获取出勤数据**(优先校宝API,失败再问你,详见下方规则)
2. 使用python-docx读取录音转写文件
3. AI分析录音文本,识别"发言人1,2,3"对应的学生
4. **AIAGENT班**:查看作品文件夹,分析每个学生作品的创意和亮点
5. 读取课程计划,获取5个知识点
6. 读取每个学生的画像
7. **CSP00/CSP04班**:使用token查询OJ做题数据
### 第2阶段:课评生成
1. 读取班级风格指南
@@ -186,9 +188,74 @@ type: skill
### 工作流程
```
确认班型班次 → 读取录音转写(docx) → AI分析识别发言人 → 获取课程知识点 → 读取学生画像 → 润色生成 → 确认修改 → 课评质检 → 保存
确认班型班次 → 🎯校宝API查出勤 → 读取录音转写(docx) → AI分析识别发言人 → 获取课程知识点 → 读取学生画像 → 润色生成 → 确认修改 → 课评质检 → 保存
```
### 0. 🎯 自动获取出勤数据(校宝API · 优先执行)
**执行时机**:确认班型和授课日期后,第一时间查询校宝API获取出勤数据。
**API信息**(从 `.env` 读取):
```
API Base URL: https://api.qonnwolf.com/api/v1
Authorization: Bearer <从 .env 读取>
```
**查询接口**:
```
GET /reports/teaching-schedule?teaching_date={日期}&teacher_name=橙子&include_students=true
```
**班级名映射**(授课日期 → 校宝班级名,用 teacher_name=橙子 筛选后自动匹配):
| 我们的班次 | 校宝 class_name 特征 | 时间段 |
|-----------|---------------------|--------|
| 周五下午1500 AIAGENT03 | AIAGENT03 | 15:00-16:30 |
| 周五下午1630 AIAGENT03 | AIAGENT03 | 16:30-18:00 |
| 周五晚上1900 CSP00 | CSP00 | 19:00-20:30 |
| 周六早上0830 CSP04 | CSP04 | 08:30-10:00 |
| 周六下午1400 CSP04 | CSP04 | 14:00-15:30 |
| 周六下午1610 CSP01 | CSP01 | 16:10-17:40 |
| 周六晚上1900 AIAGENT03 | AIAGENT03 | 19:00-20:30 |
| 周日早上0845 AIAGENT03 | AIAGENT03 | 08:45-10:15 |
| 周日早上1045 AIAGENT03 | AIAGENT03 | 10:45-12:15 |
| 周日下午1400 AIAGENT03 | AIAGENT03 | 14:00-15:30 |
**执行流程**:
1. **调用API**:用 curl 调用接口,传入授课日期和 `teacher_name=橙子`,设置 `include_students=true`
2. **匹配班级**:API返回当天橙子老师所有课次,根据用户选择的班次对应的时间段和 class_name 匹配到具体课次
3. **提取出勤**:从匹配课次的 `students[]` 数组提取每个学生的 `attendance_status`
- `attendance_status` 值:`正常` / `请假` / `迟到` / `缺勤` / `补课` 等
- 映射到课评系统:
- `正常` → 正常上课(生成课评)
- `请假` → 请假记录(生成请假记录)
- `迟到` → 正常上课(照常生成课评,可提及迟到)
- `缺勤` → 未到课记录
- `补课` → 补课课评
4. **格式化**:将出勤数据转为标准格式供后续流程使用:
```
正常上课:卢皓霖、朱浩铭、沙佩琪
请假:李汶浩
迟到:无
补课:无
```
**异常处理**(三级降级策略):
| 情况 | 判断方式 | 处理 |
|------|---------|------|
| ✅ 正常返回 | API返回 code=0,且有匹配的时间段 | 直接使用出勤数据 |
| ⚠️ API 过期/401 | HTTP 401 或返回 token 相关错误 | **立即告知橙子**:「校宝API token过期了,麻烦你提供新的token,我会保存到 `.env`」。橙子提供新token后更新 `.env` 中的 Authorization,然后重试 |
| ⚠️ 校宝无此班级 | API返回 code=0 但无匹配的时间段/班级 | **问橙子**:「校宝上没查到这个班的出勤,你手动告诉我吧:谁来了?谁请假?」 |
| ⚠️ 校宝数据不全 | API返回了班级但学生列表为空或明显缺失 | **问橙子**:「校宝上这个班的学生数据好像不全(只查到X人,应该是Y人),你确认一下?」 |
| ⚠️ 网络错误 | curl 超时或连接失败 | 重试一次,仍失败则降级问橙子 |
**⚠️ Token 更新流程**:
当橙子提供新的 token 时,更新项目根目录 `.env` 文件中的 `Authorization: Bearer <新token>` 行,然后重试查询。
> 💡 **核心原则**:出勤数据优先自动获取,减少橙子手动输入。API 出问题时及时告知并降级处理,绝不能因为 API 故障卡住整个课评流程。
### 1. 读取课堂录音转写文件
自动从 `D:\03-下载` 目录读取课堂录音转写文件(`.docx` 格式),查找该目录下最新的 `.docx` 文件:
@@ -223,7 +290,7 @@ Read 工具直接读取 _提取.txt 文件,中文显示完全正常
> **为什么这样做?** python-docx 底层 XML 是 UTF-8 编码,能正确读取中文。但 bash 终端渲染 UTF-8 中文时会产生乱码。保存为 txt 后,用 Read 工具读取即可正常显示。
>
> **清理**:课评保存完成后,删除 `_提取.txt` 临时文件。
> **清理**:课评全部保存完成后,自动删除 `_提取.txt` 临时文件和原始 `.docx` 录音文件(详见第4阶段「🧹 自动清理录音临时文件」)。
**录音文本特点**:
- 语音转文字质量参差不齐,常见同音字、模糊识别
@@ -764,20 +831,18 @@ python scripts/get_student_oj.py \
- 未上课:`YYYYMMDD_课程编号-课次(未到).md`
- 补课:正常文件名 `YYYYMMDD_课程编号-课次.md`,放在补课班级下的 `补课/` 目录中
### ⚠️ CSP 班(v2 存档结构 · 覆盖上方通用规则)
### ✅ 存档路径统一规则(2026-09-26 起,全部课程适用)
CSP00 / CSP04 课评**不**使用 `.claude/memory/class/...` 与 `output/课评汇总/` 路径,统一改用
`.claude/skills/class-feedback-report` 的归档体系(详见该技能 SKILL.md):
所有课评、家长版报告、班级汇总**统一存 `.claude/memory/class/` 对应班级目录**,
不再使用 `Class-2026-X/` 或 `output/课评汇总/`:
- **家长版三件套**(发给家长):`Class-2026-X/<班组>/<学生>/<姓名>-<班组>-<章节号>-反馈报告.{md,html,pdf}`
- 例:`Class-2026-C/克力周日0830CSP02/王凯平/王凯平-克力周日0830CSP02-03-反馈报告.md`
- `Class-2026-X`:A春 / B暑 / C秋 / D寒(2026秋季班用 `Class-2026-C`)
- **家长版三件套**(发给家长):`.claude/memory/class/<班级>/<学生>/<姓名>-<班级>-<课次>-反馈报告.{md,html,pdf}`
- 例:`.claude/memory/class/CSP04橙子周六1400/张雨禾/张雨禾-CSP04橙子周六1400-04-反馈报告.md`
- HTML 以 `samples/report-sample.html` 为样式基准;PDF 用 `scripts/mkpdf.mjs` 单页 660px 生成
- **内部课评正本**(校宝核查用):`Class-2026-X/<班组>/<学生>/feedback/YYYYMMDD_课程编号-课次.md`
- **学生画像**:`Students/<学生>/profile.md`(跨学期连续,按学生名扁平存放)
- **班级汇总**:`Class-2026-X/<班组>/summaries/<班组>-<章节号>-反馈汇总-<日期>.md`
> AIAGENT03 班、体验课仍按下方通用规则(`.claude/memory/class/...` + `output/课评汇总/`)保存。
- **内部课评正本**(校宝核查用):`.claude/memory/class/<班级>/<学生>/feedback/YYYYMMDD_课程编号-课次.md`
- **补课生**:`.claude/memory/class/<班级>/补课/<学生>/feedback/`(家长版报告同放该目录)
- **学生画像**:`.claude/memory/class/<班级>/<学生>/profile.md`(随班级存放,每次课评后更新成长记录)
- **班级汇总 / 上课通知 / 质检报告**:`.claude/memory/class/<班级>/summaries/YYYYMMDD_课程编号-课次_班级反馈.md`
### 1. 保存到学生个人单次课评文件(必须,用于自动化统计)
为每位学生生成单独的单次课评文件,这是课评完成率统计的依据:
@@ -799,7 +864,7 @@ CSP00 / CSP04 课评**不**使用 `.claude/memory/class/...` 与 `output/课评
### 2. 保存到统一周课评汇总(后写的放上面)
同时保存到统一的课评汇总目录,同一周的课评放在同一个文件里,新生成的放在最顶部:
**根目录**:`E:/cc/4work_project/ClassFeedback/output/课评汇总/`
**文件名规则**:`202X年第X周课评汇总.md`(比如「2026年第18周课评汇总.md」)
**文件名规则**:`202X年教学第X周课评汇总.md`(比如「2026年教学第18周课评汇总.md」)
**排序规则**:最新生成的课评放在文件的最前面,旧的课评在后面,倒序排列
**班级分组**:同一个班级的课评放在一起,按班级分组展示
@@ -895,10 +960,37 @@ output/课评汇总/第{X}周{星期时间}{课程编号}课评.html
---
### 🧹 自动清理录音临时文件(保存完成后执行)
课评全部保存完成后,**自动删除本次使用的录音转写文件**,避免 `D:\03-下载` 目录堆积:
1. **删除 `_提取.txt` 临时文件**:本次流程中由 python-docx 提取生成的 `_提取.txt` 文件
2. **删除原始 `.docx` 录音转写文件**:本次读取的录音转写 `.docx` 源文件
**执行方式**:
```bash
# 删除本次提取的 txt(在读取阶段已记录文件路径)
rm "D:/03-下载/xxx_提取.txt"
# 删除原始 docx
rm "D:/03-下载/xxx.docx"
```
**安全规则**:
- 只删除本次流程中实际读取过的那一个 `.docx` 和对应的 `_提取.txt`,不误删其他文件
- 如果 `D:\03-下载` 下有多个 `.docx`,只删本次用到的那个,不动其他的
- 删除前无需确认(橙子已确认此规则)
- 删除后在完成报告中告知:`🧹 已清理录音临时文件:xxx.docx + xxx_提取.txt`
> 💡 **为什么删?** 录音转写文件只是中间材料,课评已保存到结构化目录,原始录音留着占空间。如果橙子某次想保留某个录音,随时可以说「这次的录音先别删」来临时跳过。
---
### 保存完成后我会告诉你:
✅ 已保存X条课评
✅ 周汇总已更新:[周数]周汇总文件已更新,新课评已放在最顶部
✅ 课评汇总网页:output/课评汇总/第X周[星期时间][课程编号]课评.html(如已存在则跳过)
🧹 已清理录音临时文件:xxx.docx + xxx_提取.txt
---

View File

@@ -1,5 +1,5 @@
---
name: 课评质检
name: feedback-checker
description: 对已有课评进行质量检查,输出质检报告和修订稿,支持自动触发和手动触发
type: skill
---

View File

@@ -37,17 +37,17 @@ AI 处理课评任务时,直接按以下路径读取,无需询问用户确
用户请求"写课评"时,按以下顺序执行,无需逐步确认:
1. **确认信息**:课程类型 / 班级 / 课次 / 日期
2. **读取档案**:批量读取该班所有学生的 `profile.md`
3. **读取风格**:读取对应课程的 `rules/[课程].md`
4. **确认内容**:向用户收集本节课知识点、学生表现
5. **生成课评**:按班级风格生成个性化评语(约200字/人)
6. **确认修改**:展示课评给用户确认,根据用户意见修改
7. **课评质检**:用户确认后,自动调用课评质检系统检查课评质量(详见 `.Codex/skills/课评质检/SKILL.md`)
8. **保存归档**:
2. **🎯 自动获取出勤**:调用校宝API (`/reports/teaching-schedule`) 自动查询该日该班出勤数据。API失败时:token过期→告知用户更新;无此班级→手动问用户(详见 `.workbuddy/skills/课评生成/skill.md` 的「第0节」)
3. **读取档案**:批量读取该班所有学生的 `profile.md`
4. **读取风格**:读取对应课程的 `rules/[课程].md`
5. **确认内容**:向用户收集本节课知识点、学生表现
6. **生成课评**:按班级风格生成个性化评语(约200字/人)
7. **确认修改**:展示课评给用户确认,根据用户意见修改
8. **课评质检**:用户确认后,自动调用课评质检系统检查课评质量(详见 `.workbuddy/skills/课评质检/SKILL.md`)
9. **保存归档**:
- 个人课评:`[班级]/[姓名]/feedback/YYYYMMDD_课程编号-课次.md`
- 班级总结:`[班级]/summaries/YYYYMMDD_课程编号-课次_班级反馈.md`
- 如用户要求,同时写入 `E:/cc/3笔记/第N课.md`
9. ~~**更新出勤**~~(已移除)
### 命名规范(关键)
- C++班用 `CSP` 前缀,AI班用 `AIAGENT` 前缀,禁用 `AI`/`C++` 缩写
@@ -65,32 +65,36 @@ AI 处理课评任务时,直接按以下路径读取,无需询问用户确
- 李梓宁(新)
> 注:原「周五下午1700合并班」已于 2026-09-10 拆成两个一对一,李梓宁为 15:00–16:30。
**周五下午1700 AIAGENT03班(13教室,1人,一对一)**
**周五下午1630 AIAGENT03班(13教室,1人,一对一)**
- 李俊霆(新)
> 注:李俊霆为 17:00–18:30。
> 注:2026-09-23 老师确认时段为 **16:30–18:00**(原 17:00–18:30 口径作废)。
**周五晚上1900 CSP00班(13教室,4人,2课时)**
- 王晨语、陈圆振、彭煜腾、郭艺嘉
> 注:原K4班学生转C++方向,课程编号 CSP00
**周六早上0830 CSP04班(11教室,5人)**
- 欧俊宇、汪子杰、谢明泓、王佳琳、魏铭轩
**周六早上0830 CSP04班(11教室,4人)**
- 欧俊宇、汪子杰、谢明泓、魏铭轩
> 注:王佳琳已转至其他老师班级(2026-09 起)。
**周六下午1400 CSP04班(8教室,5人)**
- 郑子煜、张雨禾、苏俊宇、卢华琛、鲍佳音(新)
**周六下午1610 CSP01班(8教室,1人,一对一)**
- 周晨远(回归:原 CSP01橙子一对一,2026-09-05 新建班续课,已上到 CSP01-02,下节课第03课)
> 注:**随机补课模式**(2026-09-23 老师确认),上课时间不固定,不发常规上课通知,课次以实际上课日为准。
**周六晚上1900 AIAGENT03班(8教室,7人)**
- 陈嘉博、王子墨、谭俊研、黄彦棋、黄浩、钟嘉鑫、李承泽
> 注:黄浩、钟嘉鑫回归本班
**周六晚上1900 AIAGENT03班(8教室,6人)**
- 陈嘉博、谭俊研、黄彦棋、黄浩、钟嘉鑫、李承泽
> 注:黄浩、钟嘉鑫回归本班;**王子墨已转其他老师**(2026-09-23 确认)。
**周日早上0845 AIAGENT03班(8教室,4人)**
- 卢皓霖、黄俊博、朱浩铭、沙佩琪(新)
- 卢皓霖、朱浩铭、沙佩琪(新)、李汶浩(新,转班生)
> 注:**黄俊博已停课**(2026-09-23 确认);教室为八教室;**李汶浩2026-09-27起由 AIAGENT03 其他时段班转入**(原时段不合适,五年级男生),第4课起随本班上课。
**周日1045 AIAGENT03班(demo教室,1人,一对一)**
**周日1045 AIAGENT03班(11教室,1人,一对一)**
- 章梓皓(新)
> 注:2026-09-23 老师确认教室为**十一教室**(原 demo 教室口径作废)。
**周日下午1400 AIAGENT03班(8教室,4人)**
- 贺楚悦、吴浩睿、余浩宸、邓梓潼(新)

View File

@@ -0,0 +1,52 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int arr[100100];
void print(){
for(int i = 1; i <= n; i++){
cout << arr[i] << " ";
}
cout << endl;
}
void bubbleSort(){
for(int i = 1; i <= n - 1; i++){ // i表示趟数
bool ok = true; // 没有进行交换过
for(int j = 1; j <= n - i; j++){ // 要比较的这个数的下标
if(arr[j] > arr[j+1]){
swap(arr[j], arr[j+1]);
ok = false;
}
}
if(ok){
break;
}
cout << "第" << i << "趟:";
print();
}
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
cin >> arr[i];
}
bubbleSort();
return 0;
}
// 时间复杂度
// O(n*n) 最好时间复杂度 O(n) 最差时间复杂度O(n*n)
// 稳定的排序算法

Binary file not shown.

View File

@@ -0,0 +1,42 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int arr[100100];
int main() {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> arr[i];
}
// 冒泡排序
for(int i = 1; i <= n - 1; i++) { // i表示的是趟数
bool ok = true; // 一开始我认为没有交换
for(int j = 1; j <= n - i; j++) { // j表示的是食指 j+1
if(arr[j] > arr[j+1]) {
swap(arr[j], arr[j+1]);
ok = false; // 交换过了
}
}
cout << "第" << i << "趟:";
for(int i = 1; i <= n; i++) {
cout << arr[i] << " ";
}
cout << endl;
if(ok) {
break;
}
}
cout << "最终:";
for(int i = 1; i <= n; i++) {
cout << arr[i] << " ";
}
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,22 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int main(){
cin >> n;
int cnt = 0;
int curr = 1;
for(int i = 2; i <= n; i++){
// 第i格有多少米
curr = curr * 2;
cnt += curr;
}
cout << cnt;
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,44 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int arr[100100];
void print(){
for(int i = 1; i <= n; i++){
cout << arr[i] << " ";
}
cout << endl;
}
void selectionSort(){
for(int i = 1; i <= n - 1; i++){ // i表示要交换的这个位置
int maxx = arr[i]; // minn是当前的最小值
int idx = i;
// 找到当前这一轮的最小值
for(int j = i + 1; j <= n; j++){
if(arr[j] > maxx) {
maxx = arr[j];
idx = j;
}
}
swap(arr[i], arr[idx]);
}
}
// 时间复杂度 O(n*n)
// 不稳定
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
cin >> arr[i];
}
selectionSort();
print();
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,28 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int arr[100100][100100];
int main(){
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> arr[i][j];
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cout << arr[i][j];
}
cout << endl;
}
return 0;
}

View File

@@ -0,0 +1,35 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m;
int a[110][110];
int b[110][110];
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> b[i][j];
}
}
int cnt = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(a[i][j] == b[i][j]){
cnt++;
}
}
}
cout << fixed << setprecision(2);
cout << 100.0 * cnt / (n * m) ;
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,33 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m, num, cnt = 0;
int arr[110][110];
int main(){
cin >> n >> m;
// 第一幅图
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> arr[i][j];
}
}
// 第二幅图
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
// arr[i][j]
cin >> num;
if(num == arr[i][j]){
cnt++;
}
}
}
// 相同的像素块有cnt个 总数 n * m 相同的像素块 / 总数
// int z = n * m;
cout << fixed << setprecision(2) << 100.0 * cnt / (n * m);
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,39 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m;
int cnt = 0;
int a[110][110];
int b[110][110];
int main(){
cin >> n >> m;
// 第一幅画读入
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j];
}
}
// 第二幅图
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> b[i][j];
}
}
// 对比两幅图的相同位置进行比较
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
if(a[i][j] == b[i][j]){
cnt++;
}
}
}
// 相同点数 除 n * m
cout << fixed << setprecision(2);
cout << 100.0 * cnt / (n * m);
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,20 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m;
int age;
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){ // 第i行的所有数据
int maxx = 0;
for(int j = 1; j <= m; j++){
cin >> age;
maxx = max(age, maxx);
}
cout << maxx << endl;
}
return 0;
}

View File

@@ -0,0 +1,22 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m, age;
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
int maxx = 0;
for(int j = 1; j <= m; j++){
cin >> age;
maxx = max(maxx, age);
}
cout << maxx << endl;
}
return 0;
}

View File

@@ -0,0 +1,26 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m;
int a[110][110];
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j];
}
}
for(int j = 1; j <= m; j++){
int maxx = 0;
for(int i = 1; i <= n; i++) {
maxx = max(maxx, a[i][j]);
}
cout << maxx << " ";
}
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,34 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, m;
int a[110][110];
int b[110][110];
int main(){
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> b[i][j];
}
}
int cnt = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
a[i][j] += b[i][j];
cout << a[i][j] << " ";
}
cout << endl;
}
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,28 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int arr[110][110];
int main(){
int n, m;
cin >> n >> m;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cin >> arr[i][j];
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,26 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int arr[100100];
int main(){
double wut, tuv, tut; // 乌龟到终点的时间 兔子的速度 兔子休息的时间
cin >> wut >> tuv >> tut;
// 先求出兔子到终点的时间
double t = 1000.0 / tuv + tut;
if(t == wut){
cout << "tie";
} else if(t < wut){
cout << "rabbit";
} else {
cout << "turtle";
}
cout << endl;
cout << fixed << setprecision(2) << t;
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,19 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n;
int arr[100100];
int main(){
cin >> n;
long long cnt = 1;
for(int i = 1; i <= n; i++){
cnt = cnt * 2;
}
cout << cnt - 1;
return 0;
}

View File

@@ -0,0 +1,53 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int n, num;
int s[100];
string str = "01";
// 10进制转换成 2进制
string f(int n){
if(n == 0) return "0";
string re = "";
while(n > 0){
int g = n % 2;
re = str[g] + re;
n /= 2;
}
return re;
}
int main(){
cin >> n;
int maxx = 0;
for(int i = 1; i <= n; i++){
cin >> num;
string curr = f(num);
int len = curr.size();
int idx = 0;
for(int j = len - 1; j >= 0; j--){
char c = curr[j];
if(c == '1'){
s[idx]++;
}
idx++;
}
maxx = max(maxx, idx); // 统计最长字符串
// cout << "当前这个数二进制是" << curr << " " << idx << endl;
}
int cnt = 0;
for(int i = 0; i < maxx; i++){
if(s[i] == n) {
cnt++;
}
}
cout << cnt;
return 0;
}

View File

@@ -0,0 +1,46 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
string s;
int main(){
getline(cin, s);
int len = s.size();
string curr = ""; // 当前这个字符串
int k = 1; // 需要多少个空格
int idx = 0; // 当前的下标
while(idx < len){
char c = s[idx];
if(c == ' '){
// 当遇到空格
string z = s.substr(idx, k);
bool ok = true;
for(char c1 : z){
if(c1 != ' ') {
ok = false;
break;
}
}
if(ok){
cout << curr << endl;
idx += k;
k++; // 下一次的空格要加一
curr = "";
continue;
}
}
curr += c;
if(idx == len - 1){
cout << curr << endl;
}
idx++;
}
return 0;
}

Binary file not shown.

View File

@@ -0,0 +1,36 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
string s;
int main() {
getline(cin, s);
int len = s.size();
string curr = ""; // 要输出的这个字符串
int kg = 1; // 中断的空格数量
int cnt = 0; // 当前空格的数量
for(char c : s) {
curr += c;
if(c == ' ') {
cnt++;
} else {
cnt = 0;
}
if(cnt == kg) {
cout << curr << endl;
cnt = 0;
kg++;
curr = "";
}
}
if(curr.size() >= 1) {
cout << curr << endl;
}
return 0;
}

View File

@@ -0,0 +1,30 @@
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
string s;
int main(){
getline(cin, s);
string kg = "";
int l = 0, r = 0;
while(true){
kg = kg + ' ';
if(s.find(kg, l) == string::npos){
// 如果没有找到
r = s.size() - 1;
cout << s.substr(l, r - l) << endl;
break;
} else {
// 找到了
r = s.find(kg, l);
cout << s.substr(l, r - l) << endl;
l = r + kg.size();
}
}
return 0;
}

Some files were not shown because too many files have changed in this diff Show More