180 lines
6.6 KiB
Python
180 lines
6.6 KiB
Python
# -*- 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)
|