"""측점 표기 한 벌 — 파이썬 짝(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]