# OJ数据获取规则

> 本文件定义了OJ数据获取和分析的技术规范。

## OJ系统信息

- **平台**: Hydro OJ
- **地址**: https://oj.qonnwolf.com
- **认证方式**: Cookie登录（POST `/login`，`uname` + `password`）
- **凭据来源**: `.env` 文件中的 `OJ_USERNAME` 和 `OJ_PASSWORD`

## OJ课程结构

```
课程 (course) → 课次 (period) → 作业包 (homework) → 题目 (problem)
```

- 课程ID示例：`6975984d71e15346c9e8fdc2`
- 课次ID示例：`69aa50c127e54d3ad7ed7ab7`（HTML中 `period-card` 的 `data-id`）
- 作业包ID示例：`69ad011c27e54d3ad7ef50d0`（homework系统的ID）

## ⚠️ 重要规则

1. **OJ课次编号 ≠ 大纲编号**：OJ可能跳过或重排课次，必须按**标题匹配**
2. **只查A包（课堂练习）**：CSP03班OJ数据**只查询A作业包**，不查B/C包
3. **A包包含多道具体题目**：每个A包通常包含3~5道具体题目（如`CSP0309A1 银行叫号模拟`、`CSP0309A2 模拟发牌`等），需在OJ板块中按具体题目列出
4. **`hw_dict.json` 可能不准确**：如果配置的ID无数据，需要从课程页面重新查找

## 数据获取方式

### 方式1: 运行脚本（推荐，自动获取A包具体题目）

```bash
python scripts/update_feedback_with_oj.py \
  --course CSP03-<课次编号> \
  --title "<课程名称>" \
  --class-name "<班级目录名>" \
  --date <YYYYMMDD> \
  --students "学生1,学生2,学生3"
```

脚本执行流程：
1. 从 `hw_dict.json` 加载A作业包ID（自动过滤B/C包）
2. 访问 `/homework/{hw_id}` 获取A包中的具体题目列表（如`银行叫号模拟`、`模拟发牌`等）
3. 抓取A包提交记录，按**具体题目**分析每个学生的完成情况
4. 输出包含具体题目名称的OJ数据Markdown板块

### 方式2: 手动从作业页面获取

```python
import httpx, re
from pathlib import Path

env = {}
for line in Path('.env').read_text(encoding='utf-8').split('\n'):
    if '=' in line and not line.startswith('#'):
        k, v = line.split('=', 1)
        env[k] = v

client = httpx.Client(base_url=env['OJ_BASE_URL'], follow_redirects=True)
client.post('/login', json={"uname": env['OJ_USERNAME'], "password": env['OJ_PASSWORD']})

# 获取A作业包中的具体题目列表
hw_id = "69acffac27e54d3ad7ef5013"  # CSP03-10A
r = client.get(f'/homework/{hw_id}')
problems = re.findall(r'href="/p/([^"?]+)\?tid=' + hw_id + r'"[^>]*><b>([^<]+)</b>(?:&nbsp;|\s)*([^<]*)</a>', r.text)
# 返回: [("CSP0309A1", "CSP0309A1", "银行叫号模拟"), ...]
```

## ��业ID映射

作业ID存储在 `config/hw_dict.json`，格式为：

```json
{
  "CSP05-03": [
    {"title": "CSP05-03A", "id": "69ad011b27e54d3ad7ef50ca"},
    {"title": "CSP05-03B", "id": "69ad011d27e54d3ad7ef50dd"},
    {"title": "CSP05-03C", "id": "69ad012027e54d3ad7ef50f0"}
  ]
}
```

A/B/C分别对应：课堂练习 / 课后作业 / 拓展练习

## 提交记录解析

从 `/record?tid={homework_id}&page={page}` 或 `/record?p={problem_id}&page={page}` 页面解析HTML获取：
- 学生ID和姓名
- 题目ID和标题
- 判题状态（Accepted→AC, Wrong Answer→WA, 等）
- 提交时间

## 分析指标

对每个学生每题生成：
- **完成状态**: 是否AC
- **提交次数**: 总提交数
- **思考模式**: 一气呵成/调试改进/多次尝试/耐心调试/遇到困难
- **错误分布**: WA/CE/RE/TLE各几次

## 完成率统计规则

- 完成率 = AC的题目数 / 总题目数
- 总题目数以OJ实际为准（不固定）
- 如果只有1个作业包，统计该包内所有题目的完成情况
- 如果有多个作业包，分别统计每类（课堂练习/课后作业/拓展练习）的完成情况
