시험 534_3 기대 「No.n」 → 「n+0」(견본 label 칸은 이제 안 읽힘) · 545_1 공용 짝 거울 덧. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
39 lines
1.5 KiB
Python
39 lines
1.5 KiB
Python
"""측점 표기 한 벌 — 파이썬 짝(TS `common_util/common_util_station.ts` · 거울 시험 `test_545_1`).
|
|
|
|
`station_label` ↔ `stationLabel` · `infer_station_interval` ↔ `inferStationInterval` — 한쪽을 고치면 다른 쪽도.
|
|
가져오는 것이 없는 순수 함수(E05 보고서 등 무거운 모듈 없이 씀).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
from typing import Any
|
|
|
|
|
|
def station_label(chainage: float, interval: float, decimals: int = 1) -> str:
|
|
"""`측점번호+잔여거리`(예 `61+14.5` · `decimals=0` 이면 거리 정수)."""
|
|
safe = interval if interval > 0 else 1.0
|
|
number = math.floor((chainage + 1e-6) / safe)
|
|
rest = chainage - number * safe
|
|
if abs(rest) < 0.05:
|
|
rest = 0.0
|
|
if rest >= safe - 0.05:
|
|
number, rest = number + 1, 0.0
|
|
scale = 10 if decimals else 1
|
|
shown = math.floor(rest * scale + 0.5) / scale # JS Math.round
|
|
return f"{number}+{int(shown) if shown == int(shown) else shown}"
|
|
|
|
|
|
def infer_station_interval(stations: list[dict[str, Any]]) -> float:
|
|
"""측점 목록의 최빈 간격(0.1 m 반올림 · 같으면 큰 쪽 · 없으면 1)."""
|
|
counts: dict[float, int] = {}
|
|
for prev, cur in zip(stations, stations[1:]):
|
|
difference = float(cur["chainage_m"]) - float(prev["chainage_m"])
|
|
if difference <= 0:
|
|
continue
|
|
rounded = math.floor(difference * 10 + 0.5) / 10
|
|
counts[rounded] = counts.get(rounded, 0) + 1
|
|
if not counts:
|
|
return 1
|
|
return max(counts.items(), key=lambda item: (item[1], item[0]))[0]
|