# -*- coding: utf-8 -*-
import re, json, io, sys
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
slides = json.load(open(r"C:\GUARDiA\workspace\kintex\_workspace\proposal\_qa_slides.json", encoding="utf-8"))
# Full REQ universe
UNIV = {}
for pfx, cnt in [("F", 81), ("A", 20), ("N", 21), ("S", 20)]:
for i in range(1, cnt + 1):
UNIV[f"{pfx}-{i:03d}"] = None # slide where covered
# Parse each text line for badge tokens with prefix-context + range + continuation.
# Grammar we support in a run:
# REQ-
- single
# REQ--~ range (same prefix)
# ...·- new prefix single continuation
# ...·-~ new prefix range continuation
# ...· bare number continues LAST prefix (e.g. A-011·012)
# ...·~ bare range continues last prefix (e.g. 067~069)
cover = {} # req -> list of slides
def add(pfx, a, b, sn):
for i in range(a, b + 1):
key = f"{pfx}-{i:03d}"
cover.setdefault(key, set()).add(sn)
# token: optional prefix letter, number, optional ~ number
tok = re.compile(r"(?:REQ-)?(?:([FANS])-)?(\d{2,3})(?:\s*~\s*(?:[FANS]-)?(\d{2,3}))?")
for s in slides:
sn = s["n"]
for t in s["texts"]:
# only scan segments that look like badge context (contain REQ- or letter-number dot chains)
for m in re.finditer(r"REQ-[FANS]-\d{2,3}(?:\s*~\s*\d{2,3})?(?:[·,\s]+(?:[FANS]-)?\d{2,3}(?:\s*~\s*\d{2,3})?)*", t):
seg = m.group(0)
last_pfx = None
for mm in tok.finditer(seg):
p, a, b = mm.group(1), mm.group(2), mm.group(3)
if p:
last_pfx = p
if last_pfx is None:
continue
ai = int(a)
bi = int(b) if b else ai
# sanity: within universe range
add(last_pfx, ai, bi, sn)
missing = sorted(k for k in UNIV if k not in cover)
print("=== RANGE-EXPANDED BADGE COVERAGE ===")
print("COVERED (badge):", len(cover), "/ 142")
print("NOT badge-covered (", len(missing), "):", ", ".join(missing))
# priority 7
prio = ["F-008", "F-010", "F-026", "F-032", "A-003", "A-005", "A-008"]
print("\n=== PRIORITY 7 BADGE STATUS ===")
for r in prio:
print(f"{r}: badge slides = {sorted(cover.get(r, []))}")
# dump per-covered for the previously-flagged 18
flagged = ["F-005","F-008","F-010","F-026","F-032","F-034","F-036","F-038","F-039","F-054","F-074","F-075","F-076","A-003","A-005","A-008","S-005","S-006"]
print("\n=== PREVIOUSLY-FLAGGED 18: badge coverage after range expansion ===")
for r in flagged:
sl = sorted(cover.get(r, []))
print(f"{r}: {'BADGE ' + str(sl) if sl else 'NO BADGE'}")