Commit Graph
6 Commits
Author SHA1 Message Date
guzhujushi 3432bf3e50 fix(stats): correlation_matrix 修硬 bug,两处 pyright 报错按坑 8/10 正经修(无 ignore)
用户报的是"63 行 p 值赋值报错"。查下来:63 行运行完全正常(p 是 np.float64),
pyright 那条是 scipy 存根的缺陷。但顺着看发现了真正跑不起来的第 41 行。

correlation_matrix:
- 硬 bug: `if numeric_cols == 0` 拿 Index 和标量比 -> 得到布尔数组。
  0 列时静默不报错、1 列时碰巧能跑、>=2 列直接 ValueError 崩(而 >=2 列正是常见情况)。
  改成 len(numeric_cols) == 0,并加回归用例
- pyright 两处报错都不是运行时问题,且一处 # type: ignore 都没挂:
  - data[numeric_cols] 是坑 8 的 DataFrame | Series 重载 -> cast 收窄
  - `_, p = stats.pearsonr(...)` 解包退化成 object(scipy 的返回值是 _make_tuple_bunch
    运行时拼的类,存根里没有 pvalue)-> 新增 _pvalue(result: Any) -> float 小助手统一取,
    后面 t_test / anova / chi_square_test 可复用
- method 校验提到最前;add_stars 的 elif 链改 if;清掉 3 条 F541 与 1 条 I001,ruff 归零
- 顺带记录两处待定:对角线被标了 ***;含 NaN 时 corr 成对删失而 pearsonr 不删,r 与 p 对不上

tests:
- test_correlation_matrix_diagonal_is_one 由 skip 改成 xfail(strict=False)(决策 30):
  契约要数值矩阵、实现返回带星标字符串表,口径待拍板
- 新增 2 条:多列数值表能跑通、非法输入报错

验证: pytest 105 passed / 38 skipped / 1 xfail;ruff All checks passed;pyright 0 errors。

docs: STATUS.md(correlation_matrix 进行中 + 决策 40 + 下一步 A/B/C 选项);CHANGELOG;
      personal-pitfalls 追加第 13 条(Index == 标量 得到布尔数组);
      docs/04-environment.md 追加坑 10(scipy 检验结果的存根缺陷)
2026-10-03 14:45:10 +08:00
guzhujushi 6eab0babde feat(data): transform.py 四个函数落地;补 18 条测试、清 5 条 ruff
实现(用户本人写):
- normalize(minmax / vector / max,三种都按列)+ feature_range 校验 + 常量列不出 nan
- standardize(按列,ddof 真的传下去)+ 类型守卫
- log_transform(offset=None 时自动取 1 - min(x),保证 x + offset >= 1)+ 类型守卫
- one_hot_encode(自动识别对象列 / 指定列 / drop_first)
- data/ 下的 L0 至此结清(L0 7/12)

Codex 的轻度修复(不改接口与语义):
- 清掉 5 条 ruff:RET503 / F541 / RET504 / RET505 / SIM108
- supported_method 与 feature_range 的校验提到 np.asarray 之前(守卫集中开头)
- 修掉说反的报错文案(条件是要求下界 < 上界,原文写"上界必须小于下界")
- one_hot_encode 自动识别时显式加上 str / string:只写 object 在 pandas 3 上是弃用路径,
  每次调用发 Pandas4Warning,未来会变成"一列都选不中"的静默错误(详见坑 9)

测试:
- 新写 18 条(transform 段),其中两条是把原先挂着的 skip 转为实跑 ——
  normalize / standardize 的实现此前一条测试都没跑到(详见个人易错点 9)
- 82 passed / 40 skipped / 0 xfailed;ruff 0;pyright 0

文档:
- STATUS.md:E 节 + 验证表(122 条用例分布)+ 下一步重写(transform 待定的 4 个口径)+ 决策 34
- docs/04-environment.md:新增坑 9(pandas 3 的 str dtype 与 select_dtypes 弃用路径,含实测对照表)
- docs/dev/personal-pitfalls.md:只追加第 9 条(实现写完但测试还挂 skip,绿灯是假的)
- CHANGELOG.md:本轮变更 + 记录 transform 待定的 4 个口径
2026-10-02 20:43:03 +08:00
guzhujushi b6dc4bc5a6 feat(data): detect_outliers 收尾(文本列恒 False)+ 补测试与文档
实现(用户本人写 + Codex 轻度收尾):
- 统计量(quantile / mean / std)与掩码写入都收窄到数值列,含文本列的赛题表不再崩
- 非数值列在掩码里恒 False(用户定的语义),docstring Notes 补上这条
- 删掉死代码 data=data.copy():下面的 to_frame()/pd.DataFrame() 本就返回新对象,
  函数全程只读 data,白复制一份;且它排在类型分派之前,会把错误入参的报错
  从 ValueError 变成 AttributeError
- 删掉那行死代码后 pyright 反而暴露 1 个真错:df[Index] 被类型存根当成 Series,
  .std() 于是被判成标量、std.replace(...) 非法。在取列子表处 cast 成 DataFrame
  按运行时真值收窄(详见 docs/04-environment.md 坑 8)

测试:
- test_detect_outliers_survives_text_columns 摘掉 xfail 并加强断言(文本列必须恒 False)
- 新增 test_detect_outliers_all_text_frame_returns_all_false,钉住"整表无数值列"边界
- 58 passed / 2 xfailed  ->  60 passed / 1 xfailed;ruff 0;pyright 0
- 仅剩 1 条 xfail:impute_missing 的 mode 分支就地改调用方的表(要选语义,留给用户)

文档:
- STATUS.md:L0 5/12、验证结果表、下一步重写、新增决策 32(非数值列恒 False)
- docs/04-environment.md:新增坑 8(pandas 存根让 df[Index] 退化成 Series,及三种无效修法)
- docs/dev/personal-pitfalls.md:只追加第 8 条(限制掩码 ≠ 限制统计量)
- CHANGELOG.md:本轮变更
2026-10-02 15:41:08 +08:00
guzhujushi 97a2f95066 fix(env): 钉死 pyright 的分析目标,修掉"无法解析导入 numpy/pandas"
现象:编辑器 / pyright 满屏 reportMissingImports,但 .venv 与 conda 环境里
import numpy, pandas 都正常,pytest 也全过。

根因两层:

1. pyright 没配 venvPath / pythonPath 时会去 PATH 上找 python。本机 PATH 上
   唯一的 python 是 agent-tools 的 shim(Codex 运行时,Python 3.14),没有科学栈。
   pyright --verbose 显示它选了 3.14.6,Search paths 里一个 Anaconda 路径都没有。
   注意持久化的 User/Machine PATH 并没有这一项,是 Codex 进程临时注入的——所以
   "我的终端没问题"和"工具有问题"可以同时成立。
2. .venv 是 --system-site-packages 建的,三方包在 D:\anaconda\Lib\site-packages,
   而 pyright / Pylance 不认 pyvenv.cfg 的 include-system-site-packages,
   只去 .venv\Lib\site-packages 找(那里只有 pip)。
   pyright 不读 pyvenv.cfg,但**认 .pth**。

改动:
- pyproject.toml [tool.pyright]:venvPath = "." / venv = ".venv" /
  pythonVersion = "3.13",并注释了为什么必须写
- scripts/setup-venv.ps1:新增第 [2/4] 步,自动往 .venv 写
  _mcm_base_site_packages.pth 指向该机 base 的 site-packages,换机重建即可
- tests/test_data.py:3 处 isna().all() 断言外面套 bool()(它的类型是
  Series | bool,直接当条件 pyright 报"条件操作数无效");
  2 处故意传错类型的用例加 type: ignore[arg-type]

结果:pyright 17 errors -> 0 errors / 0 warnings;pytest 两套环境均
40 passed, 44 skipped;ruff All checks passed;setup-venv.ps1 通过 AST 解析
(纯 ASCII + LF)。

文档:docs/04-environment.md 新增坑 7(含 pyright --verbose 诊断口诀与
VS Code / PyCharm 的操作步骤)、STATUS 决策 29、CHANGELOG。
2026-10-02 13:36:16 +08:00
guzhujushi 49fd84a2df docs: L0 进度 3/12,记录 zstandard 残骸坑与决策 26/27
- STATUS.md:本次任务拆成「第一阶段已完成 / 第二阶段进行中」;
  L0 3/12;测试计数改为 39 passed / 44 skipped;
  下一步里写明 io.py 待修的两处(mkdir 早于校验、缺 Raises)
- docs/04-environment.md 坑 6:conda 升级留下的 *.conda_trash 残骸目录会被
  Python 当成 namespace package 导入成功(__file__ 为 None),
  pandas 3.0 因此抛 ImportError: Can't determine version for zstandard
  直接打断 pd.read_csv;含排查方法与「改名禁用」的修法
- docs/dev/personal-pitfalls.md:条目 3(注解与 docstring 打架)复发 +1
- 决策 26:未实现的算法逐条 skip,禁用模块级 pytestmark
- 决策 27:zstandard 残骸改名禁用,不删不重装
- CHANGELOG:补 load_table/save_table 与 Fixed 段
2026-10-01 23:11:48 +08:00
guzhujushi 5319589dfd chore: 初始化 MCM/ICM Toolkit 仓库骨架
审查并精简 ChatGPT 的建库建议后落地的第一版骨架,只定接口不写实现。

- 建议审查:14 个包 → 7 个;约 250 个函数 → 约 40 个;5 个 Result 类 → 1 个
  (docs/01-suggestion-review.md)
- docs/:架构、路线图(含永久不做清单)、环境、Git 工作流、函数卡片模板
- src/mcm_toolkit/:core / data / stats / models / solve / decision / viz
  共 23 个模块,均为签名 + docstring + NotImplementedError
- tests/:9 个文件,其中 test_api_surface.py 已通过(20 passed)
- examples/ problems/ notebooks/ figures/ tables/ 骨架
- pyproject.toml(核心依赖 4 个 + 6 组 extras)、environment.yml
- scripts/:setup-venv.ps1(ASCII + LF)、setup-conda.ps1、doctor.ps1
- 环境:.venv(system-site-packages)与 conda 环境 mcm-toolkit 均已建好,
  数值栈版本与 base 完全对齐(numpy 2.4.6 / scipy 1.18.1 / pandas 3.0.6,MKL 后端)
2026-10-01 17:43:48 +08:00