From 9f2e81babc5f911a3a4b9adc1b915f706ed8b613 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 9 Sep 2026 11:28:30 +0900 Subject: [PATCH] =?UTF-8?q?feat(B08):=20=EA=B0=9C=EA=B1=B0(=EA=B2=89?= =?UTF-8?q?=EB=8F=84=EB=9E=91)=20=EC=A0=84=EA=B0=9C=20=E2=80=94=20?= =?UTF-8?q?=EC=A0=95=EB=B3=B8=20=EB=91=90=20=ED=91=9C=EB=A5=BC=20m?= =?UTF-8?q?=EB=8B=B9=EC=9C=BC=EB=A1=9C=20(3=EB=8B=A8=EA=B3=84=20=EB=84=B7?= =?UTF-8?q?=EC=A7=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 소광리 정본 「개거(150-200) (2)」·「L형수로-(201)」 — **둘 다 m당**. ⚠⚠ **두 표가 담는 것이 다름.** 값이 비슷해 보여 합치고 싶어지는 자리라 못 박음: ``` 콘크리트 개거 150×200 터파기 · 유로폼 · 면목 **세 줄뿐** — **콘크리트 본체 줄이 없음** 콘크리트 L형수로 H=0.2 터파기 · 되메우기 · 잔토 · **콘크리트** · PVC Φ50 · 이형철근 D13 · 거푸집 · 면목 **여덟 줄** ⓘ 같은 것 — 둘 다 m당이고 거푸집 계열(유로폼·거푸집)과 면목이 있음 ``` ⚠ 개거에 콘크리트가 없는 것은 **빠뜨린 것이 아니라 원문 그대로**임. 0 으로 때우거나 L형수로 값을 옮겨 채우지 않음 — 돌붙임(메)에서 세 줄을 안 만든 그 판단과 같음. ⚠ **PVC Φ50 은 줄만 있고 수량 칸이 빔** — 안 세우고 그 사실을 줄로 냄. ⚠ 규격이 **붙박이**(「콘크리트 개거 150×200」) — `open_ditch` 등록부에 **옵션이 하나도 없음**. `ditch_spec` 을 주면 L형수로로 갈림. 칸이 생기면 열면 됨. **측구(`ditch_side`)는 안 건드림** — `design_owner: 횡단 설계` 라 B06 소관이고 `enabled: False`. 정본 「측구수로400/500」은 **「터파기 계산서」**라 터파기·잔토·되메우기 셋뿐임(본체 없음) — 그쪽이 쓸 때를 위해 적어 둠. 실전개 (연장 10m) 개거 터파기 0.3㎥ · 유로폼 5.5㎡ · 면목 20m L형수로 터파기 3.1645 · 되메우기 1.2997 · 잔토 1.8647 · 콘크리트 1.508 · 이형철근 3.98㎏ · 거푸집 7.38㎡ · 면목 10m 자체검증 — 새 시험 5건(정본 값 대조 · 개거에 콘크리트가 없는지 · 잔토 = 터파기−되메우기 · 빈 수량 줄 · 없는 규격), 회귀 596 통과 · 0 실패. Co-Authored-By: Claude Opus 5 (1M context) --- .../B08_Quantity_Engine_UnitQuantity.py | 9 +++ ..._Quantity_Engine_UnitQuantity_Revetment.py | 81 +++++++++++++++++++ 2 files changed, 90 insertions(+) diff --git a/B08_Quantity/B08_Quantity_Engine_UnitQuantity.py b/B08_Quantity/B08_Quantity_Engine_UnitQuantity.py index 6ce09aa9..d3932054 100644 --- a/B08_Quantity/B08_Quantity_Engine_UnitQuantity.py +++ b/B08_Quantity/B08_Quantity_Engine_UnitQuantity.py @@ -942,6 +942,8 @@ EXPANDERS = { "revetment": lambda h, l, o, f=None, r="": _revetment()(h, l, o, f, r), # 골막이·바닥막이는 돌 계열이나 **돌쌓기 식을 그대로 못 쓴다** — 까닭은 그 모듈에 적었다. "erosion_check": lambda h, l, o, f=None, r="": _stone_kin()("erosion_check"), + # 개거는 **m당** 원단위라 연장이 밑수다(정본 「개거(150-200)」·「L형수로-(201)」). + "open_ditch": lambda h, l, o, f=None, r="": _open_ditch()(l, o), # 바닥막이는 **돌붙임 ㎡당**이라 높이·연장이 아니라 **면적**이 밑수다(정본 「돌붙임L3=…」). "bed_sill": lambda h, l, o, f=None, r="": _bed_sill()(_num(o.get("area_m2"), 0.0), o), # ⚠⚠ **큰돌쌓기(`boulder_masonry`)를 여기에 두지 않는다** (2026-09-07 발견). @@ -954,6 +956,13 @@ EXPANDERS = { } +def _open_ditch(): + """개거 전개 함수를 늦게 가져온다.""" + from B08_Quantity.B08_Quantity_Engine_UnitQuantity_Revetment import open_ditch + + return open_ditch + + def _bed_sill(): """바닥막이 전개 함수를 늦게 가져온다.""" from B08_Quantity.B08_Quantity_Engine_UnitQuantity_Revetment import bed_sill diff --git a/B08_Quantity/B08_Quantity_Engine_UnitQuantity_Revetment.py b/B08_Quantity/B08_Quantity_Engine_UnitQuantity_Revetment.py index 8af1bf40..cd425949 100644 --- a/B08_Quantity/B08_Quantity_Engine_UnitQuantity_Revetment.py +++ b/B08_Quantity/B08_Quantity_Engine_UnitQuantity_Revetment.py @@ -153,6 +153,87 @@ def stone_kin_withheld(type_id: str) -> tuple[list[Component], list[str]]: return [], [why] if why else [] +#: 개거(겉도랑) 원단위 — 소광리 정본 「개거(150-200) (2)」·「L형수로-(201)」, **둘 다 m당**. +#: ⚠⚠ **두 표가 담는 것이 다르다.** 값이 비슷해 보여 합치고 싶어지는 자리다: +#: +#: 콘크리트 개거 150×200 터파기 · 유로폼 · 면목 **세 줄뿐** — **콘크리트 본체 줄이 없다** +#: 콘크리트 L형수로 H=0.2 터파기 · 되메우기 · 잔토 · **콘크리트** · PVC Φ50 · 이형철근 D13 · +#: 거푸집 · 면목 **여덟 줄** +#: +#: ⓘ 같은 것 — **둘 다 m당**이고 거푸집 계열(유로폼·거푸집)과 면목이 있다. +#: ⚠ 개거 표에 콘크리트가 없는 것은 **빠뜨린 것이 아니라 원문 그대로**다. 0 으로 때우거나 +#: L형수로 값을 옮겨 채우지 않는다(2026-09-09 판단 — 돌붙임(메)에서 세 줄을 안 만든 그 자리). +#: +#: ⚠ **규격이 붙박이다** — 정본에 「150×200」 하나뿐이고 `open_ditch` 등록부에 **옵션이 하나도 +#: 없다**(규격 칸 없음). 칸이 생기면 이 표를 열면 된다. +OPEN_DITCH_FORMS: dict[str, dict[str, Any]] = { + "콘크리트 개거 150×200": { + "rows": ( + ("터파기", "㎥", 0.3 * 0.1 * 1.0, "0.3 × 0.1 × 1"), + ("유로폼", "㎡", (0.2 + 0.2 + 0.15) * 1.0, "(0.2 + 0.2 + 0.15) × 1"), + ("면목", "m", 2.0 * 1.0, "2 × 1"), + ), + }, + "콘크리트 L형수로 H=0.2": { + "rows": ( + ("터파기", "㎥", 0.31645, "[{(1.11+1.51)÷2×0.2} + {(0.33×0.33)÷2}] × 1.0"), + ("되메우기", "㎥", 0.129975, "(0.2+0.30)÷2×0.25×1 + (0.2+0.19)÷2×0.33×1.0"), + ("잔토처리", "㎥", 0.186475, "터파기 − 되메우기"), + ( + "콘크리트", + "㎥", + 0.1508, + "{(0.2+0.15)÷2×0.7} + (0.21×0.13)×1 + {(0.15+0.21)÷2×0.20}×1", + ), + ("이형철근 D13", "kg", 0.398, "0.2 × 2 × 0.995"), + ("거푸집", "㎡", 0.738, "0.2 + 0.33 + √(0.2² + 0.06²)"), + ("면목", "m", 1.0, "1"), + ), + # ⚠ 정본에 줄은 있으나 **수량 칸이 비어 있다**(PVC Φ50). 0 으로 만들지 않고 알린다. + "blank_rows": (("PVC 파이프 Φ50㎜", "m"),), + }, +} + + +def open_ditch(length_m: float, options: dict[str, Any]) -> tuple[list[Component], list[str]]: + """개거(겉도랑) 전개 — **m당** 원단위를 연장에 곱한다(소광리 정본 두 탭). + + ⚠ 규격을 고를 칸이 없어 지금은 **「콘크리트 개거 150×200」 붙박이**다. 그 사실을 줄로 낸다. + """ + from B08_Quantity.B08_Quantity_Engine_UnitQuantity import DESTINATION + + if length_m <= 0: + return [], ["연장이 없어 전개하지 않음"] + spec = str(options.get("ditch_spec") or "콘크리트 개거 150×200").strip() + table = OPEN_DITCH_FORMS.get(spec) + if table is None: + return [], [ + f"개거 규격 「{spec}」 원단위가 없습니다 — 있는 것: {' · '.join(OPEN_DITCH_FORMS)}" + ] + + components = [ + Component( + name, + unit, + per_m * length_m, + DESTINATION.get(name, "quantity"), + f"{basis} × 연장 {length_m:g}m (m당 {per_m:g})", + ) + for name, unit, per_m, basis in table["rows"] + ] + notes: list[str] = [] + if "ditch_spec" not in options: + notes.append(f"규격이 「{spec}」 붙박이입니다 — 개거 제원에 규격 칸이 없습니다") + if spec == "콘크리트 개거 150×200": + notes.append( + "⚠ 이 표에는 **콘크리트 본체 줄이 없습니다** — 정본 원문 그대로입니다" + "(터파기·유로폼·면목 세 줄뿐). 지어내지 않았습니다" + ) + for name, unit in table.get("blank_rows", ()): + notes.append(f"{name}({unit}) 은 정본에 줄은 있으나 **수량이 비어 있어** 안 세웠습니다") + return components, notes + + def bed_sill(area_m2: float, options: dict[str, Any]) -> tuple[list[Component], list[str]]: """바닥막이 전개 — **돌붙임 ㎡당** 원단위를 면적에 곱한다(소광리 정본 두 탭).