feat(712-2): 단위 한 벌 master_unit — 별칭 · 개수 묶음 · 결과단위 배 읽기 · 같은 성격 환산 · 근거 글

- 별칭(master_material) · 같은 성격 환산(master_pick) · 결과단위 배 읽기 셋(Store_Combo · Hopyo_Ours · master_basis) · 보이는 꼴 별칭(master_basis) 갈아 끼움 · 엑셀 맞춤(Hopyo_Match)은 master_pick 이름 그대로 이음
- 개수 묶음(개 · EA · 본 · 매) 1:1 — 본 ↔ 개 단위경고 4 줄 사라짐 · 값 같음
- 부피 ↔ 무게 = 단위중량 표 CC000337 고른 줄 받을 때만(기본 줄 없음) · 밀도 · ㎾h 경고 글만
- B08 /1000 · /40 손 식 = 실무 엑셀 G열 식이라 그대로(시험이 같은 값 대조)
- 지킴 시험 test_712_2_unit

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 16:03:54 +09:00
co-authored by Claude Opus 5.5
parent 6d5b78f83e
commit 881c204ca8
7 changed files with 195 additions and 49 deletions
+1 -30
View File
@@ -9,18 +9,10 @@ from __future__ import annotations
from contextlib import contextmanager
from contextvars import ContextVar
from decimal import Decimal
import master_material as mm
from master_unit import UNITS, convert, kind_of, same_kind # noqa: F401 — 단위 한 벌(712-2)
# 「같은 성격」 단위 — {성격: {정규 단위: 기준 단위 몇 배}} (키는 `plain_unit` 을 거친 꼴)
UNITS = {
"무게": {"g": 1, "kg": 1000, "톤": 1000000},
"길이": {"mm": 1, "cm": 10, "m": 1000, "km": 1000000},
"넓이": {"cm2": 1, "m2": 10000},
"부피": {"cm3": 1, "ℓ": 1000, "m3": 1000000},
}
_SCALE = {u: (kind, n) for kind, group in UNITS.items() for u, n in group.items()}
REGIONS = (
"전국평균 전국 서울 경기 강원 충북 충남 전북 전남 경북 경남 부산 대구 인천 대전 울산 세종 제주 광주"
" 전남광주"
@@ -60,27 +52,6 @@ def machine(spec: dict, value) -> bool:
return bool(picks) and str(value).strip() in known and all(str(o) in known for o in picks)
# ── 단위 ───────────────────────────────────────────────────────────────
def kind_of(unit) -> str | None:
got = _SCALE.get(mm.plain_unit(unit))
return got[0] if got else None
def same_kind(a, b) -> bool:
"""단위가 같거나 같은 성격(무게 · 길이 · 넓이 · 부피)."""
pa, pb = mm.plain_unit(a), mm.plain_unit(b)
return pa == pb or (kind_of(a) is not None and kind_of(a) == kind_of(b))
def convert(price, have, want):
"""`have` 단위 단가 → `want` 단위 단가 — 같은 성격이 아니면 그대로."""
if price is None or not want or mm.plain_unit(have) == mm.plain_unit(want):
return price
if not same_kind(have, want) or kind_of(have) is None:
return price
return price * Decimal(_SCALE[mm.plain_unit(want)][1]) / Decimal(_SCALE[mm.plain_unit(have)][1])
# ── 찾기 ───────────────────────────────────────────────────────────────
def _words(term) -> tuple[list[str], list[str]]:
"""(이름·규격에 든 낱말, 지역 낱말) — 지역 낱말은 고르는 차례에만 쓰임."""