# -*- 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'}")