Merge remote-tracking branches 'origin/sub_laptop_1' and 'origin/sub_laptop_4' into sub_laptop_3
This commit is contained in:
@@ -12,7 +12,7 @@
|
||||
|
||||
- 이름 = `그룹_원문[_장].json` — 날짜 없음 · 마스터는 항상 최신. 예: `인력_건설노임.json` · `소요량_산림품셈_13장.json` · `로직_산림품셈_13장.json`
|
||||
- 그룹 = 인력 · 재료 · 기계 · 소요량 · 계수 · 환율 · 요율 · 로직
|
||||
- 원문 이름 = 산림품셈 · 건설품셈 · 건설노임 · 제조노임 · 나라장터자재 · 오피넷유가 · 한국은행환율 · 조달청제비율 · 자체
|
||||
- 원문 이름 = 산림품셈 · 건설품셈 · 건설노임 · 제조노임 · 나라장터자재 · 오피넷유가 · 시중물가 · 한국은행환율 · 조달청제비율 · 자체
|
||||
- UTF-8 · LF · 들여쓰기 2칸 · 칸 이름은 한글.
|
||||
|
||||
## 3. 출처
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
# 점검 — 재료_나라장터자재 6,999줄
|
||||
|
||||
원본 `resources/knowledge/original/원가계산/자재단가/나라장터_시설공통자재_2026-08-14.json`(.csv 같은 내용) · 마스터 `resources/master_data/재료_나라장터자재.json`. 파일 고침 없음 — 읽기만.
|
||||
|
||||
## 결론
|
||||
|
||||
- **6,999 = 원본의 물품식별번호(`prdctIdntNo`) 가짓수.** 물품마다 한 줄 — 잘린 것 아님 · 빠진 물품 0 · 남는 물품 0.
|
||||
- 줄이 준 길 — 원본 27,485줄 → 똑같은 줄 791 빼면 공시 26,694건 → 물품마다 가장 나중 제값 공시 하나 = 6,999줄.
|
||||
- 쪽 제한에 안 걸림 — 수집이 `numOfRows=999` 로 `totalCount` 에 닿을 때까지 쪽을 넘김(`collect_cost_sources.py` `collect_snapshot`).
|
||||
- ⚠ 다만 **받은 줄 속에 똑같은 줄 791** — 쪽 넘김 중 같은 줄이 두 번 옴. 개수를 `totalCount` 로 채웠으니 그만큼 **다른 줄이 안 왔을 수 있음(추정)**. 최신 회차에서 이렇게 빠졌을 수 있는 물품 ≤ 79(건축 51 · 기계설비 27 · 전기정보통신 1) — 이 물품은 앞 회차 값이 채택됐을 것.
|
||||
- **임도·사방 주요 자재는 거의 없음** — 원본이 조달청 「시설공통자재」 4분야(토목·건축·기계설비·전기정보통신)라 레미콘·철근·시멘트·골재·흄관·파형강관·돌망태는 분류 밖. 있는 것은 합판·각재(건축) · 직포매트(토목)뿐.
|
||||
- `제외묶음` 3(철근·레미콘·아스콘)은 **걸러낸 것이 아니라 원래 없다는 표시**. 시멘트·골재·흄관·파형강관·돌망태도 똑같이 없으나 제외묶음에 안 적힘.
|
||||
- 값 표본 30줄 — 원본과 모두 같음(값·단위·이름·규격·공시일시).
|
||||
|
||||
## 원본
|
||||
|
||||
| 항목 | 값 |
|
||||
|---|---|
|
||||
| 서비스 | 나라장터 가격정보현황서비스 `PriceInfoService` |
|
||||
| 오퍼레이션(분야) | `getPriceInfoListFcltyCmmnMtrilEngrk`(토목) · `…Bildng`(건축) · `…MchnEqp`(기계설비) · `…ElctyIrmc`(전기정보통신) |
|
||||
| 조건 | 분류·기간 거르개 없음 — 분야별 전건 · 쪽당 999 |
|
||||
| 받은 날 | 2026-08-14 |
|
||||
| 줄 수 | 27,485 (토목 639 · 건축 10,749 · 기계설비 9,985 · 전기정보통신 6,112) — `_meta.md` 와 같음 |
|
||||
| 쪽 수 | 토목 1 · 건축 11 · 기계설비 10 · 전기정보통신 7 |
|
||||
| 공시일 | 분야마다 네 회차 — 2024-10 · 2025-04 · 2025-10 · 2026-04 |
|
||||
| 부가세·가격종류 | 전부 「부가가치세별도」 · 「기타가격」 |
|
||||
|
||||
회차별 줄·물품(똑같은 줄·같은 날 두 공시가 섞인 차이):
|
||||
|
||||
| 분야 | 공시일 | 줄 | 공시번호 | 물품 |
|
||||
|---|---|---|---|---|
|
||||
| 토목 | 2024-10-16 · 2025-04-24 · 2025-10-23 | 각 138 | 각 138 | 각 138 |
|
||||
| 토목 | 2026-04-20 | 225 | 225 | 225 |
|
||||
| 건축 | 2024-10-30 | 2,158 | 2,129 | 2,129 |
|
||||
| 건축 | 2025-04-24 | 4,292 | 3,998 | 2,134 |
|
||||
| 건축 | 2025-10-23 | 2,134 | 2,104 | 2,104 |
|
||||
| 건축 | 2026-04-20 | 2,165 | 2,114 | 2,114 |
|
||||
| 기계설비 | 2024-10-17 | 2,980 | 2,893 | 2,893 |
|
||||
| 기계설비 | 2025-04-27 | 2,602 | 2,570 | 2,570 |
|
||||
| 기계설비 | 2025-10-23 | 2,202 | 2,055 | 2,055 |
|
||||
| 기계설비 | 2026-04-20 | 2,201 | 2,174 | 2,174 |
|
||||
| 전기정보통신 | 2024-10-16 | 1,531 | 1,478 | 1,478 |
|
||||
| 전기정보통신 | 2025-04-28 | 1,531 | 1,491 | 1,491 |
|
||||
| 전기정보통신 | 2025-10-23 | 1,531 | 1,531 | 1,531 |
|
||||
| 전기정보통신 | 2026-04-20 | 1,519 | 1,518 | 1,518 |
|
||||
|
||||
- 건축 2025-04-24 는 한 날에 두 차례 공시(`R25CW229…` · `R25CW243…`) — 물품 2,088개가 두 번 실림.
|
||||
- 똑같은 줄 791 은 쪽 경계가 아닌 쪽 안 여기저기(건축 404 · 기계설비 293 · 전기정보통신 94 · 토목 0 — 한 쪽짜리 토목만 없음).
|
||||
- 한 물품이 두 분야에 걸친 것 0.
|
||||
|
||||
## 원본 → 마스터
|
||||
|
||||
| 단계 | 줄 |
|
||||
|---|---|
|
||||
| 원본 | 27,485 |
|
||||
| 똑같은 줄 791 뺌 | 26,694 공시 |
|
||||
| 물품마다 한 공시 — 가장 나중 공시일 · 같은 날이면 큰 공시번호 · 값 빈칸·0 건너뜀 | 6,999 |
|
||||
|
||||
- 물품당 공시 수: 1번 567 · 2번 401 · 3번 416 · 4번 3,387 · 5번 2,048 · 6번 180.
|
||||
- 0원 공시 144줄 — 마스터에서 0 이 걸렸던 70줄은 앞 제값 공시로 바뀜(`비고` 「… 공시에 값이 없어 … 값을 씀」 · `_build_mat_price.py`). 못 고친 줄(`0원미회수`) 0.
|
||||
- 규칙 재현 — 위 규칙으로 원본에서 다시 고르면 6,999줄 모두 마스터와 같은 공시번호·값.
|
||||
- 최신 회차보다 옛 값인 줄 968(기계설비 779 · 건축 163 · 전기정보통신 25 · 토목 1) — 그 물품이 최신 회차에 안 실림. 대부분 공시 목록에서 빠진 것 · 위 추정 79 가 섞였을 수 있음.
|
||||
- 마스터 분야: 기계설비 2,953 · 건축 2,277 · 전기정보통신 1,543 · 토목 226.
|
||||
|
||||
## 주요 자재 — 원본에 있나
|
||||
|
||||
품명(`krnPrdctNm`)·분류명(`prdctClsfcNoNm`) 글자 찾기.
|
||||
|
||||
| 자재 | 원본 | 비고 |
|
||||
|---|---|---|
|
||||
| 레미콘 | 없음 | 제외묶음 `ready_mixed_concrete` |
|
||||
| 철근(이형봉강) | 없음 | 제외묶음 `reinforcing_steel` |
|
||||
| 시멘트 | 없음 | 제외묶음에 없음 |
|
||||
| 골재(모래·자갈·쇄석) | 없음 | 제외묶음에 없음 |
|
||||
| 흄관 | 없음 | 제외묶음에 없음 |
|
||||
| 파형강관 | 없음 | 제외묶음에 없음 |
|
||||
| 합판 | 있음 — 건축 37물품(보통합판·내수합판·치장합판 등) | |
|
||||
| 각재 | 있음 — 건축 8물품(「각재, 외송」 등) | |
|
||||
| 돌망태(개비온) | 없음 | 제외묶음에 없음 |
|
||||
| 매트 | 직포매트(PET_Mat) 토목 — 사방 녹화·침식방지 매트 아님 · 섬유단열재 건축 | 녹화·거적 없음 |
|
||||
|
||||
- 없는 까닭 — 원본이 「시설공통자재」 목록뿐. 토목 분야 226물품도 와이어로프 · 콘크리트파일 · 나선형쉬스관 · 강널말뚝 · 록볼트 · 복공판 · 크롤러·점보 부품 등 특수·소모 자재.
|
||||
- 레미콘·시멘트·아스콘은 종합쇼핑몰(MAS·일반단가) 쪽 — `_meta.md` 원천 현황 표. 그 스냅숏은 로컬에 없음(`제외묶음` 사유 「shopping mall snapshot not locally stored」).
|
||||
- 철근·골재·흄관·파형강관·돌망태의 원천은 이 조사로 확인 못 함.
|
||||
|
||||
## 값 표본 30줄
|
||||
|
||||
무작위(씨앗 20260919). 마스터 값 · 원본 `prce`(채택 공시번호의 줄).
|
||||
|
||||
| 열쇠 | 이름 | 규격 | 단위 | 마스터 | 원본 | 공시일 | 판정 |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| 21061504 | 배수용 경질염화비닐 이음관 | 90˚YT관(LT), DRF D100 | 개 | 8800 | 8800 | 2026-04-20 | 같음 |
|
||||
| 20102199 | 연돌 | 굴뚝, CH477점검관, Check hole, Φ700 | 개 | 196800 | 196800 | 2024-10-17 | 같음 |
|
||||
| 24690953 | 하이텍케이블트레이부속품 | 분체도장, JOINER SET, W400x150H | m | 3863 | 3863 | 2026-04-20 | 같음 |
|
||||
| 20135951 | 용접스터드 | 용접스터드, 머리형, M19*155mm, 자동 | 개 | 827 | 827 | 2026-04-20 | 같음 |
|
||||
| 20105008 | 아티론(난연)AL | D80*15t | m | 2070 | 2070 | 2026-04-20 | 같음 |
|
||||
| 24178998 | 케이블트레이 | ST, W1000x100Hx2.3t(커버 미포함) | m | 19900 | 19900 | 2026-04-20 | 같음 |
|
||||
| 21650756 | 피난구 유도등(고휘도) | LED, 소형(양면), 60분용 | SET | 49447 | 49447 | 2026-04-20 | 같음 |
|
||||
| 22510394 | 스텐밴드 | D275 | 개 | 1394 | 1394 | 2026-04-20 | 같음 |
|
||||
| 24691026 | 하이텍케이블트레이부속품 | 분체도장, H. CROSS, W200x60H | m | 30386 | 30386 | 2026-04-20 | 같음 |
|
||||
| 22777741 | 플랙시블조인트 | 2.5L - 소방용 | m | 14340 | 14340 | 2026-04-20 | 같음 |
|
||||
| 20135552 | 고장력볼트 | 고장력볼트, F10T, M20*100mm | 조 | 1133 | 1133 | 2026-04-20 | 같음 |
|
||||
| 20160206 | 금속레일 | 금속레일, 황동, 압출, 180cm | m | 8000 | 8000 | 2026-04-20 | 같음 |
|
||||
| 22496407 | 절연저독성난연폴리올레핀시스케이블 | HFCO, 0.6/1kV, 3C 185mm² | m | 142039 | 142039 | 2026-04-20 | 같음 |
|
||||
| 20693493 | 섬유단열재 | 섬유단열재, 펠트, 밀도200kg/㎥, 75mm | ㎡ | 21570 | 21570 | 2026-04-20 | 같음 |
|
||||
| 20126889 | 나사식 강관제 관이음쇠 | 백붓싱 (나사) D20 | 개 | 900 | 900 | 2026-04-20 | 같음 |
|
||||
| 10036357 | 강재전선관용부품 | 파이프행거, 16C | 개 | 323 | 323 | 2026-04-20 | 같음 |
|
||||
| 20094812 | 사각 Diffuser | AL ND300 | 개 | 35720 | 35720 | 2026-04-20 | 같음 |
|
||||
| 20174273 | 케이블 직선접속재 | 레진주입형, 25kV, 1C, 500㎟ | kit | 220161 | 220161 | 2026-04-20 | 같음 |
|
||||
| 20102155 | 연돌 | 굴뚝, MT90˚연결티, Manifold tee, Φ3… | 개 | 84900 | 84900 | 2024-10-17 | 같음 |
|
||||
| 20684141 | 내열케이블 | F-FR-3, 25C 2.5mm² | m | 12552 | 12552 | 2026-04-20 | 같음 |
|
||||
| 10023585 | 육각볼트 | 육각볼트, M22*65 | 개 | 781 | 781 | 2026-04-20 | 같음 |
|
||||
| 20131107 | 감압밸브, 냉온수,플랜지,10KG | D32 | 개 | 328340 | 328340 | 2026-04-20 | 같음 |
|
||||
| 20969998 | 감압밸브, 냉온수, 플랜지,20KG | D32 | 개 | 665690 | 665690 | 2026-04-20 | 같음 |
|
||||
| 22073795 | 일반구조용압연강판 | 일반구조용압연강판, 2~3mm | 톤 | 855360 | 855360 | 2026-04-20 | 같음 |
|
||||
| 10023593 | 육각볼트 | 육각볼트, M22*120 | 개 | 1175 | 1175 | 2026-04-20 | 같음 |
|
||||
| 20145199 | 자기질타일 | 자기질타일, 석재타일, 환원, 300*300*20mm | ㎡ | 40000 | 40000 | 2026-04-20 | 같음 |
|
||||
| 10023429 | 육각볼트 | 육각볼트, M8*150 | 개 | 227 | 227 | 2025-10-23 | 같음 |
|
||||
| 10023705 | 육각볼트 | 육각볼트, 스테인리스, M18*40mm | 개 | 1303 | 1303 | 2026-04-20 | 같음 |
|
||||
| 21870903 | 고장력볼트 | 고장력볼트, TS볼트, M20×150mm | 조 | 1474 | 1474 | 2024-10-30 | 같음 |
|
||||
| 21650852 | 접지단자함 | STS, 1CCT | 개 | 84212 | 84212 | 2026-04-20 | 같음 |
|
||||
|
||||
- 이름 「스텐밴드」는 원문 앞 공백 두 칸 그대로(`" 스텐밴드"`) — 표에서만 눌림.
|
||||
@@ -0,0 +1,108 @@
|
||||
"""상용 적산 자료(ESTX 2026-07) 자재 → 재료_시중물가.json — 개발용 · 배포 전 판권 구매 뒤 갱신.
|
||||
|
||||
ESTX 자재 표 = StuffcDat(칸 뜻: 다산소프트/ESTX_값사전_자재노무기계.md).
|
||||
TC = 채택 · Cost1..6 = 출처 여섯 · Page1..6 = 면수.
|
||||
0 · 미저장 = 값 없음(null). 이름·규격은 원문 그대로(띄어쓰기·오자 포함). 코드 없는 빈 줄은 뺌.
|
||||
ESTX 에 대·중분류 칸이 없어 분류는 두지 않음.
|
||||
|
||||
쓰기: ./venv/Scripts/python.exe resources/master_data/scripts/build_재료_시중물가.py
|
||||
쓴 뒤 원본과 대조.
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import math
|
||||
import random
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).parent))
|
||||
from _migrate_base import dump_master # noqa: E402
|
||||
from compare_estx import ESTX, ROOT, SLOTS, Estx # noqa: E402
|
||||
|
||||
OUT = ROOT / "resources/master_data/재료_시중물가.json"
|
||||
|
||||
|
||||
def num(v):
|
||||
if not v:
|
||||
return None
|
||||
return int(v) if float(v).is_integer() else v
|
||||
|
||||
|
||||
def build(rows: list[dict]) -> list[dict]:
|
||||
out = []
|
||||
for r in sorted(rows, key=lambda r: r["Index"]):
|
||||
code = r.get("Code")
|
||||
if not code:
|
||||
continue
|
||||
price = {"채택": num(r.get("TC"))}
|
||||
pages = {}
|
||||
for i, slot in enumerate(SLOTS, 1):
|
||||
price[slot] = num(r.get(f"Cost{i}"))
|
||||
pages[slot] = r.get(f"Page{i}") or None
|
||||
out.append(
|
||||
{
|
||||
"열쇠": code,
|
||||
"이름": r.get("Name", ""),
|
||||
"규격": r.get("Size", ""),
|
||||
"단위": r.get("Unite", ""),
|
||||
"값": price,
|
||||
"면수": pages,
|
||||
"출처": f"시중물가 {code}",
|
||||
}
|
||||
)
|
||||
return out
|
||||
|
||||
|
||||
def check(rows: list[dict]) -> None:
|
||||
"""원본 대조 — 줄 수 · 출처별 값 합 · 표본 쉰 줄."""
|
||||
data = json.loads(OUT.read_text(encoding="utf-8"))
|
||||
got = {r["열쇠"]: r for r in data["줄"]}
|
||||
raw = {r["Code"]: r for r in rows if r.get("Code")}
|
||||
assert len(got) == len(data["줄"]) == len(raw), (len(got), len(raw))
|
||||
print(
|
||||
f"줄 {len(got)} = 원본 코드 있는 줄 {len(raw)} (코드 없는 빈 줄 {len(rows) - len(raw)} 뺌)"
|
||||
)
|
||||
for i, slot in enumerate(["채택", *SLOTS]):
|
||||
col = "TC" if i == 0 else f"Cost{i}"
|
||||
a = math.fsum(r.get(col) or 0 for r in raw.values())
|
||||
b = math.fsum(r["값"][slot] or 0 for r in got.values())
|
||||
n = sum(1 for r in got.values() if r["값"][slot] is not None)
|
||||
assert abs(a - b) < 1e-3, (slot, a, b)
|
||||
print(f" {slot}: 값 {n}줄 · 합 {b:,.1f} = 원본 {a:,.1f}")
|
||||
random.seed(20260719)
|
||||
for code in random.sample(sorted(raw), 50):
|
||||
r, g = raw[code], got[code]
|
||||
assert (g["이름"], g["규격"], g["단위"]) == (
|
||||
r.get("Name", ""),
|
||||
r.get("Size", ""),
|
||||
r.get("Unite", ""),
|
||||
)
|
||||
assert (g["값"]["채택"] or 0) == r.get("TC", 0)
|
||||
for i, slot in enumerate(SLOTS, 1):
|
||||
assert (g["값"][slot] or 0) == (r.get(f"Cost{i}") or 0), (code, slot)
|
||||
assert g["면수"][slot] == (r.get(f"Page{i}") or None), (code, slot)
|
||||
print(" 표본 50줄 이름·규격·단위·값 7·면수 6 같음")
|
||||
|
||||
|
||||
def main():
|
||||
rows = Estx().table("StuffcDat")
|
||||
head = {
|
||||
"그룹": "재료",
|
||||
"원문": "시중물가",
|
||||
"판": "2026-07",
|
||||
"원천": [
|
||||
{
|
||||
"경로": ESTX.relative_to(ROOT).as_posix(),
|
||||
"해시": hashlib.sha256(ESTX.read_bytes()).hexdigest(),
|
||||
"역할": "primary",
|
||||
}
|
||||
],
|
||||
"비고": ["다산소프트 EST 2026-07 자재 · 개발용 · 배포 전 판권 구매"],
|
||||
}
|
||||
dump_master(OUT, head, build(rows))
|
||||
check(rows)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -36,6 +36,7 @@ BOOKS = (
|
||||
"제조노임",
|
||||
"나라장터자재",
|
||||
"오피넷유가",
|
||||
"시중물가",
|
||||
"한국은행환율",
|
||||
"조달청제비율",
|
||||
"자체",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user