knowledge(마스터): 미확보 9 직종을 사용자 지정 추정으로 · 구분 미확보 뺌

- 인력.json — 절단공·사진제판공·사진식자공·측량사·측량기사·시공측량기사·측량조수·시공측량조수·특수운전공 상태 「추정」 · 값은 준용 직종 노임 · 출처는 근거 문서 · 비고 한마디
- 구분 「미확보」 등록부·빌더 짝짓기 없앰 · check_master BOOKS 에 공간정보법
- 근거 md 에 「사용자 지정 추정」 절
- 로직 일괄 시험 계산 통과 1,109 → 1,119 · 멈춤 245 → 235

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JgUhN55Z3BCYhUJTjwTNfj
This commit is contained in:
2026-09-20 20:27:44 +09:00
co-authored by Claude Opus 5
parent 5160cea9ac
commit 819c5019ec
8 changed files with 46 additions and 91 deletions
@@ -1,11 +1,10 @@
"""노임 공표 원문 md → 인력 요소 파일 다섯 · 미확보 짝짓기 · 건설노임 미공표 산정.
"""노임 공표 원문 md → 인력 요소 파일 다섯 · 건설노임 미공표 산정 · 추정 줄 되채움.
원문 = resources/knowledge/original/원가계산/노임단가_* (우리 md · ESTX 값 쓰지 않음).
- 모든 줄이 같은 열 한 벌(`_틀.md` 인력) · 제조업 업종·엔지니어링 부문·측량 분야는 「상세구분」.
- 인력_엔지니어링노임 · 측량노임 · 건설사업관리노임 · SW노임 · 산림노임 — md 표 그대로 · 줄 수·값을 md 와 기계 대조.
옛이름·비고·준용은 다시 지어도 그대로 이어받음(`carry`).
- 인력_준용대상(구분 「미확보」) — 새 노임 직종과 이름이 온전히 같은 줄은 옮김(로직 참조도).
건설노임 원문 「통합·명칭변경 직종」 목록의 옛 직종은 현행 줄 `옛이름` 으로 옮겼음.
- 상태 「추정」 줄(옛·폐지 직종) — 관리자가 고른 준용 직종에서 값·단위·일시간을 되채움.
- 인력_건설노임 미공표 — 원문 4-라 산정값을 「값」 에 넣고 상태 「산정」 · 근거는 비고 한 줄.
이음 = 원문 회차의 전체직종 평균을 그대로 이음(미공표직종_추적.md 4절) · 산정값은 같은 md 5절과 대조.
- 인력_제조노임 미공표 — 조사월마다 전체 평균 증가율을 곱하며 원 미만 버림(건설 4-라 방식 준용 · 제조 원문에 규정 없음).
@@ -260,7 +259,7 @@ def check_md(src: Path, rows: list[dict], table_head: str | None = None) -> None
print(f" {src.parent.name[5:]}: {len(rows)} 줄 · 값 합 {sum(got.elements()):,} · md 대조 같음")
# ── 미확보 짝짓기 ────────────────────────────────────────────────────
# ── 관리자 칸 잇기 ────────────────────────────────────────────────────
def carry(rows: list[dict], kind: str, old: list[dict]) -> None:
"""관리자·근거가 채운 칸(옛이름 · 비고 · 준용)은 다시 지어도 그대로 — 이름으로 맞댐."""
had = {r["이름"]: r for r in old if r.get("구분") == kind}
@@ -300,36 +299,9 @@ def main():
}
assert {b: len(v[2]) for b, v in books.items()} == expect
# 이름 → ref (새 다섯 + 건설·제조 공표)
wage = mk.old_view("인력_건설노임.json")
make = mk.old_view("인력_제조노임.json")
pool = {r["이름"]: f"인력:{b}:{r['열쇠']}" for b, (_, _, rows) in books.items() for r in rows}
old_pool = {r["이름"]: f"인력:{d['원문']}:{r['열쇠']}" for d in (wage, make) for r in d[""]}
now = json.loads((MD / "인력.json").read_text(encoding="utf-8"))[""]
applied = { # 현행 줄이 이미 품은 옛 직종명(`_틀.md` 인력 값 · 옛이름)
name for r in now for name in (r.get("옛이름") or [])
} - { # 갈린 직종(절단공)은 옛이름이면서 미확보로도 남음 — 지우지 않음
r["이름"] for r in now if r.get("구분") == "미확보"
}
alias_path = MD / "인력_준용대상.json"
alias = mk.old_view(alias_path.name)
moved, kept = {}, []
for r in alias[""]:
name = r["이름"]
if name in pool:
moved[f"인력:준용대상:{r['열쇠']}"] = pool[name]
continue
assert name not in old_pool, name
if name in applied: # 이미 현행 줄 「옛이름」 으로 옮긴 직종 — 미확보로 다시 만들지 않음
continue
kept.append(r)
alias["비고"] = [
"값을 확인 못 한 직종(공표 노임에 이름이 온전히 같은 직종 없음) — 이름·단위만"
" · 비고 = 이 직종을 요구한 품셈 절 · 비슷한 이름도 비고에"
]
head = {k: v for k, v in alias.items() if k != ""}
dump_master(alias_path, head, kept)
for book, (src, head, rows) in books.items():
carry(rows, mk.LABOR[book], now)
@@ -337,20 +309,6 @@ def main():
rows += [r for r in mk.old_view(f"인력_{book}.json")[""] if r.get("상태") == "추정"]
dump_master(MD / f"인력_{book}.json", head, rows)
# 로직 참조 옮김 — 긴 열쇠부터
n_ref = 0
for path in sorted(MD.glob("로직_*.json")):
text = path.read_text(encoding="utf-8")
new = text
for old in sorted(moved, key=len, reverse=True):
n_ref += new.count(old)
new = new.replace(old, moved[old])
if new != text:
path.write_bytes(new.encode("utf-8"))
print(
f"미확보 {len(alias[''])} → 옮김 {len(moved)} {sorted(moved.values())} · 남김 {len(kept)} · 로직 참조 {n_ref}"
)
estimate(wage)
estimate_make(make)
print("새 틀로 받음", mk.adopt())
@@ -40,7 +40,6 @@ BOOKS = (
"건설사업관리노임",
"SW노임",
"산림노임",
"준용대상",
"유가전력",
"자재품목",
"한국은행환율",
@@ -48,6 +47,7 @@ BOOKS = (
"품셈재료",
"질의회신",
"엔산법",
"공간정보법",
"자체",
)
DIVISIONS = {
@@ -131,7 +131,6 @@ LABOR = {
"건설사업관리노임": "건설사업관리",
"SW노임": "SW",
"산림노임": "산림",
"준용대상": "미확보",
}
MERGED = {
"인력": ("인력.json", "구분", LABOR),