Files
pinmap-to-pinlist/docs/modification-assessment-v1.3.md

20 KiB
Raw Permalink Blame History

PinMAP ↔ PinList 双向转换器 — 修改需求评估 v1.3

版本: v1.3
日期: 2026-05-31
评估人: 脚本架构师 (Script Architect)
状态: 待审批
变更: 4 个 Bug 修复 + 4 个功能增强BUG-001004, F005F008


1. 修改需求总览

编号 类型 标题 优先级 复杂度 关联需求
BUG-001 Bug run.bat 换行符 + lines 设置不匹配 Windows F005
BUG-002 Bug 周长计算公式错误 F006
BUG-003 Bug 双向转换未读取模板样式 F007
BUG-004 Bug 不支持循环处理流程 F008
F005 功能 BAT 脚本修复 3 BUG-001
F006 功能 周长公式修复 1 BUG-002
F007 功能 模板读取(双向) 2 BUG-003
F008 功能 循环处理流程 2 BUG-004

2. 当前代码状态分析

2.1 代码库结构v1.2.0

pinmap-to-pinlist/
├── run.bat                          # ✏️ 需修改BUG-001/F005
├── Code/src/
│   ├── main.py                      # ✏️ 需修改BUG-003/F007, BUG-004/F008
│   ├── file_selector.py             # (不变)
│   ├── validator.py                 # ✏️ 需修改BUG-002/F006
│   ├── pinlist_validator.py         # ✏️ 需修改BUG-002/F006
│   ├── pinmap_layout.py             # ✏️ 需修改BUG-002/F006
│   ├── pinlist_parser.py            # (不变)
│   ├── pinmap_generator.py          # (不变)
│   ├── template_reader.py           # (不变)
│   ├── xlsx_writer.py               # (不变)
│   ├── models.py                    # (不变)
│   ├── xls_reader.py                # (不变)
│   ├── xlsx_reader.py               # (不变)
│   ├── pinlist_generator.py         # (不变)
│   └── utils.py                     # (不变)
└── docs/
    ├── bugs.md                      # ✏️ 需更新状态
    ├── features.md                  # ✏️ 需更新状态
    └── modification-assessment-v1.3.md  # 🆕 本文档

2.2 各 Bug 当前代码状态

BUG-001: run.bat 问题

当前 run.bat 内容

@ECHO OFF
chcp 65001 >nul
title PinMAP转PinList -By:LeeQwQ
mode con cols=80 lines=50    ← 问题:含 lines=50
color 0B
cls
cd /d "%~dp0Code\src"
python main.py
echo.
pause
EXIT

问题 1:文件使用 Unix LF 换行符(\nWindows 下应使用 CRLF\r\n)。
问题 2mode con cols=80 lines=50 中的 lines=50 是多余的,需求仅保留 cols=80


BUG-002: 周长公式错误

当前公式3 处代码):

expected_total = 2 * rows + 2 * cols - 4

问题:对于 15×15 网格 + 60 Pin当前公式计算为 2*15+2*15-4 = 56,但用户期望 (15+15)*2 = 60

涉及文件

  1. Code/src/pinlist_validator.pyvalidate_pinlist() 中的周长匹配检查
  2. Code/src/validator.pyvalidate_pinlist_for_map() 中的周长匹配检查
  3. Code/src/pinmap_layout.pycalculate_layout() 中的 total 计算和 LayoutError

数学分析

网格 当前公式 2r+2c-4 新公式 (r+c)*2 说明
4×8 20 24 当前公式少算 4
15×15 56 60 当前公式少算 4
2×2 4 8 当前公式少算 4

新公式 (rows+cols)*2 对所有尺寸均多 4 个 Pin。这意味着布局分配算法也需要相应调整。

布局分配需同步修改

当前分配(pinmap_layout.py

左边: rows 个
下边: cols-1 个
右边: rows-2 个
上边: cols-1 个
总计: 2*rows + 2*cols - 4

新分配((rows+cols)*2

左边: rows 个
下边: cols 个
右边: rows 个
上边: cols 个
总计: 2*rows + 2*cols

这意味着四个角点不再共享,每个角点归属一条边。需重新设计单元格坐标计算逻辑。


BUG-003: 模板读取路径错误

当前代码main.pyrun_list_to_map()

template_style = read_template_styles(filepath)

问题filepath 是用户选择的 PinList 输入文件路径,而非模板文件路径。模板文件应为根目录下的 PinMAP-Template.xlsx

MAP→List 方向run_map_to_list() 当前代码未调用 read_template_styles()PinList 输出直接使用 write_xlsx()(无样式)。

需要修复

  1. List→MAPread_template_styles(filepath) 改为读取根目录模板
  2. MAP→List增加模板读取和样式应用

BUG-004: 无循环处理流程

当前 main() 流程

def main():
    show_banner()
    # 选择方向 → 执行一次转换 → wait_for_exit() → 程序结束

问题:转换完成后直接退出,用户需重新运行程序才能处理下一个文件。

期望流程

启动 → 选择方向 → 处理文件 → [处理完成] → 等待输入下一个文件 / Q 返回主菜单

3. 逐项修改方案


3.1 BUG-001 / F005: BAT 脚本修复

修改范围run.bat1 个文件)

具体修改

  1. 换行符:确保文件使用 CRLF\r\n)换行。写入文件时指定 newline='\r\n'
  2. 去掉 lines=50:将 mode con cols=80 lines=50 改为 mode con cols=80

修改后 run.bat

@ECHO OFF
chcp 65001 >nul
title PinMAP转PinList -By:LeeQwQ
mode con cols=80
color 0B
cls

cd /d "%~dp0Code\src"
python main.py

echo.
pause
EXIT

风险评估

风险 影响 概率 缓解措施
CRLF 写入失败 极低 Python open(path, 'w', newline='\r\n') 保证
去掉 lines 后窗口行数变回默认 确认 默认 300 行缓冲区,足够查看日志

工作量5 分钟


3.2 BUG-002 / F006: 周长公式修复

修改范围3 个文件

文件 修改内容 修改行数
pinlist_validator.py 周长匹配公式 + 错误提示文案 ~5 行
validator.py validate_pinlist_for_map() 周长公式 ~5 行
pinmap_layout.py 边分配计数 + 单元格坐标计算 ~20 行

具体修改

3.2.1 pinlist_validator.pyvalidate_pinlist()

# 修改前:
expected_total = 2 * rows + 2 * cols - 4

# 修改后:
expected_total = (rows + cols) * 2

3.2.2 validator.pyvalidate_pinlist_for_map()

# 修改前:
expected_total = 2 * rows + 2 * cols - 4

# 修改后:
expected_total = (rows + cols) * 2

3.2.3 pinmap_layout.pycalculate_layout()

边分配计数修改

# 修改前:
left_count   = rows
bottom_count = cols - 1
right_count  = rows - 2
top_count    = cols - 1
# total = 2*rows + 2*cols - 4

# 修改后:
left_count   = rows
bottom_count = cols
right_count  = rows
top_count    = cols
# total = 2*rows + 2*cols

单元格坐标计算修改

# 修改前(角点共享):
#   左边:   (r, 0)          r ∈ [1, rows]
#   下边:   (rows, c)       c ∈ [1, cols-1]
#   右边:   (r, cols)       r ∈ [rows-1, 2]  逆序
#   上边:   (1, c)          c ∈ [cols-1, 2]  逆序

# 修改后(角点不共享,每条边独立):
#   左边:   (r, 0)          r ∈ [1, rows]
#   下边:   (rows, c)       c ∈ [1, cols]
#   右边:   (r, cols)       r ∈ [rows, 1]    逆序
#   上边:   (1, c)          c ∈ [cols, 1]    逆序
# 修改后代码:
left_cells   = [(r, 0) for r in range(1, rows + 1)]
bottom_cells = [(rows, c) for c in range(1, cols + 1)]
right_cells  = [(r, cols) for r in range(rows, 0, -1)]
top_cells    = [(1, c) for c in range(cols, 0, -1)]

get_name_cell() 函数修改

# 修改前:
#   left:   (r, c+1)
#   bottom: (r-1, c)
#   right:  (r, c-1)
#   top:    (r+1, c)

# 修改后逻辑不变Name 单元格相对于序号单元格的位置不变)
# 但需确保角点单元格 Name 不冲突

风险评估

风险 影响 概率 缓解措施
布局算法修改引入新 Bug 对 4×8、15×15、2×2 等典型尺寸做单元测试
角点单元格 Name 重叠 修改 get_name_cell() 确保角点 Name 不冲突
已有用户数据不兼容 用户需重新输入正确的 PinList
修改 3 个文件不一致 使用同一公式常量,避免硬编码

工作量1.5 小时


3.3 BUG-003 / F007: 模板读取修复

修改范围1 个文件(main.py

问题根因

  1. List→MAPread_template_styles(filepath) 传入的是输入文件路径,而非模板路径
  2. MAP→List完全没有模板读取逻辑

具体修改

3.3.1 新增模板路径解析辅助函数

def _find_template_path() -> str | None:
    """查找根目录下的 PinMAP-Template.xlsx。
    
    搜索顺序:
    1. 与 run.bat 同级的根目录
    2. 当前工作目录
    """
    # 尝试从 Code/src 回退到根目录
    src_dir = os.path.dirname(os.path.abspath(__file__))
    root_dir = os.path.dirname(os.path.dirname(src_dir))  # pinmap-to-pinlist/
    template_path = os.path.join(root_dir, "PinMAP-Template.xlsx")
    
    if os.path.exists(template_path):
        return template_path
    
    # 回退到当前工作目录
    cwd_template = os.path.join(os.getcwd(), "PinMAP-Template.xlsx")
    if os.path.exists(cwd_template):
        return cwd_template
    
    return None

3.3.2 修改 run_list_to_map()

# 修改前:
template_style = read_template_styles(filepath)

# 修改后:
template_path = _find_template_path()
if template_path:
    template_style = read_template_styles(template_path)
    if template_style:
        print(f"[INFO] 已加载模板样式: {template_path}")
    else:
        print("[WARN] 模板文件存在但解析失败,使用默认样式")
else:
    template_style = None
    print("[INFO] 未检测到模板文件,使用默认样式")

3.3.3 修改 run_map_to_list()

# 在写入 PinList 之前,增加模板读取逻辑:
template_path = _find_template_path()
template_style = None
if template_path:
    template_style = read_template_styles(template_path)
    if template_style:
        print(f"[INFO] 已加载模板样式: {template_path}")

# 写入时:
if template_style is not None:
    write_xlsx_with_style(data, output_path, template_style)
else:
    write_xlsx(data, output_path)

风险评估

风险 影响 概率 缓解措施
模板路径解析错误 多路径回退 + 优雅降级
模板解析失败导致崩溃 template_reader.py 已有 try-except 优雅降级
MAP→List 应用模板样式后 PinList 格式不符合用户预期 模板仅影响样式(字体/边框),不影响数据

工作量1 小时


3.4 BUG-004 / F008: 循环处理流程

修改范围1 个文件(main.py

具体修改

main() 改造为循环结构:

def main():
    show_banner()

    while True:
        # ── Direction selection ───────────────────────────────
        if len(sys.argv) > 1:
            # Legacy mode: 直接文件参数 → MAP→List → 循环
            direction = 1
            filepath = sys.argv[1]
            sys.argv = [sys.argv[0]]  # 清除 argv下次循环进入交互模式
        else:
            print("请选择转换方向:")
            print("  1 — PinMAP → PinList")
            print("  2 — PinList → PinMAP")
            print("  Q — 退出程序")
            print()

            choice = input("请输入选项 (1/2/Q): ").strip().upper()
            if choice == 'Q':
                print("感谢使用,再见!")
                return
            elif choice == '1':
                direction = 1
            elif choice == '2':
                direction = 2
            else:
                print("[ERROR] 无效选项,请输入 1、2 或 Q")
                continue

            filepath = None

        # ── Dispatch ──────────────────────────────────────────
        if direction == 1:
            print()
            print("─" * 40)
            print("  方向: PinMAP → PinList")
            print("─" * 40)
            print()
            run_map_to_list(filepath)
        else:
            print()
            print("─" * 40)
            print("  方向: PinList → PinMAP")
            print("─" * 40)
            print()
            run_list_to_map(filepath)

        # ── 处理完成后循环 ────────────────────────────────────
        print()
        print("=" * 40)
        next_action = input("输入文件名继续处理,或按 Enter 返回主菜单,输入 Q 退出: ").strip()
        if next_action.upper() == 'Q':
            print("感谢使用,再见!")
            return
        elif next_action:
            # 直接处理指定文件(自动检测方向)
            filepath = next_action
            # 根据文件内容自动判断方向,或默认 MAP→List
            direction = 1
        else:
            # 返回主菜单(继续 while 循环)
            pass

同时需要修改 run_map_to_list()run_list_to_map()

将两个函数末尾的 wait_for_exit() 替换为 input("按 Enter 键继续..."),这样处理完成后用户可以继续操作而不是退出。

# 修改前(两处):
wait_for_exit()

# 修改后:
input("按 Enter 键继续...")

但注意wait_for_exit() 仍保留,用于:

  • 致命错误FATAL时的退出
  • 用户未选择文件时的退出
  • 命令行参数模式下最后一次退出

风险评估

风险 影响 概率 缓解措施
循环导致内存泄漏(模块重复 import Python import 有缓存,重复 import 无开销
用户输入 Q 后状态混乱 Q 只在主菜单和处理完成后接受,转换过程中不响应
命令行参数模式与循环模式冲突 命令行参数模式执行一次后清除 argv进入交互循环

工作量1 小时


4. 修改影响矩阵

文件 BUG-001 BUG-002 BUG-003 BUG-004 总改动量
run.bat ✏️ 换行+CRLF, 去lines 2 行
main.py ✏️ 模板路径 ✏️ 循环流程 ~40 行
pinlist_validator.py ✏️ 公式 ~5 行
validator.py ✏️ 公式 ~5 行
pinmap_layout.py ✏️ 公式+布局 ~20 行
合计 1 文件 3 文件 1 文件 1 文件 5 文件

5. 优先级排序

优先级 编号 原因
P0 BUG-002 / F006 核心公式错误,所有 List→MAP 转换均受影响
P1 BUG-001 / F005 影响 Windows 用户体验,修复简单
P2 BUG-003 / F007 功能增强,模板样式对输出质量有影响
P2 BUG-004 / F008 体验优化,批量处理场景需要

6. 工作量估算

任务 文件 预估时间 依赖
BUG-001/F005 run.bat 5 分钟
BUG-002/F006 pinlist_validator.py, validator.py, pinmap_layout.py 1.5 小时
BUG-003/F007 main.py 1 小时
BUG-004/F008 main.py 1 小时
文档更新 bugs.md, features.md 10 分钟

总计预估:约 3 小时


7. 推荐开发顺序

第1轮独立可并行
  BUG-001/F005: BAT 脚本修复5 分钟,任何 Agent

第2轮核心必须最先
  BUG-002/F006: 周长公式修复1.5 小时,需理解布局算法)

第3轮独立
  BUG-003/F007: 模板读取修复1 小时)
  BUG-004/F008: 循环处理流程1 小时)
  (两者都修改 main.py建议先后执行避免冲突

第4轮收尾
  文档更新bugs.md + features.md

8. 验收标准

8.1 BUG-001 / F005 验收

验收项 方法 预期结果
run.bat 使用 CRLF 换行 二进制查看文件 每行末尾为 \r\n
不含 lines= 参数 文本搜索 lines= 字符串
仅含 mode con cols=80 文本搜索 仅一行 mode con cols=80
Windows 下双击运行正常 实际运行 窗口正常打开,中文显示正确

8.2 BUG-002 / F006 验收

验收项 方法 预期结果
15×15 网格 + 60 Pin 验证通过 输入测试 无错误提示,转换成功
4×8 网格 + 24 Pin 验证通过 输入测试 无错误提示,转换成功
2×2 网格 + 8 Pin 验证通过 输入测试 无错误提示,转换成功
错误 Pin 数量仍报错 输入 15×15+56Pin 提示不匹配
布局计算正确 检查输出文件 四条边 Pin 分布正确

8.3 BUG-003 / F007 验收

验收项 方法 预期结果
List→MAP 读取模板 放置模板文件后转换 日志显示"已加载模板样式"
MAP→List 读取模板 放置模板文件后转换 日志显示"已加载模板样式"
无模板时优雅降级 不放置模板文件 日志显示"未检测到模板文件",使用默认样式
模板解析失败降级 放置损坏的模板文件 日志显示"解析失败",使用默认样式
输出文件样式正确 打开输出文件 字体、边框、对齐与模板一致

8.4 BUG-004 / F008 验收

验收项 方法 预期结果
处理完不退出 完成一次转换 显示"按 Enter 键继续"或循环提示
输入 Q 返回主菜单 处理完成后输入 Q 返回方向选择菜单
主菜单输入 Q 退出 主菜单输入 Q 程序退出
连续处理多个文件 连续选择文件 可连续处理,无需重新运行
命令行参数模式 run.bat input.xls 处理完成后进入循环

9. 风险评估汇总

风险 影响 概率 缓解措施
周长公式修改导致已有布局算法不一致 同步修改 validator + layout确保公式统一
角点单元格 Name 冲突 修改 get_name_cell() 确保不重叠
main.py 两处修改冲突 先完成 BUG-003再完成 BUG-004避免同时修改
模板路径在命令行模式下解析错误 使用 __file__ 绝对路径而非 cwd
循环流程中模块重复 import 性能 极低 Python 有 import 缓存

10. 总结

项目 内容
修改文件数 5 个run.bat, main.py, pinlist_validator.py, validator.py, pinmap_layout.py
新增文件数 0
影响核心模块 pinmap_layout.py 布局算法)
技术难度 中(周长公式 + 布局算法需同步修改)
预估工作量 ~3 小时
推荐 Agent Python 编码 Agent1-2 个)
风险等级 中(公式修改需仔细验证)

结论

  1. BUG-002 为最高优先级,影响所有 List→MAP 转换的正确性
  2. BUG-001 修复最简单,可快速完成
  3. BUG-003 和 BUG-004 都修改 main.py,需先后执行避免冲突
  4. 所有修改均使用 Python 标准库,无新增依赖
  5. 建议修改完成后运行完整测试套件验证

文档结束 — 请审批后进入编码阶段