- Finger — 풀이 두 벌(_text · _stmate) 걷고 블록 단위 줄 투영 하나(_units) · 글은 조건 · 옛 판 · 계수 · 「…의 N %」 만 · 셈 밖 줄 안 씀 - Shares — 몫 = 단위 줄을 절(제목 · 윗절)로 묶음 한 벌 · 식 다시 풀기(qty_of · sections_stm) 걷음 · trade = ReadEst.trade - Elem.prices = 단위 줄 단가(글 다시 안 풂 · machines 갈래 안 건드림) - Match.clause = Basis.clause 만 · 대체 몸 · _TYPO_CLAUSE 걷음(오타는 읽기 ReadEst.sources) · fix_typo = 사본(Line 이 부름) - Fit.cache_path — HP 지문 칸(올린 엑셀 sha256 + 판) · 파일 그대로면 다시 안 읽음(lru) · 붙여넣기 HP 만 파일 해시 - 지문 전후 = 셈 단위 275 중 150 같음 · 다름 = 장비 절 · 글(쓰는 곳 없음) 100 · 고침(STmate 기계 두 묶음 · 거창 자재 · 끝 점 직종 · 옛 몫 금액 ÷ 단가 엉터리 · 제외금액 줄) — 골든 1위 줄마다 · 불리는 블록 206 갈래 · 1위 · 상태 전후 같음(162/177 · 기초 80 · SK 37 · 대기 89) - S1 다시 굳힘 = 봉화 · 울진대흥 · 울진소광 자원(같은 코드 두 묶음 따로) · S2 다시 굳힘 125/275(위 까닭) - 시험 고침 — finger(블록 = ReadEst.items · STmate 단위 줄 · 셈 밖) · fit 옛 HP(항목 · 글 없음) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
50 lines
2.3 KiB
Python
50 lines
2.3 KiB
Python
"""M02 일위대가 맞춤 몫(PLAN 338-1 · 설계 2-2 · 2-7 · 776-3) — 단가산출 블록 단위 줄을 절(맨 윗 절 ·
|
|
작은 절)마다 묶어 노임(직종 → 인) · 장비(「굴착기|0.6」 → 시간) 벡터. 형식 모름(단위 줄만 ·
|
|
`M02_Hopyo_UnitLine`) · 셈 밖 줄 뺌 · 금액 안 씀 · 장비 갈래 = `M02_Hopyo_Words.mtypes`.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from typing import Any
|
|
|
|
from M02_MasterTemplete.M02_Hopyo_ReadEst import trade # 노임 이름 → 우리 인력(B09 도 씀)
|
|
from M02_MasterTemplete.M02_Hopyo_Words import mtypes, nfkc
|
|
|
|
__all__ = ["eq_key", "sections", "trade"]
|
|
_SIZE = re.compile(r"(\d+(?:\.\d+)?)\s*(㎥|m3|톤|ton|t\b|kw|hp)", re.I)
|
|
|
|
|
|
def eq_key(text: Any) -> str | None:
|
|
"""장비 글 → 「굴착기|0.6」(갈래 + 로 묶음 · 크기 없으면 「굴착기|」) · 장비 아니면 None."""
|
|
kinds = mtypes(text)
|
|
if not kinds:
|
|
return None
|
|
m = _SIZE.search(nfkc(text).replace(",", ""))
|
|
size = (
|
|
m.group(1).rstrip("0").rstrip(".") if m and "." in m.group(1) else m.group(1) if m else ""
|
|
)
|
|
return f"{'+'.join(sorted(kinds))}|{size}"
|
|
|
|
|
|
def _part(title: str, parent: str) -> dict[str, Any]:
|
|
return {"제목": title, "절": parent, "노임": {}, "장비": {}}
|
|
|
|
|
|
def sections(units: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
"""블록 단위 줄(`M02_Hopyo_UnitLine`) → 몫마다 {제목 = 줄 절, 절 = 윗절, 노임, 장비} — 셈 밖 ·
|
|
매개값 없는 줄 뺌 · 장비 = 시간 50 아래 · 노임 · 장비가 하나도 없는 몫은 뺌."""
|
|
out: dict[str, dict[str, Any]] = {}
|
|
for one in units:
|
|
q, kind = one.get("품"), one.get("묶음")
|
|
if one.get("밖") or not q or kind not in ("L", "X"):
|
|
continue
|
|
title = str(one.get("절") or "")
|
|
part = out.setdefault(title, _part(title, str(one.get("윗절") or title)))
|
|
if kind == "L" and (who := one.get("직종") or trade(one.get("이름"))):
|
|
part["노임"][who] = part["노임"].get(who, 0) + float(q)
|
|
elif kind == "X" and q < 50:
|
|
k = eq_key(f"{one.get('이름') or ''} {one.get('규격') or ''}") or f"?{one.get('코드')}"
|
|
part["장비"][k] = part["장비"].get(k, 0) + float(q)
|
|
return [p for p in out.values() if p["노임"] or p["장비"]]
|