cswork / AI 辅助编程轮全部练习

重构 · 约 45 分钟

库存报表:一个字符都不能动

src/report.py 里的 stock_report() 会按顺序重放一天的仓库流水(入库、出库、盘点、仓间调拨),然后输出仓库主管每天早上 7 点看的报表:各仓库的库存和货值、低于补货线的商品,以及被拒绝的流水。有个脚本会把这段文本贴进共享表格,按精确的空格位置切列,所以输出一个字符都不能变。

它是一个 130 行的函数。金额格式化复制了三份,名称截断复制了两份,每种流水都是同一个循环里的又一个分支。

把它重构好:

  • stock_report(items, movements) 签名不变,对任何输入返回完全相同的文本,包括被拒绝的流水和它们的问题行;
  • 不改行为,哪怕看起来像是在修 bug(只有空格的仓库名照样算一个仓库);
  • 结构要改到 tests/test_metrics.py 通过为止。

tests/test_metrics.py 用 Python 自带的 ast 模块统计 src/,并在程序输出里把起始代码的数值和你的数值并排打印出来:

指标上限
最长函数的行数25
单个函数或 lambda 里的分支数(if/elif、for、while、条件表达式、推导式里的每个 if、match 的每个 case,and/or 每多一个操作数算一个)8
重复代码块(连续三条语句,或三行以上的 if/for/while,忽略字面量和变量名后比较)1

src/ 里不能用 exec、eval 或 compile:从字符串运行的代码,上面哪一项都量不到。

建议的做法:

  1. 先把两件事分开:应用流水,和生成文本。测试里比较整份报表字符串:只检查某一行的测试,发现不了整列错位。
  2. 每种流水一个小函数;用"类型 → 函数"的字典替换 elif 链。
  3. 每种重复的格式一个辅助函数:金额、表格里的一行。

隐藏测试保留了一份原函数,会在精选的和随机生成的流水上逐字比对整份报表,并且同样检查结构指标。你只能看到通过了几个。

正在打开项目…