58 lines
2.1 KiB
Python
58 lines
2.1 KiB
Python
#!/usr/bin/env python3
|
||
"""ЗАМОР 21: terminologist P1 consistency across 3 passes. $0."""
|
||
from parse_common import terminologist_rows, parse_bankstop
|
||
from collections import defaultdict, Counter
|
||
|
||
tr = terminologist_rows()
|
||
|
||
# per-pass structure (second counting path: also count unique src per pass)
|
||
pass_lines = Counter(r["pass"] for r in tr)
|
||
pass_src = defaultdict(set)
|
||
for r in tr:
|
||
pass_src[r["pass"]].add(r["src"])
|
||
print("=== PASS STRUCTURE ===")
|
||
for p in (1,2,3):
|
||
print(f" pass {p}: lines={pass_lines[p]} unique_src={len(pass_src[p])}")
|
||
print(" total lines:", len(tr))
|
||
|
||
# Build src -> {pass: [dst,...]} (a src could in principle repeat within a pass if in 2 batches)
|
||
src_pass = defaultdict(lambda: defaultdict(list))
|
||
for r in tr:
|
||
src_pass[r["src"]][r["pass"]].append(r["dst"])
|
||
|
||
# within-pass duplicates?
|
||
dup = [(s, p, v) for s, pm in src_pass.items() for p, v in pm.items() if len(v) > 1]
|
||
print("\n=== within-pass duplicate src (should be ~0; partition) ===", len(dup))
|
||
for s,p,v in dup[:20]:
|
||
print(" ", s, "pass", p, "->", v)
|
||
|
||
# n>=2 population: src in >=2 passes
|
||
n2 = {s: pm for s, pm in src_pass.items() if len(pm) >= 2}
|
||
print(f"\n=== src total distinct: {len(src_pass)} ; in >=2 passes (n>=2 pop): {len(n2)}")
|
||
# how many in all 3
|
||
n3 = {s: pm for s, pm in src_pass.items() if len(pm) == 3}
|
||
print(f" in all 3 passes: {len(n3)}")
|
||
|
||
# stability: dst identical across all passes present (take first dst per pass since dup rare)
|
||
def dstset(pm):
|
||
vals = set()
|
||
for p, v in pm.items():
|
||
for d in v:
|
||
vals.add(d)
|
||
return vals
|
||
|
||
stable, unstable = [], []
|
||
for s, pm in n2.items():
|
||
ds = dstset(pm)
|
||
if len(ds) == 1:
|
||
stable.append(s)
|
||
else:
|
||
unstable.append((s, {p: v[0] for p, v in pm.items()}))
|
||
|
||
print(f"\n=== STABILITY (n>=2 pop, N={len(n2)}) ===")
|
||
print(f" stable (identical dst): {len(stable)} ({len(stable)/len(n2)*100:.1f}%)")
|
||
print(f" UNSTABLE: {len(unstable)} ({len(unstable)/len(n2)*100:.1f}%)")
|
||
|
||
print("\n=== ALL UNSTABLE UNITS (src : pass->dst) ===")
|
||
for s, pm in sorted(unstable):
|
||
print(f" {s:12s} " + " | ".join(f"P{p}={pm[p]}" for p in sorted(pm)))
|