knowledge(마스터): 조달청 2022하 시설자재가격 받기 · 표 빌더 · 12 재료·없는 재료 대조
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ
This commit is contained in:
@@ -135,3 +135,12 @@
|
||||
- 유가전력 — 휘발유·경유 새 판 반영 없음.
|
||||
- 원본 받기 — 문서 URL(게시글 uuid · seq)을 반기마다 `collect_cost_sources.py` 상수에 손으로 갱신.
|
||||
- 판 최신 여부 표 없음 — `resources/tester/test_master_sources.py` 가 가리키는 `resources/data_master_sources/` 가 이 저장소에 없음.
|
||||
|
||||
## 시설자재가격 (지식DB 표 · 마스터 아님)
|
||||
|
||||
| 항목 | 값 |
|
||||
| --- | --- |
|
||||
| 출처 | 조달청 시설공사 자료실 「시설자재 가격정보공개」 첨부 xlsx · `원가계산/자재단가/조달청_시설자재_22하/` |
|
||||
| 받는 법 | pps.go.kr 시설공사 게시판(key=00038)에서 글 찾아 첨부 내려받기(키 불필요) |
|
||||
| 주기 | 연 2회(상·하반기) — 게시판 최신 반기 글은 2022 하반기 |
|
||||
| 빌더 | `scripts/build_시설자재가격.py` (csv 씀 · `--count` 로 재료 글자 수 셈) |
|
||||
|
||||
@@ -42,3 +42,26 @@
|
||||
|
||||
- `resources/knowledge/original/원가계산/자재단가/조달청_시설자재/시설자재가격_21하.zip`
|
||||
- `resources/knowledge/original/원가계산/자재단가/경남교육청_일위대가/일위대가_1.xlsx` (건축) · `일위대가_2.xlsx` (토목)
|
||||
|
||||
## 최신 반기 자료 대조 (조달청 2022 하반기 시설공통자재)
|
||||
|
||||
- 자료 — 게시글 bbsSn=2209300017 · `조달청_시설자재_22하/` · 표 `시설공통자재_22하.csv` 6,950줄(빌더 `scripts/build_시설자재가격.py`).
|
||||
- 이 게시판의 반기 자료는 2022 하반기가 마지막 — 2023 이후는 게시글 없음(2026 수시조사 글만).
|
||||
|
||||
| 12 재료 | 자료 안 줄 수 (품명·규격에 글자 포함) |
|
||||
|---|---|
|
||||
| 합판 | 37 |
|
||||
| 각재 | 8 |
|
||||
| 건설용거푸집(유로폼) | 24 |
|
||||
| 비계 | 7 |
|
||||
| 클램프 | 18 |
|
||||
| 철선 | 13 |
|
||||
| 못 | 39 (짧은 글자라 딴 품명 섞임) |
|
||||
| 동바리 · 파이프서포트 · 폼타이 · 유공관 · 종자 · 방부 · 잡석 | 0 |
|
||||
|
||||
| `_없는_재료.md` 111 줄 | 결과 |
|
||||
|---|---|
|
||||
| 자료에 있음 (이름 글자 포함) | 에폭시 2 · 보호막 1 · 실리콘 11 · 노즐 2 · 아스팔트싱글 3 |
|
||||
| 나머지 | 없음 (2글자 이하 이름은 품명 전체 일치만 봄) |
|
||||
|
||||
- 위 줄은 이름 글자만 겹침 — 종류·규격 대조는 안 함. 마스터에 넣지 않음.
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""조달청 시설공통자재 xlsx(4분야) → 품명·규격·단위·금액 csv (지식DB 폴더 안). 마스터 JSON 은 안 만짐.
|
||||
|
||||
쓰기: ./venv/Scripts/python.exe resources/master_data/scripts/build_시설자재가격.py
|
||||
세기: ... build_시설자재가격.py --count (12 재료 · ref/_없는_재료.md 이름이 자료에 몇 줄인지 출력)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
import openpyxl
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
DIR = ROOT / "resources/knowledge/original/원가계산/자재단가/조달청_시설자재_22하"
|
||||
OUT = DIR / "시설공통자재_22하.csv"
|
||||
MISSING = ROOT / "resources/master_data/ref/_없는_재료.md"
|
||||
TWELVE = [
|
||||
"합판",
|
||||
"각재",
|
||||
"건설용거푸집",
|
||||
"동바리",
|
||||
"파이프서포트",
|
||||
"비계",
|
||||
"클램프",
|
||||
"철선",
|
||||
"못",
|
||||
"폼타이",
|
||||
"유공관",
|
||||
"종자",
|
||||
"방부",
|
||||
"잡석",
|
||||
]
|
||||
|
||||
|
||||
def rows():
|
||||
for f in sorted(DIR.glob("시설공통자재_*.xlsx")):
|
||||
ws = openpyxl.load_workbook(f, read_only=True, data_only=True).worksheets[0]
|
||||
head = None
|
||||
for r in ws.iter_rows(values_only=True):
|
||||
if head is None:
|
||||
head = r if r and r[0] == "물품분류번호" else None
|
||||
continue
|
||||
if r[2]:
|
||||
yield (
|
||||
f.stem.split("_")[1],
|
||||
r[2],
|
||||
r[3] or "",
|
||||
r[4] or "",
|
||||
str(r[5] or "").replace(",", ""),
|
||||
)
|
||||
|
||||
|
||||
def count(data, words):
|
||||
return {w: sum(1 for d in data if w in f"{d[1]}{d[2]}") for w in words}
|
||||
|
||||
|
||||
def main():
|
||||
data = list(rows())
|
||||
if "--count" in sys.argv:
|
||||
print(len(data), "줄")
|
||||
for w, n in count(data, TWELVE).items():
|
||||
print("12재료", w, n)
|
||||
for m in re.finditer(
|
||||
r"^\| MP\d+ \| ([^|]+?) \|", MISSING.read_text(encoding="utf-8"), re.M
|
||||
):
|
||||
name = re.sub(r"\(.*", "", m.group(1)).strip()
|
||||
n = (
|
||||
count(data, [name])[name]
|
||||
if len(name) >= 3
|
||||
else sum(1 for d in data if d[1] == name)
|
||||
) # 짧은 이름은 품명 전체 일치만
|
||||
print(f"없는재료 {name} {n}")
|
||||
return
|
||||
with OUT.open("w", encoding="utf-8-sig", newline="") as fp:
|
||||
w = csv.writer(fp)
|
||||
w.writerow(["분야", "품명", "규격", "단위", "금액"])
|
||||
w.writerows(data)
|
||||
print(OUT.name, len(data), "줄")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user