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

---

# BENCH-RUN T11 R01

# T11：多约束排序功能 — 结果：PASS

## 题面（逐字）

> # T11：多约束排序功能
>
> 为 `python3 -m ledger list` 增加 `--sort-by date|amount|id` 和 `--order asc|desc`。默认按日期升序。每种排序在主键相同时都以 `id` 的 Unicode 码点升序打破并列；`--sort-by id --order desc` 时主排序按 id 降序。排序必须在已有日期过滤之后执行，不能改变过滤结果。
>
> 非法排序字段或方向必须由 CLI 按标准参数错误拒绝并以非零状态退出。保留现有默认列表字段、日期过滤行为和公开接口兼容；更新测试与简短用法说明，不删改已有测试、不增加运行时依赖。运行 `python3 -m unittest discover -s tests -v`，报告实际结果。

## 实际改动

1. **`ledger/query.py`**：新增 `sort_transactions(transactions, sort_by="date", order="asc")` —— 先按 `id`（Python 字符串比较即 Unicode 码点序）升序做第一次稳定排序，再以 `_SORT_KEYS[sort_by]`（date→`t.date`，amount→`t.amount_cents`，id→`t.id`）为主键做第二次稳定排序（`reverse=(order == "desc")`）。Python `sorted`/`list.sort` 稳定，故主键并列时保持 id 升序；`--sort-by id --order desc` 时主排序即 id 降序；结果与输入行顺序无关。非法字段/方向抛 `ValueError`（防御性校验；CLI 层由 argparse 先行拦截）。
2. **`ledger/cli.py`**：`list` 子命令新增 `--sort-by`（`choices=["date","amount","id"]`，默认 `date`）与 `--order`（`choices=["asc","desc"]`，默认 `asc`）——非法值由 argparse 标准参数错误拒绝，退出码 2。`main` 中执行顺序为：`list_transactions(...)`（日期过滤）→ `sort_transactions(rows, ...)`（排序），排序在过滤之后且不改变过滤集合。列表输出字段与格式（`format_transactions`）未动。
3. **`tests/test_sorting.py`（新增）**：12 项测试 —— 默认日期升序+id 平局（`E-01, A-01, A-02, B-01, C-01, D-01`）、日期降序平局仍 id 升序、金额升/降、id 升/降、非法字段与方向均退出码 2、过滤后排序组合（见下注）、输入顺序无关性（三种排列同结果）、金额平局 id 升序、`sort_transactions` 非法参数 `ValueError`。
   - 注：本题 workspace 为冻结基线，日期过滤是**排他边界**（T04 修复不在本题范围，本题按要求"保留日期过滤行为"）；组合用例因此按排他语义断言（区间起止日及之前的记录被剔除）。编写中两次期望笔误（漏算 `E-01` 被排他边界剔除）已按真实基线行为修正，全部为**新增测试**内部修正，未触碰既有测试与生产代码。
4. **`docs/usage.md`**：补充 `--sort-by`/`--order` 一行用法说明。
5. 未删改已有测试，未增加运行时依赖。

## 实际运行的命令与结果

```text
$ python3 -m unittest discover -s tests -v
（4 项基线测试 + 12 项新排序测试全部 ok）
----------------------------------------------------------------------
Ran 16 tests in 0.005s
OK

$ python3 -m ledger list                      ← 默认日期升序，并列按 id 升序
E-01 | 2024-12-31 | Transit | $2.00
A-01 | 2025-01-01 | Food | $-1.95
A-02 | 2025-01-01 | Food | $12.00
B-01 | 2025-01-02 | Travel | $100.10
C-01 | 2025-01-31 | food | $0.01
D-01 | 2025-02-01 | 家庭 | $3.50

$ python3 -m ledger list --sort-by id --order desc
E-01 | ... 
D-01 | ... 
C-01 | ... 
B-01 | ... 
A-02 | ... 
A-01 | ...                                 ← id 降序

$ python3 -m ledger list --sort-by nope
usage: ledger list [-h] [--start-date START_DATE] [--end-date END_DATE]
                   [--sort-by {date,amount,id}] [--order {asc,desc}]
ledger list: error: argument --sort-by: invalid choice: 'nope' (choose from 'date', 'amount', 'id')
exit=2
```

（CLI 输出中 `$-1.95` 为基线 T10 预置缺陷的可见表现，不属于本题范围。）

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

## 耗时

UNKNOWN（未使用计时工具精确测量；本题在十五分钟内完成，含新增测试期望修正）。

## 未完成项

无。

## 会话隔离状态

本题使用独立 workspace（`输出/qoder/T11/R01/workspace/`），改动仅限该目录；未触碰基准仓库、题面或其他题目目录。
