품셈 8-1-7 5호 「유류가격은 해당지역의 가격으로 한다」. 칸은 있었으나 시도별 값이 없어 잠겨 있었음. 오피넷 avgSidoPrice.do 스냅샷을 받아 데이터셋으로 세우고 물림. - 안 고르면 전국평균 그대로 — 현장 소재지를 임의로 찍지 않음. - 판에 없는 지역은 조용히 전국평균으로 눕지 않고 사유를 남김. - 「지역 공시가」를 고를 수 있는지는 코드가 아니라 판이 정함. - ⚠ 원천의 시도 가름이 행정구역과 다름(20=전남광주 한 줄, 07·16 없음) — 원문 그대로 둠. - 수집 스크립트에 시도별 호출을 더함(전국평균과 두 벌로 보존). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
87 lines
3.5 KiB
Python
87 lines
3.5 KiB
Python
"""유가 지역 단가 — 품셈 8-1-7 5호 「유류가격은 **해당지역의 가격**으로 한다」 (2026-09-09).
|
|
|
|
칸은 전부터 있었는데 **값이 없어 잠겨 있던** 자리다. 오피넷 시도별 판을 받아 물렸다.
|
|
|
|
⚠ 겨누는 것 다섯
|
|
① 안 고르면 **전국평균 그대로** — 현장 소재지를 임의로 찍지 않음
|
|
② 고르면 **그 시도 값**으로 서고, 기계 시간당 사용료가 함께 움직임
|
|
③ 판에 없는 지역은 **조용히 전국평균으로 눕지 않고** 그 사실을 신원에 적음
|
|
④ 코드 `00`(전국)은 지역 선택지에서 뺌 — 두 판이 같은 이름으로 서면 못 가림
|
|
⑤ 「지역 공시가」를 고를 수 있는지는 **코드가 아니라 판이 정함**
|
|
"""
|
|
|
|
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))
|
|
|
|
from B09_Estimation.B09_Estimation_Lists_Sources import fuel_scopes # noqa: E402
|
|
from B09_Estimation.B09_Estimation_MachineOperating import ( # noqa: E402
|
|
load_fuel_price,
|
|
load_regional_fuel_table,
|
|
)
|
|
from B09_Estimation.B09_Estimation_PriceBook import PriceKind # noqa: E402
|
|
from B09_Estimation.B09_Estimation_UnitPrice import cached_build # noqa: E402
|
|
|
|
|
|
def test_안_고르면_전국평균() -> None:
|
|
price, meta = load_fuel_price()
|
|
assert meta["scope"] == "national_average"
|
|
assert meta["region"] == "" and meta["region_name"] == ""
|
|
assert price > 0
|
|
|
|
|
|
def test_고르면_그_시도_값으로_선다() -> None:
|
|
table, _ = load_regional_fuel_table()
|
|
code = next(iter(sorted(table)))
|
|
price, meta = load_fuel_price(region=code)
|
|
assert price == table[code]["value"]
|
|
assert meta["scope"] == "regional" and meta["region_name"] == table[code]["name"]
|
|
|
|
|
|
def test_판에_없는_지역은_사실을_적는다() -> None:
|
|
"""⚠ 조용히 전국평균으로 누우면 사용자는 지역값인 줄 안다."""
|
|
national, _ = load_fuel_price()
|
|
price, meta = load_fuel_price(region="ZZ")
|
|
assert price == national
|
|
assert "판에 없어" in meta["region_missing"]
|
|
|
|
|
|
def test_전국_줄은_지역_선택지에서_뺀다() -> None:
|
|
table, _ = load_regional_fuel_table()
|
|
assert "00" not in table
|
|
assert len(table) >= 10
|
|
|
|
|
|
def test_고를_수_있는지는_판이_정한다() -> None:
|
|
scopes = {s["key"]: s for s in fuel_scopes()}
|
|
assert scopes["national_average"]["available"] is True
|
|
# 판이 들어와 있으므로 지역도 열려 있어야 한다.
|
|
assert scopes["regional"]["available"] is bool(load_regional_fuel_table()[0])
|
|
|
|
|
|
def test_기계_시간당_사용료가_지역을_따라_움직인다() -> None:
|
|
"""② 값이 실제로 갈리는지 — 안 갈리면 칸만 있고 뜻이 없다."""
|
|
table, _ = load_regional_fuel_table()
|
|
# 전국평균과 값이 다른 시도를 골라 견준다.
|
|
national, _ = load_fuel_price()
|
|
code = next(c for c, v in sorted(table.items()) if v["value"] != national)
|
|
|
|
base = cached_build()
|
|
picked = cached_build((), (), "", code)
|
|
machine = next(
|
|
c for c, t in sorted(base.book.titles.items()) if t.kind is PriceKind.MACHINE_HOURLY
|
|
)
|
|
diff = picked.book.resolve(machine).total - base.book.resolve(machine).total
|
|
assert diff != Decimal(0)
|
|
|
|
fuel_title = next(
|
|
t for t in picked.book.titles.values() if t.kind is PriceKind.MATERIAL and t.name == "경유"
|
|
)
|
|
# 어느 판으로 섰는지 줄에 남아야 한다.
|
|
assert table[code]["name"] in fuel_title.spec
|