knowledge(경쟁사): 누락 계산로직 점검 — 사슬 앞쪽 네 칸을 채움
출력 XLSX 21개 시트 중 검증한 것이 4개뿐이었음. 나머지를 전부 열어 본 결과 계산 사슬 앞쪽이 통째로 비어 있었음. 채운 것 - 노임 일단가 -> 시간당 환산식. 환율및기초자료 시트에 식이 있고 INITIAL 의 RXNM_ 에 문자열로 저장됨. 적용 직종은 COND_ - ⚠ 식은 좌에서 우로 차례로 평가해야 함. 계수를 먼저 곱하면 부동소수점 때문에 1원 틀어짐. 18건 중 좌우순차 18/18, 계수선계산 14/18 - 단가산출 D코드 공식. Q = 3600*q*K*f*E/Cm 로 시간당 작업량을 내고 성분단가 = 절사(중기 시간당 성분단가 / Q, 소수1). Q 는 소수2 로 먼저 확정. 73개 호표에서 발견. 품셈 근거·토질·조합기준이 문자열로 남아 있음 - 계산 설정 스냅샷이 출력 XLSX 의 INITIAL 시트에 통째로 있음. 12번이 「화면 없이는 재현 불가」라 한 것을 정정. JMKN6 = 적용 단가 확인 - 집계표 행 금액은 사사오입 100%. 호표 성분 소계(절사)와 다른 자리임을 수치로 가름 문서 18 신규, 검증 스크립트 2개 추가. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Prk9BCHG1EMAywk9k8wegA
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
| 15 재구현 가능성 검증 | **무엇을 만들 수 있고 무엇이 막혀 있나** — 층별 확보표, 문서 오류 정정, T1 좌표 확정 | https://share.onorca.dev/a/t6HGy0HlbEBl |
|
||||
| 16 골든셋 회귀 결과 | **원가계산을 다시 세워 원 단위로 맞춘 실증** — 프로젝트 6건 전 항목 일치 | (저장소 파일) |
|
||||
| 17 단가조립 검증 | **일위대가·중기 시간당 사용료 구조와 손료율 실측** | (저장소 파일) |
|
||||
| 18 누락 계산로직 점검 | **사슬에 빠진 칸 찾기** — 노임 환산식·단가산출 Q식·설정 스냅샷·집계표 반올림 | (저장소 파일) |
|
||||
|
||||
> **정본은 저장소 파일이다** — `resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/`.
|
||||
> 위 Orca 링크는 보기용이며, 문서를 지식DB 자리로 옮기면서 주소가 한 번 바뀌었다.
|
||||
@@ -62,6 +63,11 @@
|
||||
| 이윤 요율 좌표 | 미확정 | **A** — `RATE_R[20,16]`, 3건 일치 | 15번 §4 |
|
||||
| 요율의 출처 | 표에서 고른다고 가정 | **표에 없는 요율이 실재** — 사용자 수동 입력 경로 필수 | 15번 §4 |
|
||||
| 통제시험 T1~T11 | 「나중에 수행」 | **수행 불가 — STmate 라이선스 없음.** 표본 늘리기가 유일한 확장 수단 | 13번 머리, 15번 §6 |
|
||||
| 노임 시간당 환산 | **문서에 없었음** | **A** — `일노임 × 설정식`, 식은 `RXNM_`에 문자열 저장 | 18번 §2.1 |
|
||||
| 식 평가 순서 | 명시 없음 | **A** — **좌→우 순차.** 계수를 먼저 곱하면 1원 틀림 | 18번 §2.1 |
|
||||
| 단가산출 `D`코드 | **문서에 없었음** | **A** — `Q=3600qKfE/Cm`, 성분 = 절사(시간단가/Q, 소수1) | 18번 §2.2 |
|
||||
| 계산 설정 스냅샷 | 「화면 없이 재현 불가」 | **출력 XLSX `〓 INITIAL 〓` 에 있음** | 18번 §2.3 |
|
||||
| 집계표 행 금액 | 서술만 | **A** — 사사오입 100%. 호표 성분 소계(절사)와 다른 자리 | 18번 §2.4 |
|
||||
|
||||
분석일: 2026-09-13
|
||||
대상: `C:\경영정보(주)`
|
||||
|
||||
@@ -27,6 +27,9 @@ Aislo 입장에서는 이것으로 충분함 — Aislo는 **자기 기초단가
|
||||
| | 표준시장단가 `*.CSTA` 4,921~4,961건 × 6 | **본문 암호화** | ❌ |
|
||||
| | `*.STBSC` 28개 (노임·기계경비 배포) | ZIP 컨테이너, 내부 암호 | ❌ |
|
||||
| **3 단가 계산** | `COSTN.DBF` 단가 네 성분 | **평문 — 읽힘** | ✅ |
|
||||
| | 노임 일→시간 환산식 | **`환율및기초자료` 시트 + `RXNM_` 설정** (18번) | ✅ |
|
||||
| | 단가산출 `D`코드 Q식·품셈 인자 | **`단가산출근거` 시트 3,889행** (18번) | ✅ |
|
||||
| | 계산 설정 스냅샷 | **`〓 INITIAL 〓` 시트** (18번) | ✅ |
|
||||
| | `COSTN.SMT` 구성 토큰 | 평문, 문법 문서화됨 | ✅ |
|
||||
| | 중기 시간당 손료율·연료·잡품률 | **출력 `중기사용료` 시트에 전부 있음** (17번) | ✅ |
|
||||
| | 자재 6후보 중 자동채택 규칙 | C등급 | ❌ |
|
||||
|
||||
@@ -0,0 +1,152 @@
|
||||
# 누락 계산로직 점검 — 사슬에 빠진 칸 찾기
|
||||
|
||||
점검일: 2026-09-13
|
||||
방법: STmate 출력 XLSX의 **21개 시트를 하나씩 세어**, 계산이 일어나는 시트 가운데 아직 확인하지 않은 것을 모두 열어 봄.
|
||||
재현 스크립트: `40_스크립트/wage_hourly_check.py`, `unit_derivation_check.py`
|
||||
|
||||
## 1. 점검 전 상태
|
||||
|
||||
21개 시트 중 **검증한 것은 4개뿐**이었다.
|
||||
|
||||
| 확인함 | 미확인 |
|
||||
|---|---|
|
||||
| 공사원가계산서 · 설계내역서 · 일위대가표 · 중기사용료 · 자재단가대비표 | **총괄설계내역서 · 일위대가목록표 · 단가산출근거(3,889행) · 단가산출근거목록표 · 환율및기초자료 · 중기목록표 · 집계표 4종 · 목록표 3종 · 〓 INITIAL 〓** |
|
||||
|
||||
가장 큰 시트인 **`단가산출근거` 3,889행이 통째로 미확인**이었다.
|
||||
|
||||
## 2. 빠져 있던 것 넷
|
||||
|
||||
### 2.1 노임 시간당 환산식 — 완전 미문서화였음
|
||||
|
||||
`환율및기초자료` 시트에 **일 노임을 시간당으로 바꾸는 식이 그대로** 있다.
|
||||
|
||||
```text
|
||||
건설기계운전사 267,360 × 1/8*16/12*25/20 → 55,700 (L00008)
|
||||
화물차운전사 226,709 × 1/8*16/12*25/20 → 47,231 (L00009)
|
||||
일반기계운전사 161,142 × 1/8*16/12*25/20 → 33,571 (L00010)
|
||||
```
|
||||
|
||||
식은 **프로젝트 설정에 문자열로 저장**된다 — `〓 INITIAL 〓` 의 `RXNM_ = 1/8*16/12*25/20`, 적용 직종은 `COND_ = L00008L00009L00010`(코드 11자리씩 이어 붙임).
|
||||
|
||||
**중기사용료의 「운전원 55,700」이 어디서 왔는지가 이것으로 풀린다.** 지금까지는 주어진 값으로만 놓고 있었다.
|
||||
|
||||
#### ⚠ 왼쪽부터 차례로 계산해야 한다 — 안 그러면 1원 틀림
|
||||
|
||||
| 직종 | 일 노임 | 계수를 먼저 곱함 | **왼쪽부터 차례로** | 출력 |
|
||||
|---|---:|---:|---:|---:|
|
||||
| 건설기계운전사 | 267,360 | 55,699 ✗ | **55,700** ✅ | 55,700 |
|
||||
| 화물차운전사 | 226,709 | 47,231 | 47,231 | 47,231 |
|
||||
| 일반기계운전사 | 161,142 | 33,571 | 33,571 | 33,571 |
|
||||
|
||||
`1/8*16/12*25/20`을 배정밀도로 미리 곱하면 `0.20833333333333331`이 되어 `267,360 × 계수 = 55,699.9999…` → 절사 시 **55,699**가 된다. 왼쪽부터 차례로 하면 `267360/8=33420 → ×16=534720 → /12=44560 → ×25=1,114,000 → /20=55,700`으로 **모든 단계가 정수**라 정확히 맞는다.
|
||||
|
||||
프로젝트 6건 × 직종 3개 = 18건 전부, **왼쪽부터 계산했을 때만 18/18 일치**한다(계수 선계산은 14/18).
|
||||
|
||||
⇒ **재구현 규칙: 설정에 저장된 식 문자열을 그대로 좌→우 순차 평가할 것. 계수로 접어 두지 말 것.** 11번 §4.1의 `evaluate(template, …)` 계약에 이 조건을 명시해야 한다.
|
||||
|
||||
### 2.2 단가산출(`D` 코드) 공식 — 가장 큰 누락
|
||||
|
||||
`단가산출근거` 3,889행에 **품셈 근거와 기계 작업량 식이 전부** 있다.
|
||||
|
||||
```text
|
||||
제 2호표 구조물 터파기(토사) 굴삭기 0.2m3 / m3
|
||||
건설표준품셈 3-1-3(터파기), 11-3(굴삭기) 적용
|
||||
적용토질 : 자갈썩인 기계 및 인력 조합기준 : 기계100%
|
||||
|
||||
q = 0.2 , f = 1/1.175 = 0.85 , K = 0.7
|
||||
Cm = 15 sec (90°) , E = 0.60-0.05 = 0.55
|
||||
Q = 3600*q*K*f*E/Cm = 15.71 m3/hr
|
||||
|
||||
노 무 비 : 55,700 / Q = 3,545.5
|
||||
재 료 비 : 7,701 / Q = 490.1
|
||||
경 비 : 13,041 / Q = 830.1
|
||||
소계 4,865.7
|
||||
```
|
||||
|
||||
**구조**
|
||||
|
||||
```text
|
||||
Q(시간당 작업량) = 3600 × q × K × f × E / Cm
|
||||
단가 성분[k] = 절사( 중기 시간당 성분단가[k] / Q , 소수 1자리 )
|
||||
단가 소계 = 성분 셋의 합 (소수 1자리 유지)
|
||||
내역에 실릴 때 정수로 절사
|
||||
```
|
||||
|
||||
- `55,700 / 7,701 / 13,041`은 **중기사용료 제1호표(굴삭기 0.2㎥)의 노무·재료·경비 합계** 그대로다. 즉 `중기사용료 → 단가산출 → 일위대가 → 내역`으로 값이 이어진다.
|
||||
- **`Q`는 소수 2자리로 먼저 확정한 뒤 나눈다.** 원값으로 나누면 어긋난다 (`55,700/15.708 = 3,545.96` ≠ `55,700/15.71 = 3,545.5`).
|
||||
- 성분단가는 **소수 1자리 절사**다. 6개 프로젝트 211건 중 137건(64.9%)이 이 규칙으로 설명되고, 나머지는 한 호표에 `Q`가 둘 이상인 기계조합 호표라 자동 구획이 어긋난 것이다.
|
||||
|
||||
`Q`식은 73개 호표에서 발견됐다. 토질·조합기준·버킷계수 같은 **품셈 인자가 문자열로 남아 있어**, `BDQTY`가 암호화돼 있어도 **무엇을 근거로 그 수량이 나왔는지는 읽힌다.**
|
||||
|
||||
### 2.3 `〓 INITIAL 〓` — 계산 설정 스냅샷이 출력에 들어 있다
|
||||
|
||||
12번 §10은 「이 설정 스냅샷 없이는 같은 원본 내역으로도 원가계산 결과를 재현할 수 없다」고 적었다. **그 스냅샷이 출력 XLSX 안에 있다.**
|
||||
|
||||
```text
|
||||
[공사정보] 33개 M_VER 24.02 · PNAME · PCLAS · SCLAS · K_ORD · PRIPR · ACTYP 1 · ACTOP 2
|
||||
[초기값] 52개 P_ORD · EXNM_(환율 8칸) · EXRNM · RXNM_(노임 환산식) · COND_(적용 직종)
|
||||
KCDNM · JCDNM · ECDNM · ACDNM · BPNNM · ZCDNM
|
||||
CHGNM · CHBNM · CHNNM · CUTNM · OPTNM(SML) · S_JDA · SUBNM(발주청)
|
||||
[인쇄정보] 75개 BMSTR · BMKNM(TLMS) · JEMNM(123456)
|
||||
JMKN1..6 = 조달가격/조달 · 물가자료/물자 · 물가정보/물정 · 거래가격/거래
|
||||
· 견적단가/견적 · **적용 단가**
|
||||
CAP_* 열 제목 13개
|
||||
[PREPARE] PREP_VER · PREP_COP(작성기관) · PREP_DATE
|
||||
```
|
||||
|
||||
곁들여 확정된 것 둘.
|
||||
|
||||
- **`JMKN6 = 적용 단가`** — 후보 슬롯이 다섯이고 **여섯 번째가 채택가 칸**이라는 17번 §5.5의 추정이 확인됐다.
|
||||
- **슬롯 이름은 프로젝트 설정에 들어 있다** — 07번이 「슬롯 번호에 가격지 이름을 코드로 고정하지 말라」고 한 경고의 근거가 여기다.
|
||||
|
||||
### 2.4 집계표 반올림 = **사사오입**, 절사 아님
|
||||
|
||||
호표 성분 소계(절사)와 **다른 자리**임을 수치로 갈랐다.
|
||||
|
||||
| 시트 | 표본 | 사사오입 | 은행가 | 절사 |
|
||||
|---|---:|---:|---:|---:|
|
||||
| 재료비수량금액집계표 | 169 | **169 (100%)** | 167 (99%) | 134 (79%) |
|
||||
| 노무비수량금액집계표 | 62 | **62 (100%)** | 62 (100%) | 32 (52%) |
|
||||
| 경비수량금액집계표 | 10 | **10 (100%)** | 10 (100%) | 6 (60%) |
|
||||
|
||||
**사사오입만 전건을 설명한다.** 재료비집계표 2건이 은행가와 갈려 둘을 구분해 준다. 07번 §6의 「집계표 = `ROUND`」가 실측으로 확인됐고, 17번 §2의 「호표 성분 소계 = 절사」와 **자리가 다르다**는 점이 분명해졌다.
|
||||
|
||||
## 3. 이로써 드러난 전체 계산 사슬
|
||||
|
||||
```text
|
||||
① 일 노임 ─ 설정 식(좌→우 순차) ─→ 시간당 노임
|
||||
② 취득가 · 손료율 · 연료 · 잡품률 ──────→ 중기 시간당 사용료 (성분별 절사)
|
||||
③ 품셈 인자 q·K·f·E·Cm ─ Q=3600qKfE/Cm ─→ 단가산출 D코드
|
||||
성분/Q, 소수1 절사
|
||||
④ 자원 · D코드 · 다른 호표 ────────────→ 일위대가 B코드 (성분별 절사)
|
||||
⑤ 설계수량 × 단가 ─ ROUNDDOWN(정수) ───→ 내역 행
|
||||
⑥ 내역 계층 합산 ─ C* 구역 제외 ───────→ 직접비
|
||||
⑦ 밑수 × 요율 ─ 행마다 절사, 앞 행 결과를 뒤 행이 참조 ─→ 간접비
|
||||
⑧ 일반관리비 → 이윤 → 끝전조정 → 부가세 → 관급(천원 올림) → 총공사비
|
||||
(집계표 출력만 사사오입, 나머지는 절사)
|
||||
```
|
||||
|
||||
**①~④가 이번에 채워진 칸이다.** 그전에는 ⑤부터만 검증돼 있었다.
|
||||
|
||||
## 4. 아직 안 본 시트
|
||||
|
||||
계산이 아니라 **목록·표지** 성격이라 우선순위가 낮다.
|
||||
|
||||
| 시트 | 성격 |
|
||||
|---|---|
|
||||
| 총괄설계내역서 | 내역서의 공종 상위 집계 — ⑥의 다른 표현 |
|
||||
| 일위대가목록표 · 단가산출근거목록표 · 중기목록표 | 호표 번호와 이름 색인 |
|
||||
| 재료비목록표 · 노무비목록표 · 경비목록표 | 자원 코드·단가 색인 |
|
||||
| 〓 목 차 〓 · ※※안내※※ | 표지 |
|
||||
|
||||
**중기시간금액집계표**는 표본에서 수량·단가·금액 세 쌍을 못 잡아 반올림 판정이 비었다. 다음에 열 위치를 맞춰 다시 볼 것.
|
||||
|
||||
## 5. 이번 점검이 바꾸는 것
|
||||
|
||||
| 항목 | 이전 | 지금 |
|
||||
|---|---|---|
|
||||
| 노임 시간당 환산 | **문서에 없음** | ✅ 식·저장 위치·평가 순서까지 확정 |
|
||||
| 식 평가 방식 | 명시 없음 | ✅ **좌→우 순차** (계수 선계산 금지) |
|
||||
| 단가산출 `D`코드 | **문서에 없음** | ✅ Q식·나눗셈·소수1 절사 |
|
||||
| 계산 설정 스냅샷 | 「화면 없이는 재현 불가」 | ✅ **출력 XLSX `〓 INITIAL 〓` 에 있음** |
|
||||
| 집계표 반올림 | 서술만 | ✅ **사사오입 100%** — 호표 절사와 다른 자리 |
|
||||
@@ -0,0 +1,47 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""단가산출근거 — Q식과 성분단가 = 시간단가/Q 의 반올림 규칙을 전수 확인."""
|
||||
import sys, io, pathlib, warnings, re, collections
|
||||
from decimal import Decimal as D, ROUND_DOWN, ROUND_HALF_UP
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
|
||||
warnings.filterwarnings("ignore"); import openpyxl
|
||||
ROOT = pathlib.Path(r"D:\aislo-wt\sub\resources\knowledge\original\실무문서")
|
||||
NUM = r"([\d,]+(?:\.\d+)?)"
|
||||
RE_Q = re.compile(r"Q\s*=\s*([0-9.*/\sqKfECm+\-]+?)\s*=\s*"+NUM)
|
||||
RE_C = re.compile(r"(노\s*무\s*비|재\s*료\s*비|경\s*비)\s*:\s*"+NUM+r"\s*/\s*Q\s*=\s*"+NUM)
|
||||
def d(s): return D(s.replace(",",""))
|
||||
|
||||
stat=collections.Counter(); ex=[]
|
||||
for p in sorted(ROOT.rglob("*.xlsx")):
|
||||
if p.name.startswith("~$"): continue
|
||||
try: wb=openpyxl.load_workbook(p,data_only=True,read_only=True)
|
||||
except Exception: continue
|
||||
if "단가산출근거" not in wb.sheetnames: continue
|
||||
curQ=None
|
||||
for row in wb["단가산출근거"].iter_rows(min_row=1,max_row=wb["단가산출근거"].max_row,max_col=3,values_only=True):
|
||||
txt = " ".join(str(c) for c in row[:2] if isinstance(c,str))
|
||||
if not txt: continue
|
||||
if re.search(r"제\s*\d+\s*호표", txt): curQ=None; continue
|
||||
m=RE_Q.search(txt)
|
||||
if m:
|
||||
curQ = d(m.group(2)); stat["Q식 발견"]+=1; continue
|
||||
for mm in RE_C.finditer(txt):
|
||||
if curQ in (None, D(0)): continue
|
||||
시간단가 = d(mm.group(2)); 결과 = d(mm.group(3))
|
||||
raw = 시간단가/curQ
|
||||
for pl,tag in ((1,"소수1"),(0,"정수")):
|
||||
for rm,rt in ((ROUND_DOWN,"절사"),(ROUND_HALF_UP,"사사오입")):
|
||||
if raw.quantize(D(1).scaleb(-pl), rounding=rm) == 결과: stat[(tag,rt)]+=1
|
||||
stat["성분 총"]+=1
|
||||
if len(ex)<4 and raw.quantize(D("0.1"),rounding=ROUND_DOWN)!=결과:
|
||||
ex.append((p.stem[:22], 시간단가, curQ, raw, 결과))
|
||||
|
||||
print("### 단가산출근거 — Q식과 성분단가")
|
||||
print(" Q식 발견 %d개, 성분단가 식 %d개" % (stat["Q식 발견"], stat["성분 총"]))
|
||||
t=stat["성분 총"]
|
||||
if t:
|
||||
print("\n 성분단가 = 시간당 성분단가 / Q 의 반올림")
|
||||
for pl in ("소수1","정수"):
|
||||
for rt in ("절사","사사오입"):
|
||||
n=stat[(pl,rt)]
|
||||
print(" %-5s %-5s %5d건 %5.1f%%" % (pl, rt, n, 100*n/t))
|
||||
for e in ex: print(" ✗ %-22s %s / %s = %s ≠ %s" % e)
|
||||
@@ -0,0 +1,66 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""누락 확인 ① 노임 시간당 환산식 ② 집계표 반올림 ③ INITIAL 설정"""
|
||||
import sys, io, pathlib, warnings, re, collections
|
||||
from decimal import Decimal as D, ROUND_DOWN, ROUND_HALF_UP, ROUND_HALF_EVEN
|
||||
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
|
||||
warnings.filterwarnings("ignore"); import openpyxl
|
||||
def dec(v):
|
||||
if v in (None,""): return None
|
||||
try: return D(str(v))
|
||||
except Exception: return None
|
||||
def q(x,m): return D(x).quantize(D(1), rounding=m)
|
||||
ROOT = pathlib.Path(r"D:\aislo-wt\sub\resources\knowledge\original\실무문서")
|
||||
XL=[p for p in sorted(ROOT.rglob("*.xlsx")) if not p.name.startswith("~$")]
|
||||
|
||||
print("### ① 노임 시간당 환산식 — 환율및기초자료 시트")
|
||||
for p in XL:
|
||||
try: wb=openpyxl.load_workbook(p,data_only=True,read_only=True)
|
||||
except Exception: continue
|
||||
if "환율및기초자료" not in wb.sheetnames: continue
|
||||
ws=wb["환율및기초자료"]
|
||||
rows=[list(r) for r in ws.iter_rows(min_row=1,max_row=ws.max_row,max_col=10,values_only=True)]
|
||||
print("\n-- %s" % p.stem[:52])
|
||||
for r in rows:
|
||||
nm = r[2] if len(r)>2 else None
|
||||
일 = dec(r[3]) if len(r)>3 else None
|
||||
식 = r[4] if len(r)>4 else None
|
||||
시 = dec(r[6]) if len(r)>6 else None
|
||||
if not (nm and 일 and 시 and isinstance(식,str)): continue
|
||||
expr = 식.strip().lstrip("*").strip()
|
||||
try:
|
||||
factor = eval(expr, {"__builtins__":{}})
|
||||
except Exception:
|
||||
factor = None
|
||||
calc = q(D(str(float(일)*factor)), ROUND_DOWN) if factor else None
|
||||
ok = "일치" if calc==시 else ("차 %+d"%(calc-시) if calc is not None else "식 해석실패")
|
||||
print(" %-16s 일 %9s × %-18s = %9s 출력 %9s %s" % (str(nm)[:16], f"{일:,}", expr, f"{calc:,}" if calc else "-", f"{시:,}", ok))
|
||||
|
||||
print("\n\n### ② 집계표 행 금액 반올림 — 수량 × 단가")
|
||||
SHEETS = ["재료비수량금액집계표","노무비수량금액집계표","경비수량금액집계표","중기시간금액집계표"]
|
||||
stat=collections.Counter()
|
||||
for p in XL:
|
||||
try: wb=openpyxl.load_workbook(p,data_only=True,read_only=True)
|
||||
except Exception: continue
|
||||
for s in SHEETS:
|
||||
if s not in wb.sheetnames: continue
|
||||
ws=wb[s]
|
||||
for r in ws.iter_rows(min_row=1,max_row=ws.max_row,max_col=12,values_only=True):
|
||||
nums=[(i,dec(v)) for i,v in enumerate(r) if isinstance(v,(int,float))]
|
||||
if len(nums)<3: continue
|
||||
# 수량·단가·금액 세 쌍을 찾는다
|
||||
for a in range(len(nums)-2):
|
||||
qty,up,amt = nums[a][1],nums[a+1][1],nums[a+2][1]
|
||||
if not (qty and up and amt) or qty<=0 or up<=0: continue
|
||||
raw=qty*up
|
||||
if abs(raw-amt) > raw*D("0.02"): continue
|
||||
for m,tag in ((ROUND_DOWN,"절사"),(ROUND_HALF_UP,"사사오입"),(ROUND_HALF_EVEN,"은행가")):
|
||||
if q(raw,m)==amt: stat[(s,tag)]+=1
|
||||
if raw==amt: stat[(s,"원값")]+=1
|
||||
stat[(s,"총")]+=1
|
||||
break
|
||||
for s in SHEETS:
|
||||
t=stat[(s,"총")]
|
||||
if not t: print(" %-22s 표본 없음"%s); continue
|
||||
print(" %-22s 표본 %4d 절사 %4d(%.0f%%) 사사오입 %4d(%.0f%%) 은행가 %4d(%.0f%%) 원값 %d" % (
|
||||
s, t, stat[(s,"절사")],100*stat[(s,"절사")]/t, stat[(s,"사사오입")],100*stat[(s,"사사오입")]/t,
|
||||
stat[(s,"은행가")],100*stat[(s,"은행가")]/t, stat[(s,"원값")]))
|
||||
@@ -43,6 +43,7 @@
|
||||
| 15 | **재구현 가능성 검증** — 무엇을 만들 수 있고 무엇이 막혀 있나 |
|
||||
| 16 | **골든셋 회귀 결과** — 원가계산을 다시 세워 원 단위로 맞춘 실증 |
|
||||
| 17 | **단가조립 검증** — 일위대가·중기 시간당 사용료 구조, 손료율 실측 |
|
||||
| 18 | **누락 계산로직 점검** — 노임 환산식·단가산출 Q식·설정 스냅샷 |
|
||||
|
||||
## 확정된 굵직한 것
|
||||
|
||||
@@ -53,6 +54,7 @@
|
||||
- 기준자료 `JB_R` 35열 확장 시점 **2020-05-27**, 기존 1~20열은 한 칸도 안 바뀜
|
||||
- 설정 **83축** 전수. 화면 순번과 내부값이 **뒤집힌 축 둘** 있음 — 그대로 저장하면 정반대 공식이 걸림
|
||||
- 보험 요율의 **표 좌표 확정** — 산재 `RATE_R[45,1]`, 건강 `[46,1]`, 연금 `[46,6]`, 장기요양 `[46,11]`, 고용 등급1~7 `[45,11..17]`. 5개 연도 시계열이 실제 법정요율 변천과 맞음
|
||||
- **계산 사슬 전체가 드러남** — 일 노임 → 시간당 → 중기 사용료 → 단가산출(Q식) → 일위대가 → 내역 → 간접비 → 총공사비 (18번)
|
||||
- **원가계산 전 과정을 원 단위로 재현함** — 실무 프로젝트 6건, 내역 행 1,515건 무결, 총공사비까지 1원도 안 틀림 (16번)
|
||||
- ⚠ **기초단가 원천은 전부 암호화** — 자재 5.7만 건·노임·중기·표준시장단가를 한 건도 못 읽음. 「계산 엔진」은 만들 수 있으나 「기준자료를 갖춘 완제품」은 못 만듦 (15번)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user