#!/usr/bin/env python3 """exp13 — гейты на выходах армов (пре-рег §1.3): эхо-rate / refusal / объём-коридор / полнота. Читает diag/arms13//_.txt + diag/chunks.json (исходники zh). $0 (детерминированно). Выход: diag/arms13/gates.json + печать таблицы. """ from __future__ import annotations import json, re from pathlib import Path DIAG = Path("/home/ubuntu/books/gu-zhenren/diag") OUT = DIAG / "arms13" TARGETS = [(5, 0), (5, 1), (7, 0), (7, 1), (14, 0), (14, 1)] LEN_BOUNDS = (2.2, 4.2) # zh→ru приёмки REFUSAL = re.compile(r"(?i)\b(я не могу|не буду переводить|as an ai|i cannot|i'm sorry|извините, но я|не могу выполнить|против правил)\b") HAN = re.compile(r"[一-鿿㐀-䶿]") def han_ratio(t: str) -> float: ns = [c for c in t if not c.isspace()] if not ns: return 1.0 return sum(1 for c in ns if HAN.match(c)) / len(ns) def main() -> None: chunks = json.loads((DIAG / "chunks.json").read_text(encoding="utf-8")) arms = sorted([p.name for p in OUT.iterdir() if p.is_dir()]) rows, per_arm = [], {} for arm in arms: agg = {"arm": arm, "n": 0, "echo": 0, "refusal": 0, "vol_bad": 0, "empty": 0, "han_sum": 0.0, "vol_sum": 0.0} for ch, ci in TARGETS: key = f"{ch}/{ci}" p = OUT / arm / f"{ch}_{ci}.txt" src = chunks[key]["source"] if not p.exists() or not p.read_text(encoding="utf-8").strip(): agg["empty"] += 1; agg["n"] += 1; continue t = p.read_text(encoding="utf-8").strip() hr = han_ratio(t) vr = len(t) / max(1, len(src)) echo = hr > 0.10 ref = bool(REFUSAL.search(t)) volbad = not (LEN_BOUNDS[0] <= vr <= LEN_BOUNDS[1]) agg["n"] += 1; agg["han_sum"] += hr; agg["vol_sum"] += vr agg["echo"] += echo; agg["refusal"] += ref; agg["vol_bad"] += volbad rows.append({"arm": arm, "chunk": key, "han": round(hr, 4), "vol": round(vr, 2), "echo": echo, "refusal": ref, "vol_bad": volbad, "chars": len(t)}) n = max(1, agg["n"] - agg["empty"]) agg["han_avg"] = round(agg["han_sum"] / n, 4) agg["vol_avg"] = round(agg["vol_sum"] / n, 2) agg["echo_rate"] = round(agg["echo"] / max(1, agg["n"]), 3) per_arm[arm] = agg (OUT / "gates.json").write_text(json.dumps({"per_arm": per_arm, "rows": rows}, ensure_ascii=False, indent=1), encoding="utf-8") print(f"{'arm':<5} {'n':>2} {'echo':>5} {'refus':>5} {'volBad':>6} {'empty':>5} {'han_avg':>8} {'vol_avg':>7}") for arm in arms: a = per_arm[arm] print(f"{arm:<5} {a['n']:>2} {a['echo']:>5} {a['refusal']:>5} {a['vol_bad']:>6} {a['empty']:>5} {a['han_avg']:>8} {a['vol_avg']:>7} echo_rate={a['echo_rate']}") if __name__ == "__main__": main()