knowledge(마스터): 추정 줄에 준용 직종 값 채움 · 출처는 근거 문서

- 상태 「추정」 아홉 줄 — 값·단위·일시간을 준용 직종 것으로 채움 · 출처 짧게(건설품셈 기계설비 13-06 · 제조노임 직종해설 · 엔산법 시행령 별표2 · 건설노임 명칭변경표 2010.1) · 비고는 공작기계공 「밀링원일 수 있음」 만 남김
- 시험사1급 준용 비파괴시험공 → 특급품질관리원
- 빌더 refill_estimated — 다시 지을 때마다 준용 직종에서 값 되채움
- check_master — 추정 줄 값 = 준용 직종 값 검사 · 출처 낱말에 엔산법
- 엔진 — 추정 줄은 제 값 · 호표 출처 「추정(준용: ○○)」

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 19:44:33 +09:00
co-authored by Claude Opus 5
parent ca34d9740f
commit 7a9bcac924
6 changed files with 53 additions and 22 deletions
+3 -3
View File
@@ -44,7 +44,7 @@
## 4. 출처
- 한 칸 · `원문 이름 + 번호` — 「산림품셈 13-4-1」 · 「건설품셈 공통 8-4-1」(건설은 부문 필수) · 「건설노임 1018」 · 「질의회신 건협기술-2230」 · 「자체」
- 한 칸 · `원문 이름 + 번호` — 「산림품셈 13-4-1」 · 「건설품셈 공통 8-4-1」(건설은 부문 필수) · 「건설노임 1018」 · 「질의회신 건협기술-2230」 · 「엔산법 시행령 별표2」 · 「자체」
- [주] 는 뒤에 붙임 — 「산림품셈 13-4-4 주⑩」
- 판(기준일)은 파일 머리에 한 번 · 인력·기계는 갈래 묶음 안에.
@@ -92,7 +92,7 @@
- 인력 `구분` = 건설업 · 제조업 · 엔지니어링 · 측량 · 건설사업관리 · SW · 산림 · 미확보 · 구분별 원문·기관·판·공표일·원천·상세구분·비고는 머리 `구분` 묶음.
- 새 조사 = 머리 `구분` 에 한 항목 더하고 줄을 붙이면 끝 · 키는 LB 일련번호 이어 받음.
- `상세구분` = 제조업 업종 · 엔지니어링 부문 · 측량 기술계/기능계 분야 — 없으면 `null` · 목록은 머리에.
- `상태` = 공표 · 산정(미공표 직종의 원문 4-라 값을 `값` 에 넣음 · 근거는 `비고` 한 줄) · 미공표(원문에 값 없음) · 미확보(공표 노임에 같은 직종 없음) · 추정(원문이 이름을 맞대지 않아 작업 범위로 짐작한 대응 — `구분` 은 대응 직종 것 · `` 은 비움 · `준용` 에 대응 직종 키 · 근거는 `비고` 한 줄).
- `상태` = 공표 · 산정(미공표 직종의 원문 4-라 값을 `값` 에 넣음 · 근거는 `비고` 한 줄) · 미공표(원문에 값 없음) · 미확보(공표 노임에 같은 직종 없음) · 추정(원문이 이름을 맞대지 않아 작업 범위로 짐작한 대응 — `구분` 은 대응 직종 것 · `준용` 에 그 직종 키 · `값`·`단위`·`일시간` 은 빌더가 준용 직종에서 채움 · 근거 문서`출처` 짧게).
- `일시간` = 1일 노임 기준 시간 — 8 · 잠수부만 6(원문 4-가).
- 기계 `세부분류` = 건설품셈 · 산림품셈 · 세부분류별 원문·판·주는 머리 `세부분류` 묶음.
- 값이 여럿인 요소(기계)는 `값` 을 묶음으로 — `{ "가격": …, "상각비계수": …, "정비비계수": …, "관리비계수": …, "손료계수": …, "주연료": …, "주연료종류": …, "잡재료율": …, "조종원": …, "조종원직종": … }` · `손료계수` = 원문 「계」.
@@ -100,7 +100,7 @@
- 원문에 없는 값을 지어 넣지 않음. 원문 「-」 = 칸을 비움(`null`).
- `준용` = 모든 줄의 공통 칸 — 관리자가 고르는 다른 요소 키 · 준용 값을 미리 채우지 않음. 공표 노임에 이름이 온전히 같은 직종이 없으면 구분 「미확보」.
- `옛이름` = 품셈이 쓰는 옛 직종명 목록(읽기 전용) · 이름 바뀜·통합 근거가 선 것은 준용이 아니라 현행 줄에 바로 적음 · 이력은 그 줄 `비고` · 근거는 `노임단가_직종대응_근거.md`.
- 엔진 차례 = 준용이 있으면 그 요소 값 · 없으면 제 값 · 호표 출처에 「준용: <이름>」 · 상태 「추정」 이면 「준용: <이름>(추정)」.
- 엔진 차례 = 준용이 있으면 그 요소 값 · 없으면 제 값 · 호표 출처에 「준용: <이름>」 · 상태 「추정」 은 제 값을 쓰고 호표 출처에 「추정(준용: <이름>)」.
- 원문 이름 대신 번호로 적은 값(`조종원직종` = 노임 원문번호 「1048」)은 원문 이름을 `비고` 칸에.
재료 값:
@@ -354,6 +354,24 @@ def main():
estimate(wage)
estimate_make(make)
print("새 틀로 받음", mk.adopt())
refill_estimated()
def refill_estimated() -> None:
"""상태 「추정」 줄 — 값·단위·일시간을 준용 직종에서 다시 채움(공표 회차가 바뀌면 같이 바뀜)."""
path = MD / "인력.json"
data = json.loads(path.read_text(encoding="utf-8"))
by_key = {r[""]: r for r in data[""]}
n = 0
for r in data[""]:
if r.get("상태") != "추정":
continue
target = by_key[r["준용"]]
r[""], r["단위"], r["일시간"] = target[""], target["단위"], target["일시간"]
n += 1
head = {k: v for k, v in data.items() if k != ""}
path.write_text(mk.dump_rows(head, data[""]), encoding="utf-8", newline="\n")
print(f"추정 {n} 줄 값 = 준용 직종 값")
# ── 건설노임 미공표 산정 ─────────────────────────────────────────────
+11 -2
View File
@@ -47,6 +47,7 @@ BOOKS = (
"조달청제비율",
"품셈재료",
"질의회신",
"엔산법",
"자체",
)
DIVISIONS = {
@@ -311,7 +312,7 @@ def _check_linked(where: str, row: dict) -> list[str]:
def check_links(whole: mf.Master) -> list[str]:
"""끊긴 키 — 품셈재료 연결 · 인력 준용이 가리키는 줄."""
"""끊긴 키 — 품셈재료 연결 · 인력 준용이 가리키는 줄 · 추정 줄 값 = 준용 직종 값."""
out = []
for key, row in whole.index.get("MP", {}).items():
link = row.get("연결")
@@ -320,8 +321,16 @@ def check_links(whole: mf.Master) -> list[str]:
for key, row in whole.index.get("LB", {}).items():
for col in ("준용",):
ref = row.get(col)
if ref not in (None, "") and str(ref) not in whole.index.get("LB", {}):
if ref in (None, ""):
continue
target = whole.index.get("LB", {}).get(str(ref))
if target is None:
out.append(f"{whole.label(key)} · {col}{ref}」 없는 인력 키")
elif row.get("상태") == "추정" and row.get("") != target.get(""):
out.append(
f"{whole.label(key)} · 추정 값 「{row.get('')}」 이"
f" 준용 「{target.get('이름')}」 값 「{target.get('')}」 과 다름"
)
return out
@@ -274,8 +274,10 @@ class Master:
alias = row.get("준용")
if alias not in (None, ""):
target = self.get(str(alias))
mark = "(추정)" if row.get("상태") == "추정" else ""
return target.get(""), f"준용: {target.get('이름') or alias}{mark}"
name = target.get("이름") or alias
if row.get("상태") == "추정": # 값을 이미 준용 직종에서 채워 둠
return row.get(""), f"추정(준용: {name})"
return target.get(""), f"준용: {name}"
return row.get(""), None
def logic(self, ref: str) -> dict:
+11 -11
View File
@@ -2,8 +2,8 @@
"그룹": "인력",
"비고": [
"열 한 벌 = 키 · 원문번호 · 구분 · 상세구분 · 이름 · 규격 · 단위 · 값 · 출처 · 일시간 · 상태 · 옛이름 · 비고 · 준용 — 모든 줄이 모든 칸을 가짐(없으면 null · 빈 목록)",
"상태 = 공표 · 산정(원문 4-라 산정값을 값에 넣음 · 근거는 비고) · 미공표(원문에 값 없음) · 미확보(공표 노임에 같은 직종 없음) · 추정(원문이 이름을 맞대지 않아 작업 범위로 짐작 · 구분은 대응 직종 것 · 값은 비움 · 준용에 대응 직종 키 · 근거는 비고)",
"준용 = 관리자가 고르는 다른 직종 키 — 있으면 엔진이 그 직종 값을 씀(값이 있어도 앞섬) · 없으면 값 · 호표 출처에 「준용: <이름>」",
"상태 = 공표 · 산정(원문 4-라 산정값을 값에 넣음 · 근거는 비고) · 미공표(원문에 값 없음) · 미확보(공표 노임에 같은 직종 없음) · 추정(원문이 이름을 맞대지 않아 작업 범위로 짐작 · 구분·값·단위·일시간은 준용 직종 것 · 준용에 직종 키 · 근거 문서는 출처)",
"준용 = 관리자가 고르는 다른 직종 키 — 있으면 엔진이 그 직종 값을 씀(값이 있어도 앞섬) · 없으면 값 · 호표 출처에 「준용: <이름>」 · 상태 「추정」 은 제 값을 쓰고 「추정(준용: <이름>)」",
"새 조사 = 머리 「구분」 에 한 항목(원문 · 기관 · 판 · 공표일 · 원천 · 상세구분) 더하고 줄을 붙이면 끝 · 키는 LB 일련번호 이어 받음",
"옛이름 = 품셈이 쓰는 옛 직종명 목록(읽기 전용) · 근거 resources/knowledge/original/원가계산/노임단가_직종대응_근거.md"
],
@@ -597,10 +597,10 @@
{ "키": "LB000359", "원문번호": "나무의사", "구분": "산림", "상세구분": null, "이름": "나무의사", "규격": "", "단위": "원/일", "값": 326359, "출처": "산림노임 나무의사", "일시간": 8, "상태": "공표", "옛이름": [], "비고": null, "준용": null },
{ "키": "LB000360", "원문번호": "수목치료기술자", "구분": "산림", "상세구분": null, "이름": "수목치료기술자", "규격": "", "단위": "원/일", "값": 238447, "출처": "산림노임 수목치료기술자", "일시간": 8, "상태": "공표", "옛이름": [], "비고": null, "준용": null },
{ "키": "LB000362", "원문번호": "절단공", "구분": "미확보", "상세구분": null, "이름": "절단공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "미확보", "옛이름": [], "비고": "건설품셈 기계설비 13-6-11 · 건설품셈 기계설비 13-6-13 · 건설품셈 기계설비 13-6-17", "준용": null },
{ "키": "LB000373", "원문번호": "정보처리기사", "구분": "엔지니어링", "상세구분": "정보통신", "이름": "정보처리기사", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 엔산법 별표2 기사자격 = 초급기술자 · 부문은 일반값", "준용": "LB000292" },
{ "키": "LB000373", "원문번호": "정보처리기사", "구분": "엔지니어링", "상세구분": "정보통신", "이름": "정보처리기사", "규격": "", "단위": "원/일", "값": 249574, "출처": "엔산법 시행령 별표2", "일시간": 8, "상태": "추정", "옛이름": [], "비고": null, "준용": "LB000292" },
{ "키": "LB000384", "원문번호": "사진제판공", "구분": "미확보", "상세구분": null, "이름": "사진제판공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "미확보", "옛이름": [], "비고": "건설품셈 토목 9-5-6-2가 · 건설품셈 토목 9-5-7-2", "준용": null },
{ "키": "LB000385", "원문번호": "사진식자공", "구분": "미확보", "상세구분": null, "이름": "사진식자공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "미확보", "옛이름": [], "비고": "건설품셈 토목 9-5-6-2가 · 건설품셈 토목 9-5-7-2", "준용": null },
{ "키": "LB000386", "원문번호": "옵셋인쇄공", "구분": "제조업", "상세구분": "출판․인쇄", "이름": "옵셋인쇄공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 제조노임 31호 예시 「오프셋인쇄기조작원」", "준용": "LB000163" },
{ "키": "LB000386", "원문번호": "옵셋인쇄공", "구분": "제조업", "상세구분": "출판․인쇄", "이름": "옵셋인쇄공", "규격": "", "단위": "원/일", "값": 121205, "출처": "제조노임 직종해설 31호", "일시간": 8, "상태": "추정", "옛이름": [], "비고": null, "준용": "LB000163" },
{
"키": "LB000390",
"원문번호": "측량사",
@@ -617,15 +617,15 @@
"비고": "건설품셈 기계설비 13-5-2 · 건설품셈 기계설비 13-5-8 · 건설품셈 기계설비 13-6-1 · 건설품셈 기계설비 13-6-2 · 건설품셈 기계설비 13-6-3 · 건설품셈 기계설비 13-6-4 · 건설품셈 기계설비 13-6-6 · 건설품셈 기계설비 13-6-7 · 건설품셈 기계설비 13-6-8 · 건설품셈 기계설비 13-6-10 · 건설품셈 기계설비 13-6-12 · 건설품셈 기계설비 13-6-16 · 건설품셈 기계설비 13-7-1 · 건설품셈 기계설비 13-7-2 · 건설품셈 기계설비 13-7-4 · 건설품셈 기계설비 13-9-2 · 건설품셈 기계설비 13-10-2 · 건설품셈 기계설비 13-10-3 · 건설품셈 기계설비 13-11-3",
"준용": null
},
{ "키": "LB000391", "원문번호": "제관공", "구분": "건설업", "상세구분": null, "이름": "제관공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 13-6 노무 항목 · 공표는 플랜트제관공뿐", "준용": "LB000057" },
{ "키": "LB000392", "원문번호": "공작기계공", "구분": "제조업", "상세구분": "공작기계 조작", "이름": "공작기계공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 제조노임 옛 코드 37.선반원 → 69.선반기조작원 · 밀링원일 수 있음", "준용": "LB000202" },
{ "키": "LB000394", "원문번호": "마킹공", "구분": "건설업", "상세구분": null, "이름": "마킹공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 13-6 노무 항목 · 공표는 플랜트제관공뿐", "준용": "LB000057" },
{ "키": "LB000395", "원문번호": "산소절단공", "구분": "건설업", "상세구분": null, "이름": "산소절단공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 13-6 노무 항목 · 공표는 플랜트제관공뿐", "준용": "LB000057" },
{ "키": "LB000391", "원문번호": "제관공", "구분": "건설업", "상세구분": null, "이름": "제관공", "규격": "", "단위": "원/일", "값": 266029, "출처": "건설품셈 기계설비 13-06", "일시간": 8, "상태": "추정", "옛이름": [], "비고": null, "준용": "LB000057" },
{ "키": "LB000392", "원문번호": "공작기계공", "구분": "제조업", "상세구분": "공작기계 조작", "이름": "공작기계공", "규격": "", "단위": "원/일", "값": 123489, "출처": "제조노임 직종해설 70·85호", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "밀링원일 수 있음", "준용": "LB000202" },
{ "키": "LB000394", "원문번호": "마킹공", "구분": "건설업", "상세구분": null, "이름": "마킹공", "규격": "", "단위": "원/일", "값": 266029, "출처": "건설품셈 기계설비 13-06", "일시간": 8, "상태": "추정", "옛이름": [], "비고": null, "준용": "LB000057" },
{ "키": "LB000395", "원문번호": "산소절단공", "구분": "건설업", "상세구분": null, "이름": "산소절단공", "규격": "", "단위": "원/일", "값": 266029, "출처": "건설품셈 기계설비 13-06", "일시간": 8, "상태": "추정", "옛이름": [], "비고": null, "준용": "LB000057" },
{ "키": "LB000396", "원문번호": "측량기사", "구분": "미확보", "상세구분": null, "이름": "측량기사", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "미확보", "옛이름": [], "비고": "건설품셈 기계설비 13-6-8", "준용": null },
{ "키": "LB000397", "원문번호": "시험사1급", "구분": "건설업", "상세구분": null, "이름": "시험사1급", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 13-6 X-Ray촬영 = 비파괴검사", "준용": "LB000067" },
{ "키": "LB000397", "원문번호": "시험사1급", "구분": "건설업", "상세구분": null, "이름": "시험사1급", "규격": "", "단위": "원/일", "값": 199588, "출처": "건설노임 명칭변경표 2010.1", "일시간": 8, "상태": "추정", "옛이름": [], "비고": null, "준용": "LB000068" },
{ "키": "LB000398", "원문번호": "특수운전공", "구분": "미확보", "상세구분": null, "이름": "특수운전공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "미확보", "옛이름": [], "비고": "건설품셈 기계설비 13-6-8 · 건설품셈 기계설비 13-6-9", "준용": null },
{ "키": "LB000400", "원문번호": "제도공", "구분": "제조업", "상세구분": "CAD설계", "이름": "제도공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 제조노임 1호 예시 「기계 제도사」", "준용": "LB000133" },
{ "키": "LB000401", "원문번호": "현도공", "구분": "건설업", "상세구분": null, "이름": "현도공", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "추정", "옛이름": [], "비고": "추정: 작업 범위 해설로 짐작 — 13-6 노무 항목 · 공표는 플랜트제관공뿐", "준용": "LB000057" },
{ "키": "LB000400", "원문번호": "제도공", "구분": "제조업", "상세구분": "CAD설계", "이름": "제도공", "규격": "", "단위": "원/일", "값": 160065, "출처": "제조노임 직종해설 1호", "일시간": 8, "상태": "추정", "옛이름": [], "비고": null, "준용": "LB000133" },
{ "키": "LB000401", "원문번호": "현도공", "구분": "건설업", "상세구분": null, "이름": "현도공", "규격": "", "단위": "원/일", "값": 266029, "출처": "건설품셈 기계설비 13-06", "일시간": 8, "상태": "추정", "옛이름": [], "비고": null, "준용": "LB000057" },
{ "키": "LB000402", "원문번호": "측량조수", "구분": "미확보", "상세구분": null, "이름": "측량조수", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "미확보", "옛이름": [], "비고": "건설품셈 기계설비 13-6-12 · 건설품셈 기계설비 13-6-16", "준용": null },
{ "키": "LB000403", "원문번호": "시공측량기사", "구분": "미확보", "상세구분": null, "이름": "시공측량기사", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "미확보", "옛이름": [], "비고": "건설품셈 기계설비 13-6-14", "준용": null },
{ "키": "LB000404", "원문번호": "시공측량조수", "구분": "미확보", "상세구분": null, "이름": "시공측량조수", "규격": "", "단위": "원/일", "값": null, "출처": "준용대상", "일시간": 8, "상태": "미확보", "옛이름": [], "비고": "건설품셈 기계설비 13-6-14", "준용": null }
+6 -4
View File
@@ -626,11 +626,13 @@ def test_미공표_준용():
def test_추정은_준용_값에_표시(whole):
"""추정 = 원문이 이름을 맞대지 않아 작업 범위로 짐작한 대응 — 값은 비우고 준용 직종 값 · 출처에 「(추정)」."""
"""추정 = 작업 범위로 짐작한 대응 — 값은 준용 직종 것 그대로 · 출처는 근거 문서 · 호표에 「추정(준용: ○○)」."""
row = whole.get("LB:제관공")
assert row["상태"] == "추정" and row[""] is None and row["구분"] == "건설업"
assert row["비고"].startswith("추정: ") and row["옛이름"] == []
assert whole.value("LB:제관공") == (whole.get("LB:1057")[""], "준용: 플랜트제관공(추정)")
target = whole.get("LB:1057")
assert row["상태"] == "추정" and row["구분"] == "건설업" and row["옛이름"] == []
assert row[""] == target[""] and row["단위"] == target["단위"]
assert row["출처"] == "건설품셈 기계설비 13-06"
assert whole.value("LB:제관공") == (target[""], "추정(준용: 플랜트제관공)")
def test_노임_갈래_파일_원문_대조():