Files
pinmap-to-pinlist/Code/src/pinlist_validator.py

114 lines
3.9 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.
"""PinList validator — checks pin data integrity.
Validates a PinList for:
1. Pin numbers starting from 1 with no gaps
2. No duplicate pin numbers
3. Total pin count matches grid perimeter (rows + cols) × 2
4. Missing PinName defaults to NC (warning)
5. Pin count not a multiple of 4 (info)
"""
from models import PinListEntry, ValidationResult, ValidationError
def validate_pinlist(
entries: list[PinListEntry],
rows: int,
cols: int,
) -> ValidationResult:
"""
验证 PinList 数据。
检查项:
1. Pin 序号从 1 开始连续无缺失
2. Pin 序号无重复
3. Pin 总数 = (rows + cols) × 2周长匹配
4. Pin 缺少 PinName 时默认为 NCwarning
5. Pin 数量不是 4 的倍数时提示info
Parameters
----------
entries : list[PinListEntry]
已按序号排序的引脚列表
rows : int
用户输入的 PinMAP 行数
cols : int
用户输入的 PinMAP 列数
Returns
-------
ValidationResult
"""
errors: list[ValidationError] = []
warnings: list[ValidationError] = []
infos: list[ValidationError] = []
numbers = [e.number for e in entries]
# ── 1. 连续性检查 ────────────────────────────────────────────
expected_numbers = list(range(1, len(numbers) + 1))
if numbers != expected_numbers:
missing = set(expected_numbers) - set(numbers)
if missing:
errors.append(ValidationError(
level="error",
message="Pin序号不连续",
details=f"缺失的序号: {sorted(missing)}",
))
# ── 2. 唯一性检查 ────────────────────────────────────────────
if len(numbers) != len(set(numbers)):
from collections import Counter
counts = Counter(numbers)
duplicates = sorted(n for n, c in counts.items() if c > 1)
errors.append(ValidationError(
level="error",
message="Pin序号存在重复",
details=f"重复的序号: {duplicates}",
))
# ── 3. 周长匹配 ──────────────────────────────────────────────
# 周长公式:(rows + cols) * 2
expected_total = (rows + cols) * 2
actual_total = len(entries)
if actual_total != expected_total:
errors.append(ValidationError(
level="error",
message="Pin数量与网格周长不匹配",
details=(
f"网格 {rows}×{cols} 需要 {expected_total} 个引脚,"
f"但 PinList 有 {actual_total}"
),
))
# ── 4. 缺失 PinNamewarning────────────────────────────────
missing_names = [e for e in entries if not e.name or not e.name.strip()]
if missing_names:
warnings.append(ValidationError(
level="warning",
message=f"检测到 {len(missing_names)} 个引脚缺少 PinName",
details=(
f"缺失引脚序号: {[e.number for e in missing_names]}"
f"将默认为 NC"
),
))
# ── 5. 非 4 倍数提示info──────────────────────────────────
if actual_total % 4 != 0:
infos.append(ValidationError(
level="info",
message="Pin数量不是4的倍数",
details=(
f"Pin数量 ({actual_total}) 不是 4 的倍数,"
f"四条边将不均匀分布"
),
))
is_valid = len(errors) == 0
return ValidationResult(
is_valid=is_valid,
errors=errors,
warnings=warnings,
)