#!/usr/bin/env python3 """Render the confirmed station table (지반고 = A열, 계획고 = B열, 20 m station numbering per user decision 2026-10-21) into DOC/03_설계 and check the design grade against the drawn label S=2.4913% (정상 구배 검산). No value is adjusted.""" import csv import sys SRC, OUT = sys.argv[1], sys.argv[2] rows = [] with open(SRC, encoding="utf-8") as fh: rd = list(csv.DictReader(fh)) gl, dg = {}, {} for r in rd: sta = int(r["station_anchor"]) if float(r["across_m"]) < -25: gl[sta] = float(r["value"]) else: dg[sta] = float(r["value"]) stas = sorted(set(gl) & set(dg)) n = len(stas) xs = [s for s in stas] mx = sum(xs) / n my = sum(dg[s] for s in stas) / n slope = sum((s - mx) * (dg[s] - my) for s in stas) / sum((s - mx) ** 2 for s in stas) grade_pct = slope * 100 resid = [dg[s] - (my + slope * (s - mx)) for s in stas] max_res = max(abs(r) for r in resid) lines = ["# 본선 종단 측점값 — 지반고·계획고 (초안, 확정 해석 반영)\n", "| 버전 | 일자 | 변경 내용 |", "|---|---|---|", "| v0.1.00 | 2026-10-21 | 최초 작성. 02-002 종단 눈금 4+740~5+480, 지반고(A열)·계획고(B열) 확정 해석 반영 |\n", "## 1. 확정 사항 (사용자 답변 2026-10-21)", "- 소수 A열(중심선 측 약 -33m) = **지반고**, B열(약 -16m) = **계획고** [출처: C0060302-002, CR-TABL-TEX2]", "- 측점은 **측점 번호 20m 기준**. 도면상 눈금 거리 21.27m는 사용하지 않음 (축척 1.0635배 불일치 기록)", "- 공백 구간(4+700~4+740, 5+480~5+500)은 **[미확정]**, 확보 구간만 모델링\n", "## 2. 측점별 지반고·계획고", "| 측점(m) | 표기 | 지반고 GL(m) | 계획고(m) |", "|---|---|---|---|"] for s in stas: lines.append(f"| {s} | {s // 1000}+{s % 1000:03d} | {gl[s]:.3f} | {dg[s]:.3f} |") lines += ["", "## 3. 검산", f"- 계획고 직선 회귀 구배: **{grade_pct:.4f}%** (도면 표기 S=2.4913%와 비교)", f"- 계획고 회귀 잔차 최대: {max_res:.3f} m (구배 전 구간 직선 가정 시). 구배 꺾임이 있으면 잔차에 나타남", "- 지반고는 구배 검산 대상이 아님 (지형 값)\n", "## 4. 미확정·후속 (OPEN 등재 대상)", "- 4+700~4+740, 5+480~5+500 종단 값 없음 → [미확정]", "- 허용오차 ±50mm 판정: 본 초안은 도면 표기 값 그대로이며, 3D 대조 판정은 Task 7 이후 수행", "- 라이닝 두께 수치: 04-004~009 콘크리트라이닝 구조도 확인 예정 (사용자 지시 2026-10-21)\n"] open(OUT, "w", encoding="utf-8").write("\n".join(lines) + "\n") print(f"stations={n} grade={grade_pct:.4f}% max_resid={max_res:.3f}")