- 집수정 □형 Ø800 — 관측 줄에 원문 치수(소광리 「집수정구조도(800)」 설계조건 칸·산출식)를 싣고 그 치수로 표 수량이 원문 식대로 다시 나오는지 시험 원문 값으로: 콘크리트 2.84 → 2.83752 · 합판거푸집 21.28 → 21.2843 · 철근 D13 4.78 → 4.776 · 면목 12.67 → 12.6728(터파기·되메우기·잔토 그대로) 그림: 긴 벽 정면(바닥기초·관·방수로·터파기) + 평면 · 관·방수로 자리는 원문 입체도 모식이라 적음 - 물넘이포장 — 슬래브 T(규격) · 와이어메쉬 2/3T(소광리 「포장」 그림) · 터파기 · 새 사유 「원문 둘이 다름: 소광리 포장 와이어매쉬 1.0·비닐 2㎡ ↔ 이 표(울진 1공구) 1.16·비닐 없음」을 표·그림이 같이 씀 - 날개벽 5종 — 원문 탭에 구조도 그림이 없고 날개 모양이 손으로 적은 수뿐이라 까닭 · 돌집수정 ㄷ·ㄴ형 — 집계표 관측값이라 치수 원문 없음 까닭 - 사유 문구(브레인 판정): 개거 150×200 「원문 둘이 다름(산출식 0.3×0.1 ↔ 그림 홈 150×200 + 밑 보 400×200)」 · 바닥막이 「옹벽은 버림·잡석까지 팜 — 바닥막이는 정본이 돌 두께만이라 다름」 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
114 lines
4.6 KiB
Python
114 lines
4.6 KiB
Python
"""구조물도 그림 — 집수정 · 날개벽 · 물넘이포장 (관측 원단위, 2026-09-14 · 표 = 그림).
|
||
|
||
⚠ 집수정 □형 Ø800 — 그림 치수(`section`)로 **표 수량이 원문 식 그대로** 다시 나와야 함.
|
||
원문 값으로 바꿈: 콘크리트 2.84 → 2.83752 · 합판거푸집 21.28 → 21.2843 ·
|
||
철근 4.78 → 4.776 · 면목 12.67 → 12.6728.
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import math
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
if str(ROOT) not in sys.path:
|
||
sys.path.insert(0, str(ROOT))
|
||
|
||
from B08_Quantity.B08_Quantity_Engine_ObservedUnit import load_observed_table # noqa: E402
|
||
from B08_Quantity.B08_Quantity_Engine_StructureFigure import attach_figures # noqa: E402
|
||
from B08_Quantity.B08_Quantity_Engine_StructureSheet import build_standard_sheets # noqa: E402
|
||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import build_table # noqa: E402
|
||
|
||
BASIN_SPEC = {
|
||
"inlet_basin_form": "□형(기본형)",
|
||
"inlet_basin_material": "콘크리트",
|
||
"pipe_diameter_mm": "800",
|
||
}
|
||
|
||
|
||
def _sheets(**options) -> list[dict]:
|
||
pipe = {
|
||
"structure_id": "p1",
|
||
"type_id": "pipe",
|
||
"start_m": 0.0,
|
||
"end_m": 0.0,
|
||
"options": {"pipe_kind": "흄관", **options},
|
||
}
|
||
payload = build_standard_sheets(build_table([pipe], None))
|
||
attach_figures(payload)
|
||
return payload["sheets"]
|
||
|
||
|
||
def _sheet(sheets: list[dict], type_id: str) -> dict:
|
||
return next(sheet for sheet in sheets if sheet["type_id"] == type_id)
|
||
|
||
|
||
def test_집수정_치수로_표_수량이_원문_식대로_다시_나온다() -> None:
|
||
entry = load_observed_table().find("pipe_inlet_basin", BASIN_SPEC)
|
||
s = entry["section"]
|
||
amounts = {item["name"]: item["amount"] for item in entry["components"]}
|
||
inner, wall, base = s["inner"], s["wall_m"], s["base_m"]
|
||
ol, ow, h = inner["length_m"] + 2 * wall, inner["width_m"] + 2 * wall, inner["height_m"]
|
||
il, iw = inner["length_m"], inner["width_m"]
|
||
sp = s["spillway"]
|
||
notch = (sp["top_m"] + sp["bottom_m"]) / 2 * sp["depth_m"]
|
||
hole = 3.14 * (s["pipe_d_m"] / 2) ** 2 # 원문이 3.14 로 셈
|
||
concrete = ol * ow * h - il * iw * h - sp["count"] * notch * wall - hole * wall + ol * ow * base
|
||
slant = math.hypot((sp["top_m"] - sp["bottom_m"]) / 2, sp["depth_m"])
|
||
form = (
|
||
(ol * h - hole)
|
||
+ (ol * h - notch)
|
||
+ (ow * h - notch) * 2
|
||
+ (il * h - hole)
|
||
+ (il * h - notch)
|
||
+ (iw * h - notch) * 2
|
||
+ (ol + ow) * base * 2
|
||
+ slant * wall * sp["count"] * 2
|
||
)
|
||
chamfer = ol + il * 2 + slant * sp["count"] + sp["bottom_m"] * sp["count"] + wall * 4
|
||
trench = (ol + s["dig"]["extra_length_m"]) * s["dig"]["width_m"] * (h + base)
|
||
backfill = trench - il * iw * (h + base)
|
||
assert abs(concrete - amounts["콘크리트"]) < 1e-9 # 2.83752
|
||
assert abs(form - amounts["합판거푸집"]) < 5e-5 # 21.28432
|
||
assert abs(chamfer - amounts["면목"]) < 5e-5 # 12.67279
|
||
assert abs(trench - amounts["터파기"]) < 1e-9
|
||
assert abs(backfill - amounts["되메우기"]) < 1e-9
|
||
assert abs(trench - backfill - amounts["잔토처리"]) < 1e-9
|
||
|
||
|
||
def test_집수정_그림이_서고_날개벽은_까닭() -> None:
|
||
sheets = _sheets(wing_wall_type="A-TYPE", **BASIN_SPEC)
|
||
basin = _sheet(sheets, "pipe_inlet_basin")
|
||
texts = [s["text"] for s in basin["figure"] if s["kind"] == "text"]
|
||
assert "안 3×1×1.2 · 벽 0.2 · 바닥기초 3.4×1.4×0.2 m" in texts
|
||
assert "터파기 3.8 × 2 × 깊이 1.4 m" in texts
|
||
wing = _sheet(sheets, "pipe_wing_wall")
|
||
assert (
|
||
wing["rows"] and wing["figure"] is None and "구조도 원본 확보 대기" in wing["figure_reason"]
|
||
)
|
||
|
||
|
||
def test_돌집수정은_치수_원문이_없어_까닭() -> None:
|
||
basin = _sheet(
|
||
_sheets(pipe_diameter_mm="800", inlet_basin_form="돌집수정 ㄷ형"), "pipe_inlet_basin"
|
||
)
|
||
assert basin["rows"] and basin["figure"] is None and "집계표 관측값" in basin["figure_reason"]
|
||
|
||
|
||
def test_물넘이포장_그림과_표에_원문_차이_사유가_같다() -> None:
|
||
structure = {
|
||
"structure_id": "f1",
|
||
"type_id": "ford_pavement",
|
||
"start_m": None,
|
||
"end_m": None,
|
||
"options": {"ford_width_m": 5, "length_m": 10, "thickness_cm": 20},
|
||
}
|
||
payload = build_standard_sheets(build_table([structure], None))
|
||
attach_figures(payload)
|
||
sheet = payload["sheets"][0]
|
||
texts = [s["text"] for s in sheet["figure"] if s["kind"] == "text"]
|
||
diff = [note for note in sheet["notes"] if "원문 둘이 다름" in note]
|
||
assert diff and diff[0] in texts
|
||
assert "와이어메쉬 — 밑에서 0.133 m (2/3T)" in texts
|