# -*- coding: utf-8 -*- """마스터 데이터 검사 — 원문 절 목록 ↔ 마스터 전수 대조(건설품셈 공통 1장) · `check_master.py` 가 부름. - 절 = 원문 `###` 머리 전부 · 범위 = 머리부터 다음 같은 · 윗 단계 머리 앞까지(요구 630). - 가이드(1-1 · 1-2-1) 빼고 계산 대상 절마다 마스터 키(계수 · 로직)가 하나 이상 — 없으면 「통째 빠짐」. - 품 · 표 · 식 절(_대조_632 판정)은 로직이 있어야 함 · 1-2-9 · 1-4-2 = PLAN 783-1 로 미룸 표지. """ from __future__ import annotations import re from pathlib import Path HERE = Path(__file__).resolve().parent CH1 = ( HERE.parents[2] / "resources/knowledge/original/원가계산/건설공사_표준품셈/본문/01_공통부문/제01장_적용기준" ) WHO = ("건설품셈 공통", "01장 적용기준") GUIDE = ("1-1-", "1-2-1") # 사용자 판정(요구 632) — 가이드 CALC = ("1-2-7", "1-2-9", "1-4-2", "1-5-4", "1-5-6") # 품 · 표 · 식(_대조_632 2장) DEFER = {"1-2-9": "783-1", "1-4-2": "783-1"} # 로직 = 프로젝트 조정(B09) 승인 뒤 def sections(folder: Path = CH1) -> list[tuple[str, str]]: """(절 번호, 이름) — 원문 차례.""" out = [] for md in sorted(folder.glob("1-*.md")): for line in md.read_text(encoding="utf-8").split("\n"): m = re.match(r"^### (\d+-\d+-\d+) (.+)$", line) if m: out.append((m[1], re.sub(r"\s*\(['‘].*$", "", m[2]).strip())) return out def _guide(no: str) -> bool: return no.startswith(GUIDE[0]) or no == GUIDE[1] def table(files: dict[str, dict], folder: Path = CH1) -> list[dict]: """절마다 {절 · 이름 · 쓰임 · 판정 · 계수 · 로직 · 표지}.""" keys: dict[str, dict[str, list[str]]] = {} for data in files.values(): group = data.get("그룹") for row in data.get("표") or data.get("줄") or []: if (row.get("구분"), row.get("상세구분")) != WHO: continue kind = "로직" if group == "로직" else "계수" keys.setdefault(str(row.get("원문번호")), {}).setdefault(kind, []).append(row["키"]) out = [] for no, name in sections(folder): got = keys.pop(no, {}) out.append( { "절": no, "이름": name, "쓰임": "가이드" if _guide(no) else "계산 대상", "판정": "품·표·식" if no in CALC else "규칙·계수만", "계수": got.get("계수", []), "로직": got.get("로직", []), "표지": f"{DEFER[no]} 로 미룸" if no in DEFER else "", } ) for no, got in keys.items(): # 원문 목차에 없는 원문번호 out.append( { "절": no, "이름": "", "쓰임": "목차 밖", "계수": got.get("계수", []), "로직": got.get("로직", []), } ) return out def check_toc(files: dict[str, dict], folder: Path = CH1) -> list[str]: found = [] for r in table(files, folder): where = f"공통 1장 {r['절']} {r['이름']}" if r["쓰임"] == "목차 밖": found.append(f"{where} · 원문 목차에 없는 원문번호 ← {r['계수'] + r['로직']}") elif r["쓰임"] == "계산 대상" and not r["계수"] and not r["로직"]: found.append(f"{where} · 통째 빠짐 — 계수 · 로직 키 없음") elif ( r["쓰임"] == "계산 대상" and r["판정"] == "품·표·식" and not r["로직"] and not r["표지"] ): found.append(f"{where} · 품·표·식 절인데 로직 없음") return found