Files
Aislo/common_util/common_util_quantity_spread.py
eomsangdonandClaude Opus 5 c7d917864c feat(B08): 암 시공법 칸 · 관급구분 표 입력 · 산출 크기 요약
- 암 시공법(ripping/blasting)을 갈래 비율 칸 아래에 붙임. 갈래 이름만으로는
  품셈 공종(암절취 FP-09-04 / 발파암 FP-09-05)을 못 고르던 자리. 기본은
  「안 정함」이고, 안 정하면 인계에서 사유와 함께 드러남. 비율 미입력 상태의
  「암」 한 줄에도 칸을 냄.
- 관급/사급은 표 안에서 줄마다 고름. 관급 줄에만 설치주체가 열리고 사급으로
  되돌리면 잠기며 비워짐. 만진 줄은 표시가 남음.
- 산출 요약(최소·중앙·최대)을 원단위·자재총괄·인계에 붙임. 단위별로 갈라 냄 —
  값이 있기만 하면 시험이 못 잡는 자릿수 어긋남을 사람이 훑게 하는 장치.

화면에서 걸려 고친 것 둘
- 관급을 골라도 설치주체 칸이 잠긴 채 남던 것. 고른 즉시 열고 닫게 함.
- 한 번 고른 시공법을 되돌릴 길이 없던 것. 설정 저장이 병합이라 빈 값을 보내도
  옛 값이 남았음. `save_section(replace_keys=…)` 로 되돌릴 수 있어야 하는 칸만
  통째로 갈아 끼움. 나머지는 그대로 병합.

앞 커밋에서 온 타입 오류 2건도 고침 (`slopeColumnCount` 미사용,
`variant: "outlined"` 는 없는 값). 앞선 확인에서 npx 가 엉뚱한 패키지를 실행해
「오류 없음」으로 잘못 봤음 — tsc 는 config/node_modules 것으로 부를 것.

검증 — 새 시험 5건 + 인계 28건 통과, 전체 509 passed. tsc 오류 0.
화면 실조작으로 시공법 저장·되돌리기, 관급/설치주체 저장·되돌리기 확인 후
검증으로 바꾼 값은 원래대로 복원.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-08 00:18:00 +09:00

48 lines
1.9 KiB
Python

"""산출 요약 — 값의 **크기가 말이 되나**를 한눈에 보이는 자리 (2026-09-07 조율 창 권고).
왜 있나
서브 창이 씨앗뿜어붙이기를 **합계 68.8원**으로 세워 두고도 몰랐던 일이 있었다.
값이 **있기는 하니** 어떤 시험도 안 잡는다. 자릿수가 어긋난 것은 사람이 훑어야 보이고,
훑으려면 **최솟값·중앙값·최댓값이 표 옆에 떠 있어야** 한다.
⚠ 이것은 검사가 아니라 **눈에 띄게 하는 장치**다
기준을 정해 놓고 걸러 내지 않는다 — 임도 물량은 ㎥·㎡·m·ton·개가 섞여 있어 「얼마 이하면
이상하다」를 한 벌로 못 정한다. **단위별로 나눠** 내고 판단은 사람에게 맡긴다.
"""
from __future__ import annotations
from statistics import median
from typing import Any, Iterable
def spread(values: Iterable[float]) -> dict[str, float] | None:
"""최솟값·중앙값·최댓값. 값이 없으면 `None` — 0 으로 만들지 않는다."""
numbers = [float(v) for v in values if isinstance(v, (int, float))]
if not numbers:
return None
return {
"min": min(numbers),
"median": float(median(numbers)),
"max": max(numbers),
"count": len(numbers),
}
def spread_by_unit(
rows: Iterable[dict[str, Any]], *, value_key: str
) -> dict[str, dict[str, float]]:
"""단위별로 갈라 낸다. ㎥ 와 ton 을 한 통에 넣으면 최솟값이 뜻을 잃는다."""
buckets: dict[str, list[float]] = {}
for row in rows:
value = row.get(value_key)
if not isinstance(value, (int, float)):
continue
buckets.setdefault(str(row.get("unit") or "?"), []).append(float(value))
result: dict[str, dict[str, float]] = {}
for unit, numbers in buckets.items():
found = spread(numbers)
if found:
result[unit] = found
return result