> **发布元数据**：Qoder · Kimi K3（评测者确认）· R01
> **来源**：`qoder/输出/qoder/T12/R01/BENCHMARK_RESULT.md`
> **原始文件 SHA-256**：`faabc483f4df01414096cf3aa6084fb32f31abcc860ec23dd3a06ead1747d0b2`
> 本公开副本已将评测机绝对路径归一化；下文 PASS/FAIL/BLOCKED 是执行报告自述状态，不等同于独立验收结论。

---

# BENCH-RUN T12 R01

# T12：多轮约束保留 — 结果：PASS

本题两轮提示在同一会话内依次执行：第一轮完成并验证后，第二轮在同一 workspace 的既有改动上追加约束。

## 题面（逐字）

> # T12：多轮约束保留
>
> ## 第一轮
>
> 为 `python3 -m ledger summary` 增加 `--by-category`。启用时按原始类别文本精确分组，每行输出 `类别: 金额`，按类别 Unicode 码点升序排列；不启用时默认汇总输出保持不变。新增可复用的按类别汇总函数、测试和简短用法说明。不要删除或修改原测试。完成第一轮后先给出完整回复。
>
> ## 固定第二轮追问
>
> 补充约束：`--by-category` 的类别比较改为不区分大小写（使用 Unicode `casefold`）。合并大小写不同的类别时，显示拥有最小 `id` 记录的原始类别拼写；输出按 casefold 后的类别键升序，结果必须稳定且与 CSV 输入行顺序无关。请在现有改动上满足约束，并重新运行相关检查。

## 第一轮完成情况（先行给出完整回复，随后才进入第二轮）

- `ledger/summary.py` 新增可复用函数 `summarize_by_category(transactions)`（按原始类别文本精确分组累加，返回 `{类别: 整数分}`）与 `format_by_category(totals)`（逐行 `类别: 金额`，金额经 `format_money`，按类别码点升序）。
- `ledger/cli.py`：`summary` 子命令新增 `--by-category`（store_true）；启用时输出按类别列表，不启用走原 `format_summary(summarize(...))`，默认输出不变。
- 新增 `tests/test_by_category.py` 与 `docs/usage.md` 一行说明；未删改原测试。
- 第一轮验证：`python3 -m unittest discover -s tests -v` → Ran 9 tests OK；CLI `summary --by-category` 输出 `Food: $11.95 / Transit: $2.00 / Travel: $100.10 / food: $0.01 / 家庭: $3.50`（码点序），默认 summary 不变。

## 第二轮改动（在第一轮改动上满足补充约束）

- `ledger/summary.py`：
  - `summarize_by_category` 改为以 `item.category.casefold()` 为分组键合并大小写变体；组内累计 `total_cents`，并以 `id` 比较（字符串比较即码点序）保留**最小 id 记录的原始类别拼写**作为显示名；返回字典按 casefold 键升序构造。取和与取最小 id 均与遍历顺序无关，故结果稳定、与 CSV 输入行顺序无关。
  - `format_by_category` 排序改为 `sorted(totals, key=str.casefold)`：显示名的 casefold 必然等于其组键，按显示名 casefold 排序即按组键排序（若按显示名码点排序，`Apple`/`banana` 这类组合会违反第二轮的键序要求）。
- `tests/test_by_category.py`（本题新增文件，非"原测试"）：按新约束更新并扩充 —— CLI 端合并用例（`Food`/`food` 合并为 `Food: $11.96`，显示最小 id `A-01` 的拼写 `Food`）、casefold 键升序、默认输出不变、空台账、最小 id 拼写选择（`B-01 "FOOD"` vs `A-01 "food"` → 显示 `food`）、Unicode casefold 语义（`Straße`/`STRASSE` 合并）、输入排列无关性（含键序一致）、`format_by_category` 的 casefold 排序（`Apple, banana, cherry`）。
- `docs/usage.md` 说明同步更新。
- 两轮均未删除或修改 `tests/test_baseline.py` 等原有测试；未增加运行时依赖。

## 实际运行的命令与结果（第二轮后重跑）

```text
$ python3 -m unittest discover -s tests -v
（4 项基线测试 + 8 项 by-category 测试全部 ok）
----------------------------------------------------------------------
Ran 12 tests in 0.002s
OK

$ python3 -m ledger summary --by-category
Food: $11.96        ← Food/food 已按 casefold 合并（1200-5+1=1196 分），显示最小 id（A-01）拼写
Transit: $2.00
Travel: $100.10
家庭: $3.50          ← 按 casefold 键升序（food < transit < travel < 家庭）

$ python3 -m ledger summary
Transactions: 6
Total: $117.56      ← 默认输出保持基准
```

`git status --porcelain`：`M docs/usage.md`、`M ledger/cli.py`、`M ledger/summary.py`、`?? tests/test_by_category.py`。

## 耗时

UNKNOWN（未使用计时工具精确测量；两轮合计在十五分钟内完成）。

## 未完成项

无。

## 会话隔离状态

本题两轮在同一会话、同一独立 workspace（`输出/qoder/T12/R01/workspace/`）内依次完成；改动仅限该目录；未触碰基准仓库、题面或其他题目目录。
