- 지움(git rm) 10 파일 3,374 줄: M02_Hopyo_Finger · Ours · Option · Fit · Combine · Verdict · Line · SkLink · SkPatch · Basis
- Match: 흐름 몫(candidates · name_cands · fix_typo · clause · b_order · _logic_specs · _line_mod · units_of · _state · view · guess · picks · chain) 지움 · 이름 도구 몫 · line_key 남김
- Words: conds · cond_score · close · cosine · jacc 지움 / Shares: sections 지움(trade · eq_key 남김)
- 옮김: Finger.kind_of → Fixed.kind_of · SkLink(sk_line · kept · left · LEFT · WHY) → Sangeun · SkPatch 기계 몫(MACH_IN · MACHINE · SOLO · _mach_logics) → Units.mach_logics
- Sangeun: 옛 /sangeun 몸(build · _sure · Maker.basis · judge · plan · make) 지움 · Kids: first · proposal · order 지움 · Build: build() · unlinked() 지움(모두 고정 Builder · build_all · _order · _origins 남김)
- Router: 옛 길 지움(GET hopyo/{키}/{번} · guess · hopyo-picks · hopyo-build · hopyo-unlinked · hopyo/{키}/sangeun) · GET hopyo/{키} = Judge.view(1차 줄 판정 줄상태 · 만든 · 블록 풀이 셈)
- Marks: 칠 = Judge.judged 만 · Forget: 맞춤 캐시 지움 줄 걷음 · Ledger: Ours.version 판 칸 걷음 · Item: Kids.first 걷음
- Row(덧): 단산 줄 = 장부 짝이 있어도 늘 「2차 필요」(장부 = 1차 후보 힌트만)
시험 정리(까닭 = 지운 길 · 모듈만 시험함):
- 지움 11 파일: test_m02_hopyo_finger · fit · golden · option · ours · basis · seam · flow · draft_calc · test_635 · test_628(지문 · 순위 · 옵션 거꾸로 · 맡은 절 · 옛 확인 흐름)
- 함수 지움: /sangeun · /hopyo-build · /hopyo-unlinked · hopyo-picks · 옛 줄 맞춤 보기를 부르던 것(572 · 718_1 · 729 · 739_1 · 777_1 · 778_5 · 780_1 · labor_national · 705_3 · m02_hopyo_match · 746_1)
- test_621 S2(지문 해시) 지움 · S1 남김 · test_m02_hopyo_build = 장부 길 시험만(PUT 으로 심음)
- 새 길로: 779_2(줄상태 = 1차 판정 · 칠 셈 전 None) · grid · stmate(hopyo-judge 줄 판) · 778_1 · 778_2(Units.mach_logics) · 642_6(Marks 원문) · 642_3 장부 짝 단산 줄 2차 지킴
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
61 lines
2.4 KiB
Python
61 lines
2.4 KiB
Python
"""712-1 지킴 — 인력 · 재료 · 경비 묶음 셈 때 파생 · 기계경비 판별 한 곳(`master_bundle`)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from decimal import Decimal
|
|
from pathlib import Path
|
|
|
|
ROOT = Path(__file__).resolve().parents[2]
|
|
sys.path.insert(0, str(ROOT / "resources/master_data/scripts"))
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
import check_master as cm # noqa: E402
|
|
import master_auto as mau # noqa: E402
|
|
import master_bundle as mb # noqa: E402
|
|
import master_formula as mf # noqa: E402
|
|
|
|
FILES = cm.load()
|
|
MASTER = mf.Master(FILES)
|
|
LOGICS = {r["키"]: r for d in FILES.values() if d.get("그룹") == "로직" for r in d.get("줄") or []}
|
|
|
|
|
|
def test_every_line_bundled():
|
|
"""호표 · 덧줄 전수 — 하위(못 가름) ≤ 31 · 나머지는 인력 · 재료 · 경비 · 기계경비 줄 = 경비."""
|
|
count = dict.fromkeys(mb.BUNDLES, 0)
|
|
machine = 0
|
|
for row in LOGICS.values():
|
|
for item in [*row.get("호표", []), *row.get("덧줄", [])]:
|
|
name, is_mach = mb.bundle(MASTER, item)
|
|
count[name] += 1
|
|
machine += is_mach
|
|
if is_mach:
|
|
assert name == "경비"
|
|
assert sum(count.values()) > 5_000
|
|
assert count["하위"] <= 31, count
|
|
assert machine >= 1_000, machine
|
|
|
|
|
|
def test_machine_rule_one_place():
|
|
"""기계경비 = 결과단위 원/시간 돈 로직 — 작업량(㎥/시간) · 이름 「시간당」 은 아님."""
|
|
machines = {k for k, r in LOGICS.items() if mb.is_machine(r)}
|
|
assert {"GC000267", "GC000268", "GF000145"} <= machines
|
|
assert not machines & {"GF000102", "GC000422", "GC000260"} # 작업량 · ㎡/시간 · 원/㎡
|
|
|
|
|
|
def test_run_lines_tagged():
|
|
"""엔진 `run` 줄마다 `묶음` · 기계경비 줄은 `장비` + 비목 노 · 재 · 경 세 몫."""
|
|
seen = set()
|
|
for key in ("GF000169", "GF000103"):
|
|
row = LOGICS[key]
|
|
given = {k: v for k, v in mau.values(MASTER, row).items() if v is not None}
|
|
got = mf.run(MASTER, key, given)
|
|
for line in got["줄"]:
|
|
assert line["묶음"] in mb.BUNDLES
|
|
seen.add(line["묶음"])
|
|
if line.get("장비"):
|
|
assert set(line["비목"]) == set(mf.COST_ITEMS)
|
|
total = sum((line["비목"].get(k) or Decimal(0)) for line in got["줄"] for k in line["비목"])
|
|
assert abs(total - got["계"]) < 1
|
|
assert {"인력", "재료", "하위"} <= seen
|