Files
pinmap-to-pinlist/Code/src/validator.py
Agent 6b718f7af3 v1.0.0: PinMAP → PinList 转换器 首次发布
- 支持 .xls (BIFF8) 和 .xlsx 格式
- GUI 文件选择 + 命令行双模式
- 智能结构验证(重复/间隙/空单元格检测)
- 逆时针 PinMAP → 顺时针 PinList 自动转换
- Python 标准库,零第三方依赖
2026-05-25 13:27:08 +08:00

104 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""PinMAP data validator.
Validates a parsed PinMAP for structural and data integrity:
1. Pin-number uniqueness
2. Pin-number continuity (1..N with no gaps)
3. Missing PinName detection (warning, defaults to "NC")
4. Rectangular-structure sanity
Usage
-----
>>> from validator import validate_pinmap
>>> result = validate_pinmap(pinmap)
>>> if result.is_valid:
... print("All good")
... else:
... for e in result.errors:
... print(f"[ERROR] {e.message}: {e.details}")
"""
from collections import Counter
from models import PinMAP, ValidationResult, ValidationError
def validate_pinmap(pinmap: PinMAP) -> ValidationResult:
"""Validate a PinMAP and return a ValidationResult.
Checks performed
----------------
1. **Uniqueness** — every pin number must appear exactly once.
2. **Continuity** — pin numbers must form the sequence 1, 2, …, N
with no gaps.
3. **PinName completeness** — pins with empty / whitespace-only names
generate a *warning* (they will default to "NC" in the output).
4. **Structure** — width and height must each be ≥ 2.
Parameters
----------
pinmap : PinMAP
A pin map produced by ``pinmap_parser.parse_pinmap``.
Returns
-------
ValidationResult
"""
result = ValidationResult(is_valid=True, errors=[], warnings=[])
numbers = [p.number for p in pinmap.pins]
# ── 1. Uniqueness ────────────────────────────────────────────
if len(numbers) != len(set(numbers)):
counts = Counter(numbers)
duplicates = sorted(n for n, c in counts.items() if c > 1)
result.errors.append(ValidationError(
level="error",
message="Pin序号重复",
details=f"重复的序号: {duplicates}",
))
# ── 2. Continuity ────────────────────────────────────────────
if numbers:
expected = set(range(1, max(numbers) + 1))
actual = set(numbers)
missing = expected - actual
if missing:
result.errors.append(ValidationError(
level="error",
message="Pin序号不连续",
details=f"缺失的序号: {sorted(missing)}",
))
# ── 3. PinName completeness ──────────────────────────────────
missing_names = [
p for p in pinmap.pins
if not p.name or not p.name.strip()
]
if missing_names:
result.warnings.append(ValidationError(
level="warning",
message=(
f"检测到 {len(missing_names)} 个引脚缺少 PinName"
),
details=(
f"缺失引脚序号: {[p.number for p in missing_names]}"
f"将默认为 NC"
),
))
# ── 4. Structure sanity ──────────────────────────────────────
if pinmap.width < 2 or pinmap.height < 2:
result.errors.append(ValidationError(
level="error",
message="方形结构不完整",
details=(
f"尺寸: {pinmap.width}x{pinmap.height},至少需要 2x2"
),
))
# ── Final verdict ────────────────────────────────────────────
if result.errors:
result.is_valid = False
return result