# -*- coding: utf-8 -*- """기계설비 글 속 계산용 수 → 계수 표 줄 (토목 규칙 + 기계설비 규칙). 주 한 줄 → [(구분, 값, 단위, 딸린 칸)]. 식 값은 값 칸에 식 글자 + 딸린 칸 「값원문」. """ import re from _md표_읽기 import R from _토목_계수 import clean from _토목_계수 import rows_of as base_rows PCT = r"([\d.]+)%" BASE = {"기준": "본 품"} def pct(name, v, sign, **more): return (name, R(v), "%", {**BASE, "가감": sign, **more}) def formulas(s): out = [] m = re.search(r"(보온공 품) = (\([^ ]+\)×V/C)", s) if m: out.append((m.group(1), m.group(2), "", {"값원문": m.group(0)})) m = re.search(r"(특별인부 품) = (보온공 품×[\d.]+)", s) if m: out.append((m.group(1), m.group(2), "", {"값원문": m.group(0)})) m = re.search(r"다음과 같이 계산한다\. (π×Tank직경×\(Tank철판단수-1\))", s) if m: out.append(("원주방향 용접장", m.group(1), "", {"값원문": m.group(1)})) return out def specific(s): out = [] for k, v in re.findall(r"(\d+)(?:㎜)? : ([\d.]+)(?= |$)", s) if "환산기준" in s else []: out.append((f"6㎜ 철판 환산기준 두께 {k}㎜", R(v), "", {})) m = re.search( r"수동용접 : " + PCT + r"\(공장가공\), " + PCT + r"\(현장가공\) 자동용접 : " + PCT + r"\(공장가공\), " + PCT + r"\(현장가공\)", s, ) if m: for nm, v in zip( ("수동용접 공장가공", "수동용접 현장가공", "자동용접 공장가공", "자동용접 현장가공"), m.groups(), ): out.append((f"작업효율 {nm}", R(v), "%", {})) m = re.search( r"전체배관 설치중량의 " + PCT + r"로 간주하여 배관하는 품으로 " + PCT + r" 증감할 때마다 본 품에 " + PCT + r"씩 가감", s, ) if m: out += [ ("Fitting류 등 중량 비율", R(m.group(1)), "%", {"기준": "전체배관 설치중량"}), ("증감 단위", R(m.group(2)), "%", {"기준": "전체배관 설치중량"}), ("증감 단위당 가감", R(m.group(3)), "%", BASE), ] m2 = re.search(r"본 품에 " + PCT + r" 범위 내에서 감하여", s) if m2: out.append(pct("공장제작조립 시 감", m2.group(1), "감")) m = re.search(r"옥내배관의 " + PCT + r"가산, 옥외매설관은 옥외배관의 " + PCT + r" 감", s) if m: out += [ ("기계실배관", R(m.group(1)), "%", {"기준": "옥내배관", "가감": "가산"}), ("옥외매설관", R(m.group(2)), "%", {"기준": "옥외배관", "가감": "감"}), ] m = re.search( r"조도가 (\d+#)를 기준한 것으로 (\d+#)까지 " + PCT + r", (\d+#)까지 " + PCT + r"를 감", s ) if m: out += [ ("조도 기준", R(m.group(1)[:-1]), "#", {}), (f"조도 {m.group(2)}까지", R(m.group(3)), "%", {**BASE, "가감": "감"}), (f"조도 {m.group(4)}까지", R(m.group(5)), "%", {**BASE, "가감": "감"}), ] m = re.search(r"Gas Heating의 경우 개소당 ([\d.]+)인", s) if m: out.append(("Gas Heating 개소당", R(m.group(1)), "인", {})) m = re.search(r"기름소모량은 (\d+)개소당 ([\d.]+)ℓ", s) if m: out.append((f"기름소모량 {m.group(1)}개소당", R(m.group(2)), "ℓ", {})) m = re.search(r"가루비누는 ㎥당 ([\d.]+)㎏", s) if m: out.append(("누설 Check용 가루비누", R(m.group(1)), "㎏/㎥", {})) m = re.search(r"1매를 ([\d.]+)㎡", s) if m: out.append(("3'×6' Sheet 1매", R(m.group(1)), "㎡", {})) m = re.search(r"Pipe길이 1m에 (\d+)회 감는", s) if m: out.append(("철선 Pipe길이 1m당 감는 횟수", R(m.group(1)), "회", {})) m = re.search(r"구멍지름이 (\d+)㎜이하일 때는 철골공 (\d+)인, (\d+)㎜ 이상일 때는 (\d+)인", s) if m: out += [ (f"송곳뚫기 구멍지름 {m.group(1)}㎜이하 철골공", R(m.group(2)), "인", {}), (f"송곳뚫기 구멍지름 {m.group(3)}㎜ 이상 철골공", R(m.group(4)), "인", {}), ] return out def clauses(s): """「… N% 가산」 꼴 절마다 한 줄 — ㉮㉯㉰ 로 갈린 것은 절별.""" out = [] parts = re.split(r"\s*[㉮-㉳]\s*", s) if re.search(r"[㉮-㉳]", s) else [s] for p in parts: rg = re.search(r"(\d+)∼(\d+)%(?:를|까지| 범위 내에서|씩)? ?(?:을 )?(가산|감|가감|증감)", p) if rg: out.append( ( re.sub(r"\s+", " ", p).strip(" ."), [R(rg.group(1)), R(rg.group(2))], "%", {**BASE, "가감": rg.group(3)}, ) ) continue found = re.findall( r"(\d[\d.]*)%(?:를|까지| 범위 내에서|씩)? ?(?:을 )?(가산|감|가감|증감)", p ) if not found: continue name = re.sub(r"\s+", " ", p).strip(" .") for v, sign in found[:1]: out.append((name, R(v), "%", {**BASE, "가감": sign})) return out def rows_of(line): s = clean(line) out = base_rows(re.sub(r"(인력품|주재료비|재료비)의\([^)]*\) ", r"\1의 ", line)) if out: return out out = formulas(s) + specific(s) if out: return out m = re.search(r"^(.+?)(?:은|는) 본 품에 " + PCT + r"를 (가산|감)", s) if m: return [pct(m.group(1), m.group(2), m.group(3))] m = re.search( r"(\d+)본 감할 때마다 " + PCT + r"씩 감하고, (\d+)본 증할 때마다 " + PCT + r"씩 가산", s ) if m: return [ pct(f"튜브 {m.group(1)}본 감할 때마다", m.group(2), "감"), pct(f"튜브 {m.group(3)}본 증할 때마다", m.group(4), "가산"), ] m = re.search( r"(높이 6∼9m까지는) 품을 " + PCT + r" 가산하고 (높이 9m를 초과하는 경우 매 3m 증가마다) 품을 " + PCT, s, ) if m: return [ pct(f"비계 사용 {m.group(1)}", m.group(2), "가산"), pct(f"비계 사용 {m.group(3)}", m.group(4), "가산"), ] m = re.search(r"단독주택 (\d+)호당 1조 및 집단아파트 (\d+)호당 1조", s) if m: return [ ("단독주택 1조당 호수", R(m.group(1)), "호", {}), ("집단아파트 1조당 호수", R(m.group(2)), "호", {}), ] return clauses(s)