Merge remote-tracking branch 'origin/main_laptop_1' into main_desktop_1
This commit is contained in:
@@ -36,7 +36,7 @@ from decimal import Decimal
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from B09_Estimation.B09_Estimation_MachineCost import load_machine_catalog
|
from B09_Estimation.B09_Estimation_MachineCost import load_machine_catalog
|
||||||
from B09_Estimation.B09_Estimation_ResourceAxis import RANGE_DASHES
|
from B09_Estimation.B09_Estimation_ResourceAxis import RANGE_DASH_CLASS
|
||||||
|
|
||||||
_ZERO = Decimal(0)
|
_ZERO = Decimal(0)
|
||||||
_SECONDS_PER_HOUR = Decimal(3600)
|
_SECONDS_PER_HOUR = Decimal(3600)
|
||||||
@@ -65,7 +65,7 @@ _RE_PARENS = re.compile(r"[((]([^))]*)[))]")
|
|||||||
_RE_NUMBER = re.compile(r"-?\d+(?:\.\d+)?")
|
_RE_NUMBER = re.compile(r"-?\d+(?:\.\d+)?")
|
||||||
_RE_FRACTION = re.compile(r"^(\d+(?:\.\d+)?)\s*/\s*(\d+(?:\.\d+)?)$")
|
_RE_FRACTION = re.compile(r"^(\d+(?:\.\d+)?)\s*/\s*(\d+(?:\.\d+)?)$")
|
||||||
#: 범위 표기 — 「0.55∼0.45」·「0.2~0.8」. **확정값이 아니다.**
|
#: 범위 표기 — 「0.55∼0.45」·「0.2~0.8」. **확정값이 아니다.**
|
||||||
_RE_RANGE = re.compile(rf"\d+(?:\.\d+)?\s*[{RANGE_DASHES}]\s*\d+(?:\.\d+)?")
|
_RE_RANGE = re.compile(rf"\d+(?:\.\d+)?\s*[{RANGE_DASH_CLASS}]\s*\d+(?:\.\d+)?")
|
||||||
|
|
||||||
|
|
||||||
class ProductivityError(ValueError):
|
class ProductivityError(ValueError):
|
||||||
|
|||||||
@@ -151,7 +151,17 @@ class ResourceCatalog:
|
|||||||
#: 갈래 키 정규화(`B09_Estimation_UnitPrice.normalize_variant_key`)도 이 목록을 쓴다.
|
#: 갈래 키 정규화(`B09_Estimation_UnitPrice.normalize_variant_key`)도 이 목록을 쓴다.
|
||||||
RANGE_DASHES = "∼~〜~-–‐"
|
RANGE_DASHES = "∼~〜~-–‐"
|
||||||
|
|
||||||
_RE_RANGE_CELL = re.compile(rf"^\d+(?:\.\d+)?\s*[{RANGE_DASHES}]\s*\d+(?:\.\d+)?$")
|
#: ⚠ **문자클래스에 그대로 넣지 말 것** — `~-–` 이 **범위 연산자**로 읽혀 거의 모든
|
||||||
|
#: 글자가 걸린다(2026-09-08 실측: 「0.7㎥」·「15톤」이 구간으로 잡혔음). 반드시 이 쪽을 쓴다.
|
||||||
|
RANGE_DASH_CLASS = "".join(re.escape(ch) for ch in RANGE_DASHES)
|
||||||
|
|
||||||
|
#: 구간 셀에는 **단위 꼬리**가 붙기도 한다 — 「51~100m」·「12~14㎝」(2026-09-08 실측 39줄).
|
||||||
|
#: ⚠ **단위가 붙었다고 다 구간이 아니다** — 「굴착기 0.7㎥」는 규격이고 자원 이름의 일부다.
|
||||||
|
#: 그래서 **수 ~ 수 + 단위**라는 모양 전체가 맞을 때만 구간으로 본다(앞에 이름이 없어야 한다).
|
||||||
|
_RANGE_UNITS = "a-zA-Z㎝㎜㎥㎡㎞mm톤"
|
||||||
|
_RE_RANGE_CELL = re.compile(
|
||||||
|
rf"^\d+(?:\.\d+)?\s*[{RANGE_DASH_CLASS}]\s*\d+(?:\.\d+)?\s*[{_RANGE_UNITS}]+$"
|
||||||
|
)
|
||||||
_RE_HANGUL = re.compile(r"[가-힣]")
|
_RE_HANGUL = re.compile(r"[가-힣]")
|
||||||
|
|
||||||
|
|
||||||
@@ -347,6 +357,15 @@ def match_table(
|
|||||||
result: AxisResult,
|
result: AxisResult,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""표 하나에 자원 축을 붙인다. 값이 안 서면 `unmatched` 로 보낸다."""
|
"""표 하나에 자원 축을 붙인다. 값이 안 서면 `unmatched` 로 보낸다."""
|
||||||
|
# ⚠ **예시 서식 표는 자원 표가 아니다.** 품셈이 「ha당 …단가산출서(예시)」처럼
|
||||||
|
# **빈 서식**을 실어 두는데(4-2 · 3-2 등), 그것을 읽으려 들면 구간 라벨·항목명이
|
||||||
|
# 자원 이름으로 오해돼 못 맞춘 목록이 못 쓰게 된다(2026-09-08 실측 39줄).
|
||||||
|
# 값이 있는데 안 서는 자리가 아니라 **애초에 값이 없는 표**다.
|
||||||
|
headers = " ".join(str(c) for c in (table.get("condition_note") or []))
|
||||||
|
if "단가산출서" in headers or "예시" in headers:
|
||||||
|
result.skipped_forms["example_form"] = result.skipped_forms.get("example_form", 0) + 1
|
||||||
|
return
|
||||||
|
|
||||||
from B09_Estimation.B09_Estimation_CrewOutput import match_crew_table
|
from B09_Estimation.B09_Estimation_CrewOutput import match_crew_table
|
||||||
|
|
||||||
# ⚠ **작업조 표는 형태 판정보다 먼저 가른다.** 「형틀목공 4인 / 시공량 35㎡」 표는
|
# ⚠ **작업조 표는 형태 판정보다 먼저 가른다.** 「형틀목공 4인 / 시공량 35㎡」 표는
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ from decimal import Decimal
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from B09_Estimation.B09_Estimation_ResourceAxis import (
|
from B09_Estimation.B09_Estimation_ResourceAxis import (
|
||||||
RANGE_DASHES,
|
RANGE_DASH_CLASS,
|
||||||
AxisResult,
|
AxisResult,
|
||||||
ResourceCatalog,
|
ResourceCatalog,
|
||||||
ResourceRow,
|
ResourceRow,
|
||||||
@@ -254,7 +254,7 @@ def _resolve_packed(catalog: ResourceCatalog, name: str, specs: list[str] | None
|
|||||||
_TRACK_PREFERENCE = ("무한궤도",)
|
_TRACK_PREFERENCE = ("무한궤도",)
|
||||||
|
|
||||||
|
|
||||||
_RE_SPEC_RANGE = re.compile(rf"^(\d+(?:\.\d+)?)[{RANGE_DASHES}](\d+(?:\.\d+)?)$")
|
_RE_SPEC_RANGE = re.compile(rf"^(\d+(?:\.\d+)?)[{RANGE_DASH_CLASS}](\d+(?:\.\d+)?)$")
|
||||||
|
|
||||||
|
|
||||||
def _spec_matches(catalog_spec: str, wanted: str) -> bool:
|
def _spec_matches(catalog_spec: str, wanted: str) -> bool:
|
||||||
|
|||||||
@@ -6293,9 +6293,10 @@
|
|||||||
"rows": 418,
|
"rows": 418,
|
||||||
"skipped_forms": {
|
"skipped_forms": {
|
||||||
"coefficient": 19,
|
"coefficient": 19,
|
||||||
|
"example_form": 8,
|
||||||
"reference": 56,
|
"reference": 56,
|
||||||
"undetermined": 75
|
"undetermined": 75
|
||||||
},
|
},
|
||||||
"unmatched": 882
|
"unmatched": 497
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user