feat(782-2): 건설 공통 1장 나머지 기초 — 계수 표 33 · 환경관리비 · 공사용수 로직 · 성격 칸 · check_master 목차 대조

- 계수_건설품셈_01장_적용기준.json 덧(CC000495~527): 규칙 · 계수만 절(1-2-2 · 1-2-3 · 1-2-4 · 1-2-5 · 1-2-6 · 1-2-8 · 1-3-2 · 1-4-1 · 1-4-2 · 1-5-1~10)마다 「규칙 글」 표(원문 글 그대로) + 수 표(단위 · 소수 표준 · 금액 단위 · 체적 변화율 L · C · 체적환산계수 f · 파쇄된 돌 10∼40% · 잡재료 2∼5% · 작업반장 · 공구손료 3% · 시공단위 품 소수자리 · 품 산정 식 · 예시 · 건설폐기물 발생량 · 공사용수) · 1-2-9 소규모 적용시공량 · 다수 규격 예시 = 계수로만
- 표 칸 「성격」 — 기존 1-3 · 1-4 표 33 + 1-2-9 둘(같은 성격 묶음 · 1-2-9 ↔ 1-4-6 작업시간 제한 한 성격) · 기존 표의 다른 글자 그대로
- 로직_건설품셈_01장_적용기준.json 덧: GC001192 건설폐기물 발생량(1-5-4 · 면적 × TON/㎡ × 폐콘크리트 증가율) · GC001193 공사용수(1-5-6 · 작업량 × 단위용수 × 잡용수율) · 원문 「-」 칸 = 줄 없음(멈춤)
- 1-2-9 소규모 · 1-4 품의 할증 로직 = 만들지 않음(PLAN 783-1)
- 빌더 덧 build_로직_건설품셈_01장_적용기준.py 나머지(+ _적용기준_나머지_표 · _적용기준_나머지_로직) · 키 = master_keys.issue(adopt 는 로직을 받지 않음)
- check_master 「목차」(check_master_toc.py) — 공통 1장 원문 절 목록 ↔ 마스터 전수 · 통째 빠진 절 · 로직 없는 품·표·식 절 · 1-2-9 · 1-4-2 = 783-1 로 미룸 표지
- 지킴 시험 test_782_2_common_ch1.py · test_782_1_carry_127.py 로직 줄 목록 = 앞 셋만 봄(같은 파일에 1-5 로직이 붙어 낡음)
- check_master 전후 같음(+ 목차 0) · 기존 로직 1513 셈 값 전후 같음 · 계산전부 1515

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-04 20:42:38 +09:00
co-authored by Claude Opus 5.5
parent 8ddb5bbda7
commit a8ed3390e9
10 changed files with 1843 additions and 4 deletions
@@ -0,0 +1,89 @@
# -*- 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