feat: PinMAP转PinList v1.2.0 - 新增PinList转PinMAP反向转换功能
This commit is contained in:
112
Code/src/pinlist_validator.py
Normal file
112
Code/src/pinlist_validator.py
Normal file
@@ -0,0 +1,112 @@
|
||||
"""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 (2×rows + 2×cols − 4)
|
||||
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 总数 = 2×rows + 2×cols − 4(周长匹配)
|
||||
4. Pin 缺少 PinName 时默认为 NC(warning)
|
||||
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. 周长匹配 ──────────────────────────────────────────────
|
||||
expected_total = 2 * rows + 2 * cols - 4
|
||||
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. 缺失 PinName(warning)────────────────────────────────
|
||||
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,
|
||||
)
|
||||
Reference in New Issue
Block a user