Files
Aislo/resources/master_data/scripts/_설비_계수.py
T

180 lines
6.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- 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)