88 lines
3.9 KiB
Python
88 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
||
"""Ревью посылки пробы A: метрика посадок считала ИСЧЕЗНОВЕНИЕ, а не ВОССТАНОВЛЕНИЕ.
|
||
|
||
`editor_wire_probe.cmd_score` зачитывает дефект исправленным по `not re.search(bad_rx, out)`.
|
||
Удаление куска текста целиком тоже даёт `not still` ⇒ выпадение фразы засчитывалось как правка.
|
||
Здесь считаю три величины из того же сырья, $0:
|
||
|
||
снят = bad_rx больше не совпадает (прежняя метрика)
|
||
восстановлен = снят И fix_rx совпадает (строгая метрика)
|
||
выпал = снят, но fix_rx НЕ совпадает (кандидат в «фразу удалили»)
|
||
|
||
Плюс валидация самих регексов на исходном черновике: fix_rx ОБЯЗАН совпадать с оригиналом,
|
||
иначе строгая метрика штрафует за корректную работу.
|
||
"""
|
||
from __future__ import annotations
|
||
import json
|
||
import re
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
REPO = Path("/home/ubuntu/projects/textmachine")
|
||
sys.path.insert(0, str(REPO / "eval" / "bank_arbitration"))
|
||
RAW = Path.home() / "books" / "gu-zhenren" / "bank-arbitration"
|
||
|
||
import editor_wire_probe as P # noqa: E402
|
||
|
||
|
||
def out_of(tag: str):
|
||
f = RAW / f"{tag}.json"
|
||
if not f.exists():
|
||
return None
|
||
return json.loads(f.read_text(encoding="utf-8"))["content"]
|
||
|
||
|
||
def validate_regexes() -> int:
|
||
"""fix_rx должен ловить ОРИГИНАЛ, bad_rx — НЕ ловить его; на посаженном — наоборот."""
|
||
bad = 0
|
||
print("=== валидация регексов посадок на исходном черновике ===")
|
||
for k in sorted(P.DEFECTS):
|
||
draft = P.draft_of(k)
|
||
planted, _ = P.planted_draft(k, draft)
|
||
for cls, old, new, bad_rx, fix_rx in P.DEFECTS[k]:
|
||
fix_on_orig = bool(re.search(fix_rx, draft))
|
||
bad_on_orig = bool(re.search(bad_rx, draft))
|
||
bad_on_plant = bool(re.search(bad_rx, planted))
|
||
ok = fix_on_orig and not bad_on_orig and bad_on_plant
|
||
if not ok:
|
||
bad += 1
|
||
print(f" ⚠ w{k}/{cls}: fix_rx на оригинале={fix_on_orig} "
|
||
f"bad_rx на оригинале={bad_on_orig} bad_rx на посаженном={bad_on_plant}")
|
||
print(f" дефектных регексов: {bad} из {sum(len(v) for v in P.DEFECTS.values())}")
|
||
return bad
|
||
|
||
|
||
def score(arm: str) -> None:
|
||
print(f"\n=== арм {arm} ===")
|
||
for cls in ("k1", "k2"):
|
||
snyat = vosst = vypal = tot = 0
|
||
rows = []
|
||
for k in sorted(P.DEFECTS):
|
||
o = out_of(f"{arm}-w{k}")
|
||
if o is None:
|
||
continue
|
||
for c, old, new, bad_rx, fix_rx in P.DEFECTS[k]:
|
||
if c != cls:
|
||
continue
|
||
tot += 1
|
||
still = bool(re.search(bad_rx, o))
|
||
restored = bool(re.search(fix_rx, o))
|
||
if not still:
|
||
snyat += 1
|
||
if restored:
|
||
vosst += 1
|
||
rows.append(f"w{k}:восст")
|
||
else:
|
||
vypal += 1
|
||
rows.append(f"w{k}:ВЫПАЛ")
|
||
else:
|
||
rows.append(f"w{k}:жив")
|
||
if tot:
|
||
print(f" {cls}: снят {snyat}/{tot} · ВОССТАНОВЛЕН {vosst}/{tot} · выпал {vypal} "
|
||
+ " ".join(rows))
|
||
|
||
|
||
if __name__ == "__main__":
|
||
validate_regexes()
|
||
for arm in sys.argv[1:] or ["edp-A0", "edp-A1", "edp-A2", "edp-A3", "edp-A4", "edp-A5"]:
|
||
score(arm)
|