From cd3aaef11792984f75b30fb1a5a3d7b3f56a33f6 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sun, 13 Sep 2026 12:42:53 +0900 Subject: [PATCH] =?UTF-8?q?knowledge(=EA=B2=BD=EC=9F=81=EC=82=AC):=20?= =?UTF-8?q?=ED=86=B5=EC=A0=9C=EC=8B=9C=ED=97=98=20=EC=88=98=ED=96=89=20?= =?UTF-8?q?=EB=B6=88=EA=B0=80(=EB=9D=BC=EC=9D=B4=EC=84=A0=EC=8A=A4=20?= =?UTF-8?q?=EC=97=86=EC=9D=8C)=20=EB=B0=98=EC=98=81=20=C2=B7=20=EC=9A=94?= =?UTF-8?q?=EC=9C=A8=20=EB=91=90=20=EB=B6=80=EB=A5=98=20=EA=B5=AC=EB=B6=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 전제 정정 - STmate 라이선스가 없어 13번 T1~T11 을 띄울 수 없음. 「나중에 시험으로 확정」 계획이 성립하지 않으므로 13번 머리에 못박고, 대체 경로 셋과 그것으로 이미 푼 것을 적음. 목록 자체는 장부 겸 절차서로 남김 - 남은 것을 늘릴 유일한 수단은 표본 늘리기. 특히 수공(S)·실적(TA/SA) 형식 표본이 하나도 없어 그 세 형식은 전혀 검증되지 않음 통제시험 없이 새로 밝힌 것 - 요율 항목이 두 부류임. 고정 칸(보험·산안비·이윤)과 규모·기간에 따라 행이 움직이는 것(간접노무비·기타경비·일반관리비). 뒤쪽은 고정 좌표라는 모델 자체가 틀림 - 이윤 좌표 RATE_R[20,16] 확정 (3건 일치) - 요율이 그 프로젝트 표에 아예 없는 경우가 실재함. 간선임도 간접노무비 14.5%, 소광 이윤 13.435% 가 자기 RATE_R 에 없음 = 사용자 수동 입력. 재구현은 rate_source 를 table(coord)/manual 로 갈라 저장해야 함 교차검증 스크립트 2개 추가. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01Prk9BCHG1EMAywk9k8wegA --- .../20_분석/00_분석_요약과_읽는법.md | 3 + .../STmate 분석/20_분석/13_통제시험_목록.md | 27 +++++- .../20_분석/15_재구현_가능성_검증.md | 35 +++++++- .../40_스크립트/t1_band_column_test.py | 27 ++++++ .../t1_cross_project_consistency.py | 85 +++++++++++++++++++ 5 files changed, 173 insertions(+), 4 deletions(-) create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/t1_band_column_test.py create mode 100644 resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/t1_cross_project_consistency.py diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/00_분석_요약과_읽는법.md b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/00_분석_요약과_읽는법.md index 7e6b7296..79ea582e 100644 --- a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/00_분석_요약과_읽는법.md +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/00_분석_요약과_읽는법.md @@ -59,6 +59,9 @@ | 중기 시간당 사용료 | 손료 계수 없음 | **A** — 손료율·취득가·연료·잡품률 25개 장비 실측 | 17번 §3·§4 | | 호표 성분 소계 반올림 | 미확정 | **A** — 절사 (중기 398건 100%) | 17번 §2 | | 자재 6후보 자동채택 | C | **A 실증** — 0 아닌 후보 중 **최저가**. 복수후보 76/76 | 17번 §5.5, 07번 §5 | +| 이윤 요율 좌표 | 미확정 | **A** — `RATE_R[20,16]`, 3건 일치 | 15번 §4 | +| 요율의 출처 | 표에서 고른다고 가정 | **표에 없는 요율이 실재** — 사용자 수동 입력 경로 필수 | 15번 §4 | +| 통제시험 T1~T11 | 「나중에 수행」 | **수행 불가 — STmate 라이선스 없음.** 표본 늘리기가 유일한 확장 수단 | 13번 머리, 15번 §6 | 분석일: 2026-09-13 대상: `C:\경영정보(주)` diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/13_통제시험_목록.md b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/13_통제시험_목록.md index e707a4ea..687f2d74 100644 --- a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/13_통제시험_목록.md +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/13_통제시험_목록.md @@ -2,8 +2,31 @@ > 정적 분석만으로는 확정할 수 없는 경계를 **시험 단위로 갈라 놓은 유일한 목록**이다. 05~12번 문서에 흩어져 있던 "미확정·C등급" 항목을 여기로 모았다. 각 문서는 이제 이 목록을 가리킨다. -기준일: 2026-09-13 -대상: `C:\경영정보(주)` — **원본은 읽기만 한다.** 시험은 프로젝트 **복제본**에서 한다. +기준일: 2026-09-13 (전제 갱신 2026-09-13) +대상: `C:\경영정보(주)` — **원본은 읽기만 한다.** + +## ⛔ 전제 정정 — 이 시험들은 **실행할 수 없다** + +**STmate 라이선스가 없어 프로그램을 띄울 수 없다.** 따라서 아래 T1~T11은 **수행 불가**이며, 「나중에 시험으로 확정한다」는 계획은 성립하지 않는다. + +이 목록은 버리지 않고 **두 가지 용도로 남긴다.** + +1. **무엇이 왜 확정 불가인지**를 항목별로 밝혀 둔 장부 — 어떤 값이 「모르는 것」인지 분명히 해 두어야 Aislo가 그 자리를 정책 플래그로 열어 둘 수 있다. +2. **라이선스가 생기거나 실무자가 대신 눌러 줄 수 있게 되면** 그대로 쓸 절차서. + +**대신 쓸 수 있는 길**은 세 갈래이며, 이미 상당 부분 성과가 났다. + +| 대체 경로 | 무엇을 풀었나 | +|---|---| +| **출력 XLSX 역추적** — 비고 칸에 밑수·요율이 적혀 있음 | 보험 요율 좌표 6개, 이윤 좌표 (15번 §4) | +| **골든셋 회귀** — 내역으로 원가계산을 다시 세워 대조 | 원가계산 전 과정, 끝전조정, 차수 규칙 (16번) | +| **출력 시트 전수 검정** — 일위대가·중기·자재단가대비표 | 성분 절사, 중기 손료율, 자재 채택=최저가 (17번) | + +**표본을 늘리는 것이 통제시험을 대신하는 유일한 확장 수단이다.** 프로젝트마다 공사규모·기간·공종이 다르므로, 표본이 늘수록 좌표와 조건이 저절로 좁혀진다. + +--- + +아래는 라이선스가 생겼을 때를 위한 원 절차서다. 시험은 프로젝트 **복제본**에서 한다. ## 0. 왜 시험이 필요한가 diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/15_재구현_가능성_검증.md b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/15_재구현_가능성_검증.md index 24988258..66a04c32 100644 --- a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/15_재구현_가능성_검증.md +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/20_분석/15_재구현_가능성_검증.md @@ -109,9 +109,32 @@ A등급 불변조건으로 적혀 있으나 실데이터에 **59행 중 2행이 ⇒ **`RATE_R`의 행 45~49는 요율 행렬이 아니라 부속표 영역**이고, 행 0~44가 규모·기간 행렬임. -### 아직 좌표가 안 갈리는 항목 +### 항목이 두 부류로 갈림 — 통제시험 없이 밝힌 것 -`연금보험료(4.5%)`·`일반관리비(6%)`·`이윤(15%)`·`환경보전비(0.8%)`·`부가가치세(10%)`는 **같은 값이 표 안 여러 곳에 있어** 단독으로는 못 가름. 확정하려면 **한 프로젝트에서 그 값만 특이한 숫자로 바꿔 저장**하는 통제시험이 필요함(13번 T1). +프로젝트 5건의 요율을 각자의 `RATE_*` 표에 겹쳐 보면 항목이 두 갈래로 나뉨. + +**① 고정 칸** — 공사규모·기간과 무관. 전 프로젝트에서 같은 좌표. + +```text +산재보험료 RATE_R[45, 1] 건강보험료 RATE_R[46, 1] +연금보험료 RATE_R[46, 6] 장기요양 RATE_R[46, 11] +고용보험 등급1~7 RATE_R[45, 11..17] +산업안전보건관리비 RATE_R[20, 17] 율 · [20, 18] 기초액 ← 3건 전부 유일 +이윤 RATE_R[20, 16] ← 3건 전부 일치 +``` + +**② 규모·기간에 따라 칸이 움직임** — 간접노무비·기타경비·일반관리비. 전 프로젝트에 공통인 좌표가 **없음.** 행이 `(공사규모 밴드, 공사기간 밴드)`로 정해지므로 고정 좌표라는 모델 자체가 틀림. 열은 공종(토목·산설·조경·건축·산설건축)이고 행이 움직인다. + +### ⚠ 요율이 표에 아예 없는 경우가 실재함 + +| 프로젝트 | 항목 | 쓴 요율 | 그 프로젝트 `RATE_R` 안에 | +|---|---|---:|---| +| 2024 간선임도 (기번3) | 간접노무비 | 14.5% | **없음** | +| 2025 소광 (기번8) | 이윤 | 13.435% | **없음** | + +즉 **사용자가 표를 거치지 않고 요율을 직접 써 넣은 것**이다. 11번 §8이 「순환이 생기면 사용자 수동 확정으로 넘긴다」고 한 경로가 실데이터에 그대로 나타났다. + +**재구현 필수 조건** — 요율을 표에서 못 찾았다고 오류로 막으면 안 된다. `rate_source ∈ {table(coord), manual}` 을 항상 함께 저장하고, 수동값이면 좌표 없이 값만 보존해야 한다. ## 5. 그래서 무엇을 만들 수 있나 @@ -142,6 +165,14 @@ A등급 불변조건으로 적혀 있으나 실데이터에 **59행 중 2행이 **Aislo 목적으로는 필요한 정보가 모였음.** 「STmate 복제」는 애초에 불가능하고 목표도 아님. +### ⛔ 통제시험은 못 함 — 라이선스 없음 + +13번의 T1~T11은 **STmate를 띄워야 하는데 라이선스가 없어 수행 불가**다. 따라서 「나중에 시험으로 확정」이라 미뤄 둔 항목은 **다른 길로 풀거나, 모르는 채로 두고 Aislo에서 정책으로 여는 수밖에 없다.** + +실제로 대체 경로가 잘 들었다 — 출력 XLSX 역추적·골든셋 회귀·출력 시트 전수 검정으로 09번이 꼽은 여섯 차단점 중 **둘을 완전히, 하나를 절반** 풀었다(17번 §7). + +**남은 것을 늘릴 방법은 표본을 늘리는 것 하나뿐이다.** 공사규모·기간·공종·계산형식이 다른 프로젝트가 들어올수록 좌표와 조건이 저절로 좁혀진다. 특히 **수공형식(`S`)·실적형식(`TA`/`SA`) 표본이 하나도 없어** 그 세 형식은 지금 전혀 검증되지 않았다. + ## 7. 다음에 할 것 | 순위 | 할 일 | 왜 | diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/t1_band_column_test.py b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/t1_band_column_test.py new file mode 100644 index 00000000..c02d4377 --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/t1_band_column_test.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +import sys, io, pathlib, re, zipfile, struct, collections, warnings, difflib +warnings.filterwarnings("ignore"); import openpyxl +SRC = open(r"C:\Users\umsan\AppData\Local\Temp\claude\D--aislo-wt-sub\df75230a-b05b-4088-ad34-bb0c9da0a312\scratchpad\t1_consist.py", + encoding="utf-8").read().split("items = collections.Counter()")[0] +SRC = SRC.replace('sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")','') +SRC = "\n".join(l for l in SRC.split("\n") if not l.strip().startswith("print(")) +ns = {} +exec(SRC, ns) +per = ns["per"]; tabs_by_proj = ns["tabs_by_proj"] +out = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace") +def P(*a): print(*a, file=out) +P("### 규모·기간 의존 항목 — 열이 고정인가 (RATE_R 행 0~44 안)") +for lab in ("간접노무비","기타경비","일반관리비","이윤"): + vals = {k: per[k][lab] for k in per if lab in per[k]} + if len(vals) < 3: continue + colsets=[]; detail=[] + for k,v in vals.items(): + M = tabs_by_proj[k].get("RATE_R") or [] + hits = {(i,j+1) for i,row in enumerate(M[:45]) for j,x in enumerate(row) if x and abs(x-v)<1e-6} + colsets.append({c for _,c in hits}); detail.append((k,v,sorted(hits)[:6])) + common = set.intersection(*colsets) if colsets else set() + P("\n■ %s 관측 %d건, 값 %s" % (lab, len(vals), sorted({v for v in vals.values()}))) + P(" 모든 프로젝트 공통 열: %s" % (sorted(common) or "없음")) + for k,v,h in detail: + P(" %-30s %7.3f%% %s" % (k[:30], v, ", ".join("(%d,%d)"%x for x in h) or "없음")) +out.flush() diff --git a/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/t1_cross_project_consistency.py b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/t1_cross_project_consistency.py new file mode 100644 index 00000000..df868766 --- /dev/null +++ b/resources/knowledge/original/경쟁사 프로그램/STmate 분석/40_스크립트/t1_cross_project_consistency.py @@ -0,0 +1,85 @@ +# -*- coding: utf-8 -*- +"""T1 대체 — 통제시험 없이, 모든 프로젝트에서 동시에 성립하는 좌표만 남긴다.""" +import sys, io, pathlib, re, zipfile, struct, collections, warnings, difflib +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\실무문서") +def dbf(zf,name): + b=zf.read(name); nrec,hlen,rlen=struct.unpack_from("bs: bs,best=s,x + if best and bs>0.55: pairs.append((stc,best)) + +# 항목 -> {프로젝트: 요율} +per = {} +tabs_by_proj = {} +for stc,xp in pairs: + try: r = rates(xp) + except Exception: continue + if not r: continue + z = zipfile.ZipFile(stc); tabs={} + for n in z.namelist(): + if re.match(r"RATE.*\.DBF$", n, re.I): + try: tabs[n.upper().replace(".DBF","")] = dbf(z,n) + except Exception: pass + key = stc.stem[:28] + tabs_by_proj[key]=tabs; per[key]=r + +items = collections.Counter() +for k,r in per.items(): + for lab in r: items[lab]+=1 +print("프로젝트 %d건, 항목별 관측 수" % len(per)) +print() +print("%-22s %5s %6s %s" % ("항목","관측","값종류","전 프로젝트에서 동시에 맞는 좌표")) +print("-"*96) +for lab, cnt in items.most_common(): + vals = {k: per[k][lab] for k in per if lab in per[k]} + if len(vals) < 3: continue + # 후보 좌표: 첫 프로젝트에서 값이 맞는 모든 자리 + first = next(iter(vals)) + cand = set() + for tn, M in tabs_by_proj[first].items(): + for i,row in enumerate(M): + for j,x in enumerate(row): + if x and abs(x-vals[first])<1e-6: cand.add((tn,i,j)) + for k in list(vals)[1:]: + keep=set() + for (tn,i,j) in cand: + M = tabs_by_proj[k].get(tn) + if M and i4: s += " …외 %d" % (len(cand)-4) + print("%-22s %5d %6d %s" % (lab[:22], len(vals), nv, s))