tmp/ 가 창끼리 안 건너가는 것이 확정돼(랩탑이 시간 두고 두 번 확인) 시험·예외가 저절로 건너가도록 git 안으로 옮김. 사용자 확정. - 내용은 하나도 안 고침 — 자리만 옮김. tmp/tests 는 남겨 둠. - 같은 이름이 이미 있던 64 개는 랩탑 것을 그대로 두고 건너뜀. - helper_b05_*.js 둘은 랩탑이 .cjs 로 이미 올린 것과 **줄바꿈만 다른 같은 내용**이라 복사본을 도로 뺌(시험이 .cjs 를 부름). - resources/tester/ 에서 전체 1176 통과 · 29 건너뜀 · 실패 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
170 lines
8.7 KiB
Python
170 lines
8.7 KiB
Python
"""막자갈(뒤채움 조약돌) — **품셈이 정한 두께 범위 안에 드는가** (2026-09-09).
|
||
|
||
⚠⚠ **이 시험은 「같은지」가 아니라 「범위 안인지」를 잰다.** 우리 막자갈은 품셈과 **다른 식**이다.
|
||
품셈 13-4-4 [주]⑨ 는 뒤채움 조약돌 두께를 **직고별 범위**로만 준다(상부 20~40㎝ ·
|
||
하부 직고별 30~140㎝). 두 길이 **같은 자리에 도착하는지**를 본다.
|
||
⚠⚠ **2026-09-09 오후 식이 갈아탔다** — 랩탑 보조가 확정 5차 작은 것 3 으로 막자갈을
|
||
「입적 − 몸통 − 고임돌」에서 **뒷채움 사다리꼴**로 바꿨다(정본 여섯 탭 상 0.30 · 하 0.45).
|
||
그래서 아래 기록을 전부 다시 쟀다 — **옛 값(0.278~0.943)은 지금 값이 아니다.**
|
||
⚠ **등호로 바꾸지 말 것** — 등호로 두면 우리 식이 품셈 식에 끌려간다. 우리 식은 우리 식이다.
|
||
⚠ **범위 밖으로 나가면 「틀림」이 아니라 「봐야 함」이다** — 우리 식이 맞을 수도 있다.
|
||
다만 **두께식이 바뀌면 조용히 새 나갈 자리**라(값은 계속 나오므로 아무도 못 본다)
|
||
그 자리에 이 그물을 둔다.
|
||
|
||
⚠ **이 시험이 잰 범위는 직고 1.0~7.5 m · 뒷길이 35~75㎝ 다.**
|
||
**검산은 「어디까지 쟀는지」를 함께 적지 않으면 다음 사람이 착시를 본다** — 앞서 4.0 까지만
|
||
재고 「다 범위 안」이라 한 적이 있다(그때 식으로는 4.5 부터 밖이었다).
|
||
⚠ **큰돌쌓기(13-6)는 이 시험의 대상이 아니다** — 두께를 **직경 위 끝**으로 보고(`BOULDER_MASONRY`)
|
||
막자갈도 안 낸다. 그래서 높이 한계가 없어도 이 자리에 안 걸린다(2026-09-09 실측 확인).
|
||
|
||
품셈 13-4-4 [주]⑨ <성토의 경우 뒤채움 조약돌의 두께>
|
||
직고 ∼1.5m 상부 20~40 · 하부 30~60 ⇒ 평균 0.25~0.50 m
|
||
직고 ∼3.0m 상부 20~40 · 하부 45~75 ⇒ 평균 0.33~0.58 m
|
||
직고 ∼5.0m 상부 20~40 · 하부 60~100 ⇒ 평균 0.40~0.70 m
|
||
직고 ∼7.0m 상부 20~40 · 하부 80~140 ⇒ 평균 0.50~0.90 m
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
ROOT = Path(__file__).resolve().parents[2]
|
||
sys.path.insert(0, str(ROOT))
|
||
|
||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import stone_masonry # noqa: E402
|
||
|
||
#: (직고 상한, 평균두께 범위) — 원문 상·하부 범위의 평균이다.
|
||
PUMSEM_RANGE_M: tuple[tuple[float, float, float], ...] = (
|
||
(1.5, 0.25, 0.50),
|
||
(3.0, 0.33, 0.58),
|
||
(5.0, 0.40, 0.70),
|
||
(7.0, 0.50, 0.90),
|
||
)
|
||
|
||
|
||
def 범위(height_m: float) -> tuple[float, float]:
|
||
for limit, low, high in PUMSEM_RANGE_M:
|
||
if height_m <= limit:
|
||
return low, high
|
||
return PUMSEM_RANGE_M[-1][1], PUMSEM_RANGE_M[-1][2]
|
||
|
||
|
||
def 두께(height_m: float, back_cm: int) -> float:
|
||
"""우리 막자갈을 **면적으로 나눈 값** — 품셈이 말하는 「뒤채움 두께」와 같은 축."""
|
||
components, _ = stone_masonry(
|
||
height_m,
|
||
10.0,
|
||
{"height_m": height_m, "length_m": 10.0, "back_len_cm": back_cm},
|
||
wet=True,
|
||
face="성토",
|
||
)
|
||
got = {c.name: c.amount for c in components}
|
||
return got["막자갈"] / got["돌쌓기"]
|
||
|
||
|
||
def test_3m_까지는_품셈_범위_안에_든다() -> None:
|
||
"""⚠ 실패하면 「틀렸다」가 아니라 **「봐야 한다」**는 뜻이다 — 두께식이 바뀐 자리를 알리는 그물.
|
||
|
||
⚠ **3.0m 까지인 것이 우연이 아니다** — 정본 여섯 탭을 전수 확인한 구간이 **H=1.0~3.0**
|
||
이다(`STONE_BACKFILL_WIDTH_M` 머리 주석). 근거가 있는 구간에서는 품셈 범위와 맞고,
|
||
근거가 없는 구간에서 갈린다.
|
||
"""
|
||
for height, back in ((1.0, 45), (1.2, 35), (2.5, 45), (3.0, 45), (3.0, 55), (3.0, 75)):
|
||
low, high = 범위(height)
|
||
got = 두께(height, back)
|
||
assert low <= got <= high, (
|
||
f"H={height} ℓ3={back}㎝ 뒤채움 두께 {got:.3f}m 가 품셈 13-4-4 [주]⑨ 범위"
|
||
f" {low}~{high}m 밖 — 우리 식이 맞을 수도 있으니 **틀림이 아니라 봐야 함**"
|
||
)
|
||
|
||
|
||
def test_3m_를_넘으면_범위_아래로_나간다() -> None:
|
||
"""⚠⚠ **지금 상태를 기록해 두는 시험이다**(2026-09-09 오후 실측).
|
||
|
||
⚠ **방향이 뒤집혔다** — 옛 식은 높은 벽에서 품셈 범위 **위**로 나갔는데, 새 식은
|
||
**아래**로 나간다. 새 식은 두께가 H 에 안 붙기 때문이다.
|
||
H 1.0 0.364 · 1.5 0.364 (안) · 2.0~3.0 0.359 (안)
|
||
H 3.5~5.0 0.354 · 6.0~7.0 0.348 · 7.5 0.342 (전부 **밖 — 아래**)
|
||
까닭은 새 막자갈이 **(상 0.30 + 하 0.45) ÷ 2 × H × 연장** 이라 두께(= 막자갈 ÷ 비탈면적)가
|
||
**0.375 ÷ √(1+경사²)** 로 거의 붙박이인 데 있다. 직고가 커지면 표준경사가 커져
|
||
비탈면적만 늘어 **오히려 조금씩 얇아진다.** 품셈 표는 반대로 직고와 함께 두꺼워진다.
|
||
⚠ **틀렸다고 단정하지 않는다** — 정본 여섯 탭이 근거이고 품셈 표는 **범위**다. 다만
|
||
정본 전수 확인 구간이 **H=1.0~3.0** 이고 갈리는 자리도 **3.0m 부터**라 겹친다 —
|
||
**높은 벽의 정본 근거가 없다**는 뜻이므로 확정 5차 작은 것 3 을 다시 볼 때 이 자리를 볼 것.
|
||
⚠ 이 시험이 깨지면(범위 안으로 들어오면) **두께식이 바뀐 것**이니 위 기록을 고칠 것.
|
||
"""
|
||
안쪽 = 두께(3.0, 45)
|
||
바깥 = 두께(3.5, 45)
|
||
assert 범위(3.0)[0] <= 안쪽 <= 범위(3.0)[1]
|
||
assert 바깥 < 범위(3.5)[0]
|
||
assert 0.35 < 바깥 < 0.36
|
||
|
||
|
||
def test_직고가_커져도_두께가_거의_안_움직인다() -> None:
|
||
"""⚠ **뒤집힌 시험이다** — 종전에는 「직고가 커지면 두꺼워진다」였다(품셈 표와 같은 방향).
|
||
|
||
새 식에서는 막자갈 **물량**이 H 에 비례해 늘지만 **두께**(물량 ÷ 비탈면적)는 거의
|
||
붙박이다. 이 사실 자체를 못 박아, 나중에 누가 「두께가 직고를 따라간다」고 잘못
|
||
읽는 것을 막는다.
|
||
"""
|
||
thicknesses = [두께(h, 45) for h in (1.2, 2.5, 4.0, 6.0)]
|
||
assert max(thicknesses) - min(thicknesses) < 0.02
|
||
# ⚠ 물량 자체는 직고를 따라 는다 — 두께가 안 움직인다고 물량까지 굳은 것이 아니다.
|
||
부피 = [두께(h, 45) * h for h in (1.2, 2.5, 4.0, 6.0)]
|
||
assert 부피 == sorted(부피)
|
||
|
||
|
||
def test_뒷길이는_두께를_안_움직인다() -> None:
|
||
"""⚠ 옛 식에서는 뒷길이가 밑수였다 — 지금은 정본 폭 붙박이라 아예 안 본다."""
|
||
assert len({round(두께(2.5, b), 6) for b in (35, 45, 55, 60, 75)}) == 1
|
||
|
||
|
||
def test_등호가_아니라_범위다() -> None:
|
||
"""⚠ 이 시험의 뜻을 못 박는다 — 품셈 값과 **같지 않아도 된다**.
|
||
|
||
같아지길 요구하면 우리 식(정본 뒷채움 사다리꼴)이 품셈 식에 끌려간다.
|
||
"""
|
||
low, high = 범위(2.5)
|
||
got = 두께(2.5, 45)
|
||
assert got != low and got != high # 경계값과 같을 이유가 없다
|
||
assert low < got < high
|
||
|
||
|
||
def test_근거_구간_밖이면_사유가_뜬다() -> None:
|
||
"""⚠ **값은 계속 나온다** — 사유가 없으면 아무도 못 본다.
|
||
|
||
교본 7-3 이 「찰 3.0m 이하 · 메 2.0m 이하」로 두지만 **코드가 높이를 막지 않고**,
|
||
표준경사표(13-4-4 [주]⑪)는 직고 7m 까지 칸을 준다 — 높은 벽이 실제로 설 수 있다.
|
||
막지도 눅이지도 않고 **정본 확인 구간 밖이라는 사실**만 사유로 낸다(임의 확정 금지).
|
||
"""
|
||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import stone_masonry
|
||
|
||
def 사유(height_m: float) -> list[str]:
|
||
_, notes = stone_masonry(
|
||
height_m,
|
||
10.0,
|
||
{"height_m": height_m, "length_m": 10.0, "back_len_cm": 45},
|
||
wet=True,
|
||
face="성토",
|
||
)
|
||
return [n for n in notes if "정본 확인 구간" in n]
|
||
|
||
assert 사유(3.0) == [] # 근거가 있는 구간에서는 잔소리하지 않는다
|
||
밖 = 사유(3.5)
|
||
assert len(밖) == 1
|
||
assert "13-4-4 [주]⑨" in 밖[0] and "실무자 확인" in 밖[0]
|
||
|
||
|
||
def test_큰돌쌓기는_이_식을_안_쓴다() -> None:
|
||
"""⚠ 높이 한계가 없는 것은 큰돌쌓기뿐이라 **거기까지 번지면 살아 있는 자리**가 된다.
|
||
|
||
큰돌쌓기(13-6)는 막자갈 줄 자체를 안 낸다 — 이 갈림이 거기로 안 번진다.
|
||
"""
|
||
from B08_Quantity.B08_Quantity_Engine_UnitQuantity import boulder_masonry
|
||
|
||
components, _ = boulder_masonry(
|
||
5.0, 10.0, {"height_m": 5.0, "length_m": 10.0, "stone_cm": "60~80"}
|
||
)
|
||
assert not any(c.name == "막자갈" for c in components)
|