Files
Aislo/resources/tester/test_b08_backfill_range.py
T
eomsangdonandClaude Opus 5 d7cb14f416 test(B08): tmp/tests 중 tester 에 없던 47 개를 resources/tester 로 옮김
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>
2026-09-09 17:15:57 +09:00

170 lines
8.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""막자갈(뒤채움 조약돌) — **품셈이 정한 두께 범위 안에 드는가** (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)