feat(core): 实现 Result 的 __repr__ 与 summary

L0 第 1 项落地。

- __repr__:单行紧凑;data 只给类型与规模(ndarray(100000)),
  绝不整数组打印;__repr__ 永不抛异常
- summary():可直接贴进论文的 Markdown 表格,
  行序 success → params.* → metrics.* → extras.*(按插入顺序,不排序),
  float 走 .6g,竖线转义,message 以引用行附在表后
- 新增 5 个模块级私有辅助:_fmt_scalar / _fmt_cell / _fmt_mapping /
  _describe_data / _truncate
- tests/test_core.py:去掉 test_result_repr_is_readable 的 skip,
  并补 3 条行为测试(默认值与失败路径与十万级数组、Markdown 结构、幂等)
- STATUS.md:L0 进度 1/12;新增决策 21(repr 不打印 data 内容)、
  22(summary 行序不排序);CHANGELOG.md 同步
This commit is contained in:
guzhujushi committed 2026-10-01 18:48:43 +08:00
1 parent bcdbdd35a3
commit cb96c847dd
4 files changed
+162 -13

No files matched your search

+22 -5
View File
@@ -58,18 +58,32 @@
- [x] 推送通道:公网 22 被防火墙过滤 → 改用 Tailscale(`100.115.86.48:22`),
`~/.ssh/config` 加了一条域名别名,remote 里仍写域名
**E. L0 实现进度(1/12)**
- [x] `core/result.py` 的 `Result`
- `__repr__`:单行紧凑;`data` 只给类型与规模,**绝不**整数组打印
(十万级数组的 repr 实测仍 < 200 字符);`success` 恒在
- `summary()`:Markdown 表格,可直接贴进论文;
行序 `success` → `params.*` → `metrics.*` → `extras.*`;
float 走 `.6g`,`|` 转义,`message` 以引用行附在表后;幂等无副作用
- 测试:`tests/test_core.py` 去掉 skip + 新增 3 条
(默认值/失败路径/大数组、Markdown 结构、可重复调用)
- [ ] 剩余 11 项(13 个函数):`get_rng` `set_seed` `load_table` `clean_missing`
`detect_outliers` `normalize` `standardize` `describe` `correlation_matrix`
`bootstrap_ci` `monte_carlo` `save_figure`
### 验证结果
| 检查 | venv | conda `mcm-toolkit` |
|---|---|---|
| `pytest` | 20 passed, 49 skipped | 20 passed, 49 skipped |
| `pytest` | 24 passed, 48 skipped | 24 passed, 48 skipped |
| `import mcm_toolkit` | 0.0.1 / 16 项 | 0.0.1 / 16 项 |
| `ruff check` | All checks passed | — |
| `ruff check` | All checks passed | All checks passed |
| `scripts/doctor.ps1` | 跑通 | — |
| SALib / pymoo / pyright | 缺失 | 已装 |
- base 亦已复核:numpy 2.4.6 / scipy 1.18.1 / pandas 3.0.6(与两套环境一致)
- skip 的都是等实现的算法行为测试;通过的 20 条是 `tests/test_api_surface.py` 的公开 API 契约测试
- skip 的都是等实现的算法行为测试;通过的 24 条 = 20 条公开 API 契约测试
(`tests/test_api_surface.py`)+ 4 条 `Result` 行为测试(`tests/test_core.py`)
- 三个 `.ps1` 通过 PowerShell AST 语法解析
### ⚠️ 需要注意 / 遗留
@@ -79,7 +93,8 @@
只差 Python 补丁号(3.13.9 vs 3.13.15)。详见 `docs/04-environment.md` §5。
- [x] ~~Gitea 远程尚未配置~~ → **已配置并推送完成**,见上面 D 节与决策 19/20。
note:仓库当前是 **Public**(匿名 `git ls-remote` 可读),要改私有去 Gitea 仓库设置。
- [ ] 所有函数实现尚未开始(按 L0 → L1 顺序,见 `docs/03-roadmap.md`)
- [ ] L0 完成 1/12(`Result`),其余按 `docs/03-roadmap.md` 的 L0 → L1 顺序推进;
详情见上面 E 节
- [ ] 本机 `exec_command` 在沙箱模式下**完全不可用**
(`helper_unknown_error: setup refresh had errors`),只有提权
(`require_escalated`)模式可用。沙箱模式只允许写 `D:\MCM&ICM_Toolkit`。
@@ -114,11 +129,13 @@
| 18 | `core.autocrlf=false`(仓库级) | 配合 `.gitattributes` 的 LF 策略,避免 Windows 上 checkout 又转成 CRLF |
| 19 | Gitea 的 SSH **走 Tailscale 内网**,不在公网开 22 | 实测公网 `8.145.36.108:22` 超时(服务器侧过滤,本机出站 22 没被封:github.com:22 可通),而 Tailscale `100.115.86.48:22` 可达且 `git@` 认证直接过 Gitea。remote 里仍写域名,域名→内网 IP 的映射放在 `~/.ssh/config`,换机只改一处 |
| 20 | 首次推送用 `--force-with-lease` **覆盖** Gitea 的 `Initial commit` | 远端那个提交是建仓时自动初始化产生的,与本地无共同祖先,普通 push 必被拒。推送前已把其中的 LICENSE 与手写简介并入本地 `README.md`,原提交仍留在本机对象库(`1c683cf`) |
| 21 | `Result.__repr__` **不打印 `data` 内容**,只给类型与规模 | 模拟轨迹动辄十万个数,repr 一旦刷屏,traceback / 调试器 / notebook 输出就全废了。要看数据请直接取 `result.data` |
| 22 | `Result.summary()` 的行序 = 字典插入顺序,不排序 | 比赛时"想先看哪个指标"自己决定键的插入顺序即可,工具不该替人排序 |
## 下一步
1. ~~接入 Gitea~~ **已完成**。以后推送前先确认 Tailscale 在线,然后 `git push`
(细节与换机步骤见 `docs/05-git-workflow.md` §3)。
2. 按 `docs/03-roadmap.md` 的 **L0(12 个函数)** 顺序填实现,先写测试再写代码。
2. 继续 L0,**下一个:`core/random.py` 的 `get_rng` / `set_seed`**(先写测试再写代码)。
3. 每写完一个函数,在 `examples/` 里加一行最小用法,并更新本文件。
4. L0 跑通后,找一道真题(建议 2025 C)走完整流程,反向沉淀函数。