feat(master_data): 건설품셈 공통 6장 로직 60개 — 철근콘크리트공사
- 로직_건설품셈_공통6장.json: 콘크리트 · 철근 · 거푸집 · PSC · 교량 가설·부대공 · 조립식 구조물 - 일당 편성 표 = 편성 ÷ 시공량 · 기계 1대 × 8시간 ÷ 시공량 · 공구손료는 인력품(작업조 노임)의 % - 8장: 기계 고르기 더함 · 조종원직종 입력 로직 새로(고소작업차 — 원문 운전사 구분에 이름 없음) - 재료_자체: 에폭시 접착제 · 폼타이 규격 · 강재거푸집 · 문양거푸집 · 원형맨홀거푸집 · 쉬즈관 - 식 엔진: 맞는 줄이 여럿이면 찾는 값 칸이 있는 줄만 · 괄호 든 칸 이름은 작은따옴표 - 막힘: 6-2-5(절단공 노임 요소 없음) · 6-3-6 해체(특수비계공 노임 요소 없음) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V1MKKZKpUHTPKb513FneU8
This commit is contained in:
@@ -112,6 +112,7 @@
|
||||
- 요소 — `그룹:원문:열쇠` · 값 묶음은 `.칸` — `기계:건설품셈:0201-0070.주연료` · 둘째 쌍점 뒤는 모두 열쇠(`재료:오피넷유가:경유:전국평균`).
|
||||
- 열쇠에 `{이름}` — 입력·중간 값을 끼움 — `기계:건설품셈:{기계}.가격`
|
||||
- 표 찾기 — `찾기(소요량:산림품셈:13-4-1 메쌓기, 뒷길이=뒷길이, 돌=돌, 쌓기=쌓기).석공`
|
||||
- 맞는 줄이 여럿이면 찾는 값 칸이 있는 줄만 봄. 칸 이름에 괄호·빈칸이 있으면 작은따옴표 — `.'시공량(m)'`
|
||||
- 찾기·로직 인자의 글자 값은 작은따옴표 — `구분='V(다짐속도,km/hr)'` · 따옴표 없으면 이름(입력·중간).
|
||||
- 로직 부르기 — `로직(건설품셈:8 굴착기(무한궤도) 시간당 경비, 기계='0201-0070')` · 돈 로직의 결과는 비목 묶음 `.노무비` `.재료비` `.경비` `.계` · 돈 아닌 로직은 수 하나.
|
||||
- 입력 · 중간 · 비목 합은 이름 그대로.
|
||||
|
||||
@@ -104,9 +104,16 @@ class _Parser:
|
||||
return ("neg", self.unary())
|
||||
node = self.primary()
|
||||
while self.take("."):
|
||||
node = ("field", node, self.name())
|
||||
node = ("field", node, self.quoted() if self.take("'") else self.name())
|
||||
return node
|
||||
|
||||
def quoted(self) -> str:
|
||||
end = self.s.find("'", self.i)
|
||||
if end < 0:
|
||||
self.fail("작은따옴표 안 닫힘")
|
||||
text, self.i = self.s[self.i : end], end + 1
|
||||
return text
|
||||
|
||||
def name(self) -> str:
|
||||
self.ws()
|
||||
m = _NAME.match(self.s, self.i)
|
||||
@@ -267,7 +274,7 @@ def _match(table: dict, row: dict, cond: str, want) -> bool:
|
||||
return have == want
|
||||
|
||||
|
||||
def find(table: dict, conds: dict) -> dict:
|
||||
def find(table: dict, conds: dict, want: str | None = None) -> dict:
|
||||
for cond in conds:
|
||||
if cond not in table.get("조건", {}):
|
||||
raise FormulaError(f"「{table['열쇠']}」 에 없는 조건 「{cond}」")
|
||||
@@ -277,6 +284,8 @@ def find(table: dict, conds: dict) -> dict:
|
||||
ups = [r[c][1] for r in hits if table["조건"].get(c) == "범위" and r.get(c)]
|
||||
if ups and None not in ups:
|
||||
hits = [r for r in hits if not r.get(c) or r[c][1] == min(ups)]
|
||||
if len(hits) > 1 and want: # 여러 줄이면 찾는 값 칸이 있는 줄만
|
||||
hits = [row for row in hits if want in row]
|
||||
if len(hits) != 1:
|
||||
raise FormulaError(f"「{table['열쇠']}」 {conds} 맞는 줄 {len(hits)}개")
|
||||
return hits[0]
|
||||
@@ -298,7 +307,12 @@ def evaluate(node, env: dict, master: Master, depth: int = 0):
|
||||
raise FormulaError(f"「{node[1]}」 값이 범위 — 입력으로 받아야 함")
|
||||
return value
|
||||
if kind == "field":
|
||||
base = evaluate(node[1], env, master, depth)
|
||||
if node[1][0] == "find":
|
||||
table = master.get(fill(node[1][1], env))
|
||||
conds = {k: evaluate(v, env, master, depth) for k, v in node[1][2]}
|
||||
base = find(table, conds, node[2])
|
||||
else:
|
||||
base = evaluate(node[1], env, master, depth)
|
||||
if not isinstance(base, dict) or node[2] not in base:
|
||||
raise FormulaError(f"칸 「{node[2]}」 없음")
|
||||
value = base[node[2]]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -69,7 +69,7 @@
|
||||
"출처": "건설품셈 공통 8-1-5 · 8-1-6",
|
||||
"소유": "공용",
|
||||
"입력": [
|
||||
{ "이름": "기계", "고르기": ["1730-0015", "7204-0055", "0602-0150", "2702-0020", "0101-0007", "0101-0010", "0101-0012", "0101-0019", "0101-0032", "2105-0005", "2104-0010", "2104-0015", "2104-0020", "2104-0025", "2104-0030", "2104-0035", "2104-0040", "2104-0045", "2104-0050", "2104-0060", "2104-0070", "2104-0080", "2104-0100", "2104-0130", "2104-0160", "2104-0200", "2104-0220", "2104-0250", "2104-0300", "4504-0032", "4504-0036", "4504-0041", "4504-0043", "4504-0047", "4504-0052", "4205-0010", "4205-0017", "4205-0020", "4205-0030", "4205-0040", "4205-0045"] },
|
||||
{ "이름": "기계", "고르기": ["1730-0015", "7204-0055", "0602-0150", "2702-0020", "0101-0007", "0101-0010", "0101-0012", "0101-0019", "0101-0032", "2105-0005", "2104-0010", "2104-0015", "2104-0020", "2104-0025", "2104-0030", "2104-0035", "2104-0040", "2104-0045", "2104-0050", "2104-0060", "2104-0070", "2104-0080", "2104-0100", "2104-0130", "2104-0160", "2104-0200", "2104-0220", "2104-0250", "2104-0300", "4504-0032", "4504-0036", "4504-0041", "4504-0043", "4504-0047", "4504-0052", "4205-0010", "4205-0017", "4205-0020", "4205-0030", "4205-0040", "4205-0045", "2105-0002", "2105-0003", "2105-0010", "2105-0015", "2105-0018", "2502-0025", "0602-0025", "2502-0050", "2101-0010", "2101-0015", "2101-0020", "2101-0025", "2101-0030", "2101-0035", "2101-0040", "2101-0050", "2101-0070", "2101-0080", "2101-0100", "2101-0150", "2101-0220", "2101-0280", "2101-0300"] },
|
||||
{
|
||||
"이름": "지역",
|
||||
"고르기": [
|
||||
@@ -304,10 +304,7 @@
|
||||
"입력": [
|
||||
{
|
||||
"이름": "기계",
|
||||
"고르기": [
|
||||
"7620-0003",
|
||||
"7730-0150"
|
||||
]
|
||||
"고르기": ["7620-0003", "7730-0150", "6516-0060", "6516-0120", "6516-0250", "6516-0300", "6105-0190", "6202-0060", "0230-0002"]
|
||||
}
|
||||
],
|
||||
"중간": [
|
||||
@@ -328,6 +325,79 @@
|
||||
],
|
||||
"끝수": "손료 원 미만 버림(건설품셈 공통 8-1-5 12)",
|
||||
"비고": "원문 운전경비 표에 주연료·조종원이 없는 기종(절단기 · 펌프) — 동력비는 원문대로 별도"
|
||||
},
|
||||
{
|
||||
"열쇠": "8 기계 시간당 경비(조종원직종 입력)",
|
||||
"이름": "기계 시간당 기계경비(조종원직종 입력)",
|
||||
"결과단위": "원/시간",
|
||||
"출처": "건설품셈 공통 8-1-5 · 8-1-6",
|
||||
"소유": "공용",
|
||||
"입력": [
|
||||
{
|
||||
"이름": "기계",
|
||||
"고르기": ["2106-0002", "2106-0003", "2106-0005"]
|
||||
},
|
||||
{
|
||||
"이름": "지역",
|
||||
"고르기": ["전국평균", "전국", "서울", "경기", "강원", "충북", "충남", "전북", "경북", "경남", "부산", "제주", "대구", "인천", "대전", "울산", "세종", "전남광주"],
|
||||
"출처": "건설품셈 공통 8-1-7 5"
|
||||
},
|
||||
{
|
||||
"이름": "조종원직종",
|
||||
"고르기": ["1048", "1049", "1050"],
|
||||
"출처": "건설품셈 공통 8-1-3 5",
|
||||
"비고": "원문 운전사 구분에 기종 이름 없음 — 설계자가 고름(1048 건설기계운전사 · 1049 화물차운전사 · 1050 일반기계운전사)"
|
||||
}
|
||||
],
|
||||
"중간": [
|
||||
{
|
||||
"이름": "손료",
|
||||
"식": "버림(기계:건설품셈:{기계}.가격 * 1000 * ((기계:건설품셈:{기계}.상각비계수 + 기계:건설품셈:{기계}.정비비계수) + 기계:건설품셈:{기계}.관리비계수) / 10000000, 0)",
|
||||
"출처": "건설품셈 공통 8-1-5 12 · 8-1-6 4"
|
||||
},
|
||||
{
|
||||
"이름": "연료",
|
||||
"식": "기계:건설품셈:{기계}.주연료종류",
|
||||
"출처": "건설품셈 공통 8-4 주①㉰"
|
||||
}
|
||||
],
|
||||
"호표": [
|
||||
{
|
||||
"종류": "재료",
|
||||
"요소": "재료:오피넷유가:{연료}:{지역}",
|
||||
"이름": "주연료",
|
||||
"단위": "ℓ",
|
||||
"수량": "기계:건설품셈:{기계}.주연료",
|
||||
"비목": "재료비",
|
||||
"출처": "건설품셈 공통 8-4-1"
|
||||
},
|
||||
{
|
||||
"종류": "인력",
|
||||
"요소": "인력:건설노임:{조종원직종}",
|
||||
"이름": "조종원",
|
||||
"단위": "인",
|
||||
"수량": "기계:건설품셈:{기계}.조종원 / 8",
|
||||
"비목": "노무비",
|
||||
"출처": "건설품셈 공통 8-1-3 6",
|
||||
"비고": "환산 근거 미확인 — 우선 하루 ÷ 8"
|
||||
}
|
||||
],
|
||||
"덧줄": [
|
||||
{
|
||||
"이름": "잡재료비",
|
||||
"식": "재료비 * 기계:건설품셈:{기계}.잡재료율 / 100",
|
||||
"비목": "재료비",
|
||||
"출처": "건설품셈 공통 8-4 주②"
|
||||
},
|
||||
{
|
||||
"이름": "기계손료",
|
||||
"식": "손료",
|
||||
"비목": "경비",
|
||||
"출처": "건설품셈 공통 8-1-6 2"
|
||||
}
|
||||
],
|
||||
"끝수": "손료 원 미만 버림(건설품셈 공통 8-1-5 12) · 합계 원문 규정 없음",
|
||||
"비고": "원문 8-1-3 5 운전사 구분에 이름 없는 기종 — 조종원직종을 설계자가 고름"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
"비고": "공시에 없는 재료 — 이름·규격·단위만 · 값은 관리자가 물가지·견적으로 채움",
|
||||
"줄": [
|
||||
{ "열쇠": "레미콘", "이름": "레디믹스트콘크리트", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 12-9-1 · 12-11-1 · 12-11-2-1 · 12-12 · 12-13 · 12-15 · 12-16 · 12-17-2 · 12-17-3 · 13-4-4 주① · 13-4-5 · 13-5-1 주⑤ · 13-5-2 · 규격(강도·골재·슬럼프)별 값이 다르면 관리자가 줄을 나눔" },
|
||||
{ "열쇠": "시멘트", "이름": "시멘트", "규격": "", "단위": "kg", "값": null, "출처": "자체", "비고": "산림품셈 12-1-3 주⑤⑥ · 12-17-1-2 주③" },
|
||||
{ "열쇠": "시멘트", "이름": "시멘트", "규격": "", "단위": "kg", "값": null, "출처": "자체", "비고": "산림품셈 12-1-3 주⑤⑥ · 12-17-1-2 주③ · 건설품셈 공통 6-3-1 주⑤" },
|
||||
{ "열쇠": "모래(중량)", "이름": "모래", "규격": "건조상태", "단위": "kg", "값": null, "출처": "자체", "비고": "산림품셈 12-1-3 주⑤" },
|
||||
{ "열쇠": "모래", "이름": "모래", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 12-11-3 · 12-17-1-2 주③" },
|
||||
{ "열쇠": "모래", "이름": "모래", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 12-11-3 · 12-17-1-2 주③ · 건설품셈 공통 6-3-1 주⑤" },
|
||||
{ "열쇠": "자갈(중량)", "이름": "자갈 또는 부순돌", "규격": "", "단위": "kg", "값": null, "출처": "자체", "비고": "산림품셈 12-1-3 주⑤" },
|
||||
{ "열쇠": "자갈", "이름": "자갈", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 12-17-1-2 주③" },
|
||||
{ "열쇠": "이형철근", "이름": "이형철근", "규격": "", "단위": "ton", "값": null, "출처": "자체", "비고": "산림품셈 12-15 · 12-16" },
|
||||
@@ -17,7 +17,7 @@
|
||||
{ "열쇠": "강봉 D32㎜", "이름": "강봉", "규격": "D32㎜, L=1000㎜", "단위": "EA", "값": null, "출처": "자체", "비고": "산림품셈 12-30-1" },
|
||||
{ "열쇠": "사다리", "이름": "사다리", "규격": "∅19㎜ 아연도금 및 스테인레스", "단위": "ton", "값": null, "출처": "자체", "비고": "산림품셈 12-16" },
|
||||
{ "열쇠": "고철", "이름": "고철", "규격": "", "단위": "kg", "값": null, "출처": "자체", "비고": "산림품셈 9-8-1 주4 · 12-34-3" },
|
||||
{ "열쇠": "폼타이", "이름": "폼타이(Form Tie)", "규격": "D형 1/2인치", "단위": "본", "값": null, "출처": "자체", "비고": "산림품셈 12-4 주⑦" },
|
||||
{ "열쇠": "폼타이", "이름": "폼타이(Form Tie)", "규격": "D형 1/2인치", "단위": "본", "값": null, "출처": "자체", "비고": "산림품셈 12-4 주⑦ · 건설품셈 공통 6-3-1 주④" },
|
||||
{ "열쇠": "문양 스티로폴", "이름": "문양 스티로폴(자재비 포함)", "규격": "", "단위": "㎡", "값": null, "출처": "자체", "비고": "산림품셈 12-5" },
|
||||
{ "열쇠": "커터 블레이드", "이름": "커터 블레이드", "규격": "320~400㎜", "단위": "개", "값": null, "출처": "자체", "비고": "산림품셈 12-7-1 주③" },
|
||||
{ "열쇠": "물", "이름": "물", "규격": "", "단위": "ℓ", "값": null, "출처": "자체", "비고": "산림품셈 12-7-1 주④" },
|
||||
@@ -70,6 +70,18 @@
|
||||
{ "열쇠": "줄눈 모르타르", "이름": "줄눈메꿈 모르타르", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 13-4-4 주④ · 13-5-1 주③" },
|
||||
{ "열쇠": "틈메우기돌", "이름": "틈메우기돌", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 13-5-1 주④" },
|
||||
{ "열쇠": "철망태", "이름": "철망태(사각형 돌망태)", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 13-11-4" },
|
||||
{ "열쇠": "돌망태 채움재", "이름": "채움재(돌망태)", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 13-11-4" }
|
||||
{ "열쇠": "돌망태 채움재", "이름": "채움재(돌망태)", "규격": "", "단위": "㎥", "값": null, "출처": "자체", "비고": "산림품셈 13-11-4" },
|
||||
{ "열쇠": "에폭시 신구콘크리트 접착제", "이름": "Epoxy 신구-콘크리트 접착제", "규격": "", "단위": "kg", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-1-5" },
|
||||
{ "열쇠": "에폭시 콘크리트고무 접착제", "이름": "Epoxy-콘크리트 고무 접착제", "규격": "", "단위": "kg", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-1-5" },
|
||||
{ "열쇠": "폼타이 9.5㎜", "이름": "폼타이(Form Tie)", "규격": "9.5㎜", "단위": "본", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-1 주④" },
|
||||
{ "열쇠": "폼타이 7.9㎜", "이름": "폼타이(Form Tie)", "규격": "7.9㎜", "단위": "본", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-1 주④" },
|
||||
{ "열쇠": "강재거푸집", "이름": "강재거푸집", "규격": "두께 3.2㎜", "단위": "㎡", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-2" },
|
||||
{ "열쇠": "문양거푸집 판넬", "이름": "문양거푸집(판넬)", "규격": "", "단위": "㎡", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-4" },
|
||||
{ "열쇠": "합성수지 원형맨홀거푸집 ø740", "이름": "합성수지(P.E) 원형 맨홀 거푸집", "규격": "ø740", "단위": "조", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-5 주④" },
|
||||
{ "열쇠": "합성수지 원형맨홀거푸집 ø900", "이름": "합성수지(P.E) 원형 맨홀 거푸집", "규격": "ø900", "단위": "조", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-5 주④" },
|
||||
{ "열쇠": "합성수지 원형맨홀거푸집 ø1200", "이름": "합성수지(P.E) 원형 맨홀 거푸집", "규격": "ø1200", "단위": "조", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-5 주④" },
|
||||
{ "열쇠": "합성수지 원형맨홀거푸집 ø1500", "이름": "합성수지(P.E) 원형 맨홀 거푸집", "규격": "ø1500", "단위": "조", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-5 주④" },
|
||||
{ "열쇠": "합성수지 원형맨홀거푸집 ø1800", "이름": "합성수지(P.E) 원형 맨홀 거푸집", "규격": "ø1800", "단위": "조", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-3-5 주④" },
|
||||
{ "열쇠": "쉬즈관", "이름": "쉬즈관", "규격": "", "단위": "m", "값": null, "출처": "자체", "비고": "건설품셈 공통 6-4-1 주④ · 6-4-2 주④" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -240,3 +240,20 @@ def test_로직_검사가_틀린_열쇠를_잡음(whole):
|
||||
|
||||
def test_돌고_도는_참조():
|
||||
assert mf.find_loops({"가": {"나"}, "나": {"가"}}) == [["가", "나", "가"]]
|
||||
|
||||
|
||||
def test_찾기_값칸_있는_줄만():
|
||||
table = {
|
||||
"열쇠": "시험",
|
||||
"조건": {"구분": "고르기", "높이": "고르기"},
|
||||
"줄": [
|
||||
{"구분": "비계공", "수량": 3},
|
||||
{"높이": "4m이하", "시공량(m)": 100},
|
||||
{"높이": "7m이하", "시공량(m)": 70},
|
||||
],
|
||||
}
|
||||
assert mf.find(table, {"구분": "비계공"}, "수량")["수량"] == 3
|
||||
assert mf.find(table, {"높이": "7m이하"}, "시공량(m)")["시공량(m)"] == 70
|
||||
with pytest.raises(mf.FormulaError):
|
||||
mf.find(table, {"높이": "7m이하"})
|
||||
assert mf.parse("찾기(소요량:건설품셈:시험, 높이='7m이하').'시공량(m)'")[2] == "시공량(m)"
|
||||
|
||||
Reference in New Issue
Block a user