knowledge(마스터): 원문번호에서 번호 뒤 제목 뺌 — 절 번호만

- 소요량 · 계수 · 로직 · 기계 4,418 줄의 원문번호를 절 번호만으로(부문·제목 뗌) — 건설품셈 부문은 구분 칸에 있음
- 한 절에 표가 여럿이어도 번호는 같게 둠 — 식별은 키
- 대장 _키대장.json 의 원문번호는 옛 열쇠 그대로(빌더가 키를 다시 찾는 열쇠) · master_keys.stamp 가 줄에만 절 번호를 씀
- check_master — 부문 앞붙임 검사를 「절 번호만」 검사로 · 원문번호 겹침은 인력·재료만 · 대장 대조는 옛 열쇠·절 번호 둘 다 받음
- master_formula — 겹친 원문번호를 「ID:원문번호」 로 부르면 멈춤
- compare_estx · 시험의 「ID:원문번호」 참조를 키로 갈아 끼움 · M01 새 로직 초안 번호에서 부문 뺌
- test_자재품목_열_한_벌 의 낡은 기대값을 지금 데이터에 맞춤(관급 열이 조달청 값으로 바뀜)

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 18:03:54 +09:00
co-authored by Claude Opus 5
parent 9624fa6a5f
commit 4ab369c841
147 changed files with 4569 additions and 4557 deletions
+37 -37
View File
@@ -229,10 +229,10 @@ MACH_WORDS = (
)
FIRST = ("0201-0020", "0201-0040", "0201-0070", "0101-", "0602-", "1306-", "1305-", "0230-")
LOGICS = [
"공통 8 기계 시간당 경비",
"공통 8 기계 시간당 경비(연료 없음)",
"공통 8 기계 시간당 경비(조종원 없음)",
"공통 8 기계 시간당 손료",
"GC000268", # 공통 8 기계 시간당 경비
"GC000276", # 공통 8 기계 시간당 경비(연료 없음)
"GC000272", # 공통 8 기계 시간당 경비(조종원 없음)
"GC000273", # 공통 8 기계 시간당 손료
]
@@ -247,7 +247,7 @@ def mach_key(name, size) -> str:
def machine_cost(master: mf.Master, mid: str, region="전국평균"):
"""로직으로 계산 — 고르기 밖 기계는 메모리에서만 고르기에 더함."""
for key in LOGICS:
row = master.logic("GC:" + key)
row = master.logic(key)
spec = next(i for i in row["입력"] if i["이름"] == "기계")
added = mid not in spec["고르기"]
if added:
@@ -255,7 +255,7 @@ def machine_cost(master: mf.Master, mid: str, region="전국평균"):
try:
given = {"기계": mid, "지역": region}
given = {k: v for k, v in given.items() if any(i["이름"] == k for i in row["입력"])}
return key, mf.run(master, "GC:" + key, given)
return key, mf.run(master, key, given)
except (mf.FormulaError, ArithmeticError, KeyError, TypeError):
continue
finally:
@@ -314,50 +314,50 @@ def machine(estx: Estx, files: dict, master: mf.Master):
# ── (4) 일위대가 ──────────────────────────────────────────────────────
# (ESTX 제목 코드, 로직 원문번호, 입력[, 단위 환산 배수 — 우리 값 × 배수 = ESTX 단위])
# (ESTX 제목 코드, 로직 키, 입력[, 단위 환산 배수 — 우리 값 × 배수 = ESTX 단위])
REGION = {"지역": "전국평균", "보정작업": "해당 없음"}
PAIRS = [
(
"U0000001217",
"공통 3-2-1 굴착(인력/토사)",
"GC000083", # 공통 3-2-1 굴착(인력/토사)
{"토질": "보통토사", "넓은구역가산": 0, "용수감": 0, "잔토처리": "없음"},
),
(
"U0000001218",
"공통 3-2-1 굴착(인력/토사)",
"GC000083", # 공통 3-2-1 굴착(인력/토사)
{"토질": "경질토사", "넓은구역가산": 0, "용수감": 0, "잔토처리": "없음"},
),
("U0000001665", "공통 3-9-1 벌목", {"나무높이": 4, "집재거리": 100, **REGION}, "0.1"),
("U0000001666", "공통 3-9-1 벌목", {"나무높이": 6, "집재거리": 100, **REGION}, "0.1"),
("U0000001667", "공통 3-9-1 벌목", {"나무높이": 10, "집재거리": 100, **REGION}, "0.1"),
("U0000001260", "공통 4-1-1 잔디붙임", {"시공법": "평떼"}),
("U0000001261", "공통 4-1-1 잔디붙임", {"시공법": "줄떼"}),
("U0000001665", "GC000129", {"나무높이": 4, "집재거리": 100, **REGION}, "0.1"),
("U0000001666", "GC000129", {"나무높이": 6, "집재거리": 100, **REGION}, "0.1"),
("U0000001667", "GC000129", {"나무높이": 10, "집재거리": 100, **REGION}, "0.1"),
("U0000001260", "GC000143", {"시공법": "평떼"}),
("U0000001261", "GC000143", {"시공법": "줄떼"}),
(
"U0000002799",
"공통 4-3-4 식재(나무높이)",
"GC000154", # 공통 4-3-4 식재(나무높이)
{"구분": "인력시공", "나무높이": "2.0이하", "지주목": "세움", **REGION},
),
(
"U0000002802",
"공통 4-3-4 식재(나무높이)",
"GC000154", # 공통 4-3-4 식재(나무높이)
{"구분": "인력시공", "나무높이": "3.0이하", "지주목": "세움", **REGION},
),
(
"U0000002693",
"공통 4-3-2 굴취(나무높이)",
"GC000152", # 공통 4-3-2 굴취(나무높이)
{"구분": "인력시공", "나무높이": "2.0이하", "야생감": 0, "분": "분 있음", **REGION},
),
(
"U0000003316",
"공통 4-3-2 굴취(나무높이)",
"GC000152", # 공통 4-3-2 굴취(나무높이)
{"구분": "기계시공", "나무높이": "2.0이하", "야생감": 0, "분": "분 있음", **REGION},
),
("U0000002794", "공통 4-2-2 식재(단식)", {"나무높이": "0.3미만"}),
("U0000002633", "공통 4-2-3 식재(군식)", {"나무높이": "1.2~1.5이하"}),
("U0000002661", "공통 4-1-4 초화류 식재", {"등급": "보통", "특수화단감": 0}),
("U0000002794", "GC000149", {"나무높이": "0.3미만"}),
("U0000002633", "GC000150", {"나무높이": "1.2~1.5이하"}),
("U0000002661", "GC000146", {"등급": "보통", "특수화단감": 0}),
(
"U0000001171",
"공통 6-1-1 레디믹스트콘크리트 타설",
"GC000198", # 공통 6-1-1 레디믹스트콘크리트 타설
{
"타설방법": "인력운반타설",
"구조물": "무근구조물",
@@ -368,7 +368,7 @@ PAIRS = [
),
(
"U0000001172",
"공통 6-1-1 레디믹스트콘크리트 타설",
"GC000198", # 공통 6-1-1 레디믹스트콘크리트 타설
{
"타설방법": "인력운반타설",
"구조물": "철근구조물",
@@ -377,10 +377,10 @@ PAIRS = [
"지역": "전국평균",
},
),
("U0000003127", "공통 6-2-2 철근 현장가공", {"Type": "Type-Ⅰ"}),
("U0000003127", "GC000206", {"Type": "Type-Ⅰ"}),
(
"U0000001068",
"공통 6-3-1 합판거푸집",
"GC000211", # 공통 6-3-1 합판거푸집
{
"유형": "복잡",
"사용횟수": "3회",
@@ -394,24 +394,24 @@ PAIRS = [
"구멍땜": 0,
},
),
("U0000001101", "공통 2-7-1 강관비계 설치 및 해체", {"높이": "10m이하", "보호망": "시공"}),
("U0000001101", "GC000022", {"높이": "10m이하", "보호망": "시공"}),
(
"U0000001988",
"유지관리 1-2-12 예초",
"GC001009", # 유지관리 1-2-12 예초
{"연간시공횟수": "연3회 이상", "경사도": "25˚ 미만", "그물막": "필요 없음"},
),
("U0000001958", "공통 3-7-3 천연섬유사면보호공 설치", {}),
("U0000001668", "공통 6-1-6 콘크리트 치핑", {}),
("U0000001703", "공통 5-3-4 말뚝두부정리(콘크리트)", {"규격": "ø400", "지역": "전국평균"}),
("U0000001694", "공통 5-3-3 말뚝두부정리(강관)", {"규격": "ø400", "지역": "전국평균"}),
("U0000003394", "토목 6-2-1 타이튼 접합 및 부설 인력", {"관경": 80, "시공조건": "시공조건 A"}),
("U0000077626", "토목 6-3-1 부설 인력", {"관경": 80, "시공조건": "시공조건 A"}),
("U0000001958", "GC000117", {}),
("U0000001668", "GC000204", {}),
("U0000001703", "GC000193", {"규격": "ø400", "지역": "전국평균"}),
("U0000001694", "GC000192", {"규격": "ø400", "지역": "전국평균"}),
("U0000003394", "GC000383", {"관경": 80, "시공조건": "시공조건 A"}),
("U0000077626", "GC000388", {"관경": 80, "시공조건": "시공조건 A"}),
(
"U0000003527",
"토목 6-8-1 주철제 게이트 제수밸브 부설 및 접합 인력",
"GC000411", # 토목 6-8-1 주철제 게이트 제수밸브 부설 및 접합 인력
{"관경": 50, "시공조건": "시공조건 A"},
),
("U0000001289", "건축 11-2-6 녹막이 페인트칠", {"시공면": "벽", "비계층수": 0}),
("U0000001289", "GC000714", {"시공면": "벽", "비계층수": 0}),
]
@@ -449,11 +449,11 @@ def unit_price(estx: Estx, master: mf.Master):
h = heads[code]
k = Decimal(scale[0]) if scale else Decimal(1)
temp, put = with_estx_materials(master, estx, code)
row = temp.logic("GC:" + key)
row = temp.logic(key)
given = {k: v for k, v in given.items() if any(i["이름"] == k for i in row.get("입력", []))}
given = {k: Decimal(str(v)) if isinstance(v, (int, float)) else v for k, v in given.items()}
try:
res = mf.run(temp, "GC:" + key, given)
res = mf.run(temp, key, given)
res = {c: res[c] * k for c in ("계", *mf.COST_ITEMS)}
except (mf.FormulaError, ArithmeticError, KeyError, TypeError) as e:
print(f" {code} {h['Name']} {h.get('Size')} | {key} | 멈춤: {str(e)[:120]}")