Merge remote-tracking branch 'origin/dev' into sub_laptop_3

This commit is contained in:
2026-09-20 21:58:46 +09:00
5 changed files with 1088 additions and 949 deletions
@@ -2,7 +2,7 @@
`scripts/build_자재품목_분류.py` 가 만든 표 — 손으로 고치지 않음.
- 구분 23 · 상세구분 96 · 미분류 1063 줄 (전체 30592 줄)
- 구분 23 · 상세구분 97 · 미분류 169 줄 (전체 30592 줄)
## 규칙
@@ -14,73 +14,77 @@
## 구분별 상세구분 (줄 수)
### 관·이음관 (7044)
### 관·이음관 (7045)
PE관 2906 · 이음쇠·부속 1003 · 주철관 828 · 강관 705 · PVC관 461 · 파형강관 417 · 유리섬유·FRP관 398 · 동관·스텐관 132 · 흄관 117 · 단열이중관 77
PE관 2906 · 이음쇠·부속 1003 · 주철관 828 · 강관 705 · PVC관 461 · 파형강관 417 · 유리섬유·FRP관 398 · 동관·스텐관 133 · 흄관 117 · 단열이중관 77
### 식생·종자 (5869)
### 식생·종자 (5989)
수목 5433 · 수목지주·보호 181 · 종자 105 · 잔디·지피 97 · 비료·토양개량 25 · 농약·약제 21 · 비료 7
수목 5532 · 수목지주·보호 181 · 종자 105 · 잔디·지피 97 · 농약·약제 42 · 비료·토양개량 25 · 비료 7
### 레미콘 (3203)
레미콘 3203
### 철근·강재 (1857)
### 철근·강재 (1870)
형강 703 · 철근 602 · 강판 262 · 구조용강관 147 · 철선 92 · 철망·와이어메쉬 51
형강 716 · 철근 602 · 강판 262 · 구조용강관 147 · 철선 92 · 철망·와이어메쉬 51
### 아스콘·포장 (1705)
아스콘 1479 · 포장블록 173 · 특수포장 30 · 아스팔트 13 · 투수포장재 10
### 안전시설 (1505)
### 안전시설 (1536)
표지판·지주 933 · 가드레일 427 · 낙석방지책 63 · 낙석방지·휀스 59 · 차선·방호 23
표지판·지주 933 · 가드레일 458 · 낙석방지책 63 · 낙석방지·휀스 59 · 차선·방호 23
### 볼트·앵커·철물 (1001)
볼트·너트 525 · 와이어로프·클램프 208 · 앵커 189 · 못 41 · 철근커플러 38
### 전기·통신 (799)
### 전기·통신 (900)
케이블·전선 312 · 판넬·차단기 163 · 전선관·트레이 134 · 조명·전등 133 · 부속·기타 57
케이블·전선 319 · 판넬·차단기 163 · 전선관·트레이 139 · 조명·전등 133 · 제어·계측기기 89 · 부속·기타 57
### 밸브·수도자재 (761)
밸브 597 · 수도계량기·유량계 79 · 스프링클러·호스 51 · 펌프 34
### 매트·토목섬유 (678)
돌망태 372 · 부직포·토목섬유 113 · 식생매트 64 · 돌망태·사방 63 · 매트 54 · 부직포 8 · 잔디보호매트 4
### 운송·용역 (675)
화물운임 552 · 시험·검사 62 · 폐기물 61
### 매트·토목섬유 (641)
### 기계·설비 (606)
돌망태 372 · 부직포·토목섬유 76 · 식생매트 64 · 돌망태·사방 63 · 매트 54 · 부직포 8 · 잔디보호매트 4
기계류 255 · 보일러·공조 172 · 놀이·운동·시설물 109 · 측정·시험기기 60 · 소방·가스 10
### 맨홀·수로·그레이팅 (599)
수로관 283 · 그레이팅 166 · 맨홀 150
### 재 (525)
### 시멘트·골재 (582)
경계석 401 · 조경석·자연석 124
골재 323 · 모르타르 188 · 시멘트 71
### 도료·방수·접착 (522)
### 도료·방수·접착 (557)
도료 249 · 접착·혼화 138 · 방수·실링 135
도료 249 · 접착·혼화 173 · 방수·실링 135
### 콘크리트제품 (484)
### 석재 (534)
말뚝·파일 223 · 경계석·블록 171 · PC구조물 90
경계석 410 · 조경석·자연석 124
### 시멘트·골재 (483)
### 콘크리트제품 (496)
골재 323 · 모르타르 101 · 시멘트 59
말뚝·파일 223 · 경계석·블록 171 · PC구조물 102
### 기계·설비 (462)
### 건축마감 (450)
보일러·공조 172 · 기계류 118 · 놀이·운동·시설물 109 · 측정·시험기기 53 · 소방·가스 10
천장·바닥·마감재 246 · 문·창·유리 123 · 타일·기와 66 · 위생기구 15
### 목재 (430)
@@ -90,13 +94,9 @@ PE관 2906 · 이음쇠·부속 1003 · 주철관 828 · 강관 705 · PVC관 46
단열재 282
### 건축마감 (279)
### 잡재료 (263)
문·창·유리 123 · 천장·바닥·마감재 75 · 타일·기와 66 · 위생기구 15
### 잡재료 (142)
소모품 92 · 용접·가스 28 · 고철·기타금속 11 · 화약 9 · 용수 2
소모품 189 · 고철·기타금속 31 · 용접·가스 28 · 화약 13 · 용수 2
### 교량·구조부속 (133)
@@ -367,6 +367,120 @@ R = [
"소모품",
r"장갑|걸레|비닐|페인트붓|^붓$|사포|브러[시쉬]|톱날|연마|숫돌|기름|오일|윤활|그리스|목탄|비누|현수막|끈|밧줄|포대|마대|볏짚|양생포|필름|테이프|와이어",
),
# 보강 — 미분류 꼬리 (기존 규칙 뒤에 붙임 · 앞 규칙 결과는 그대로)
(
"식생·종자",
"수목",
r"^(가우라|가랑코에|덴드롱|디기탈리스|루피너스|리아트리스|만데빌라|밀렛|블루세이지|비덴스|산파첸스|스토크|시클라멘|아로우카리아|아르메리아|안젤로니아|알리움|애니시다|임파첸스|이포메아|쥬리안|캄파놀라|크로톤|클레오메|토레니아|펜타스|포인세티아|한련화|장비와인핑크|꿀풀|좁쌀풀|향토초본류|향토목본류|초본류)$",
),
(
"식생·종자",
"농약·약제",
r"발근촉진제|수목도포제|전착제|카바액제|푸른솔|에코마인|증산억제제|황산동|질산칼[륨슘]|제1인산칼륨|요소|용과린|입단형성제|토양보습제|생명분|대지생명",
),
(
"식생·종자",
"수목",
r"녹매토|GP토|부엽토|배합토|인공토|복합토|에코토|생태복원토양|바크|세라소일|부엽식물|론생백|씨앗부착거적|피복재|법면안정재|천연섬유망",
),
("식생·종자", "수목", r"화분|그린폴|그린엣지|드립엣지|가로수보호판"),
("시멘트·골재", "시멘트", r"시멘트|슬래그|코우크스|SMT기층용결합재|프롬"),
(
"시멘트·골재",
"모르타르",
r"줄눈(샌드|채움)|PFM|고경도줄눈|알[칼카]리(성)?회복제|침투형알칼리|중성화|탄산화|염해|탄성보수재|방오코팅|RA-|MA(코트|콘|프라이몰)|폴리(코트|콘)|Recoh|균열(방지|저감)|바탕조정재|급결제|표면보호용|하이브리드섬유보강|나선형보강재|타스|워터스탑|몰[트더]|본크론|코타스|믹스|하이루|아루텍|에스몰|새지마|메토셀|비안새|뉴스타|탑스톤|HiCon|HI-PAT|VES|E-005S|JSM|고능축완결재|광촉매에폭시|에멀젼|파우더|필러|F-Tape|CERACOTE|포시몰|KL-화인|바니쉬|S\.R",
),
(
"도료·방수·접착",
"접착·혼화",
r"규산소다|염화칼슘|생석회|소석회|친환경수용성녹제거제|착색제|GRPS활성제",
),
(
"잡재료",
"소모품",
r"유압유|절삭유|LPG|무연분탄|복사용지|인쇄잉크|모조지|영상인화지|저장매체|USB메모리|건전지|배터리|축전지|에칠알콜|밀가루|요소수|카바이트|질소|탄산칼슘|산$|염산|인산|수산|알루미늄분말|알루미늄괴|넝마|새끼|빗자루|FILMCASSETTE|COUPLANT|형광자분|자분|침투통|비산먼지방지망|분진망|차광망|손전등",
),
(
"잡재료",
"고철·기타금속",
r"주물|동합금선|황동선|골함석|압착그립|연결체인|파일용접밴드|암타이밴드|천연밴드|나일론밴드|후크|지압판|웨지핀|케이지",
),
("잡재료", "화약", r"도폭선|미진동파쇄제|발파전석"),
("석재", "경계석", r"전석|해미석|인조석|게비온석|디딤석"),
("콘크리트제품", "PC구조물", r"비탈면보호블럭|블럭조임재|생태목틀|SSM|무소음트랜치|고무블럭"),
(
"안전시설",
"가드레일",
r"표지|칼라콘|슈퍼콘|제설함|윙카등|디자인형울타리|울타리|핸드레일|방충재|방현|외장재\(교량|휴먼보강캡",
),
(
"매트·토목섬유",
"부직포·토목섬유",
r"Geogrid|지오드레인|직포|BSA시트|프로텍션|펠트|RS강화|SRR고정구|부착망|고무판|고무바|라인벨트|완충고무",
),
(
"건축마감",
"천장·바닥·마감재",
r"판넬|PANEL|캐노피|CANOPY|ROOFSHEET|지붕판|슁글|합지벽지|폴리카보네이트|아크릴|포멕스|썬라이트|FRP|알루미늄(판|캡)|STS(헤어라인|원형봉)|강재판넬|T챤넬|엘브엣지|베이스(커버|찬넬)|보호금구|상부캡|워셔캡|주주|SS높이조절|QMR|K-SPAN|L형고정|스프라이스|보호캡|연결핀|JACK-BOLT|완충브래킷|Plate|PPP|평상|테이블|책상|야외|분리수거장|축대목|외부|내부|미끄럼방지",
),
(
"전기·통신",
"제어·계측기기",
r"콘덴서|UPS|MONITOR|TOUCHPANEL|LSUBoard|하이넬|USB|운전화면|DB$|자동탈착|MT자외선|ECTPROBE|FIELDINDICATOR|SURVEYMETER|MAGNETICCHUCK|MAGNETIC|JISA형시편|초음파탐촉자",
),
(
"기계·설비",
"기계류",
r"치즐|백호우티스|BIT|비트|TAPER|핸들패커|코어리프터|유압할암봉|에어타카|에어튜브|모듈러잭|로내대차|배기가스|재연소로|집진장치|필터백|유해가스촉매|건조기|캐스터블|래크|DUCT|FLEXIBLE|오수처리|미생물담체|다공성여재|정화침투|공드럼|홈메우기|파일안전덮개|일반고무판|데리네이트|폴리에스터펠트|내마모",
),
(
"건축마감",
"천장·바닥·마감재",
r"벽지|한지장판지|도배지|운용지|롤스크린|큐비클|세면대|캐비넷|APRON|수건|휴지걸이|컵대|옷걸이|거울|국기꽂이|베너기|차광막|오메가레일",
),
(
"도료·방수·접착",
"접착·혼화",
r"ERH-|SLC-|SC604A|레팔트|BACKUPROD|패칭재|알카리회복재|부식방지제|함침재|씰링용에폭시|전해질저감재|탄소저감재|재생첨가제|블랙터|원타임|ㄷ-보강재|주제$",
),
(
"잡재료",
"소모품",
r"방진|보안경|리어카|바퀴|쟈키|와샤|Screw|그라인더날|건축용주사기|거울원판|가루분|^풀$|호차|취부밴드|CruzerBlade|CM01-|프린터|COMPUTER|서버용PC",
),
(
"기계·설비",
"기계류",
r"에어햄머|롯드페카|샘풀|SPT|리밍셀|패커|P\.C콘|파일캡|연결판|고정판|분수용기기|고압분무|쿨링포그|정수필터|압력게이지|송관대차|관운반차|수골|대차|냉각장치|집진기|펄스유니트|인젝트|예열기|잔재처리|배풍기|배기관|유골|백연방지|다이옥신|단열문|제어함열처리",
),
(
"전기·통신",
"제어·계측기기",
r"Board|CPU|ROM교체|MMI|감전보호기|화재주수신기|점멸기|음향신호기|위성시보기|낙뢰|TIMER|전력량계|계전기|중앙감시반|조작반|모니터장치|안내시스템|재실감지|Modem|단자함|전용회선|CONT\(SCU\)",
),
(
"전기·통신",
"케이블·전선",
r"경동|연동연선|지선롯드|경완금|FC통신관|팔각테파관강주|근가밴드|랙크|Y캡",
),
("철근·강재", "형강", r"I\"형행가|열녀목|STSSR캡"),
("관·이음관", "동관·스텐관", r"^배관$"),
("전기·통신", "전선관·트레이", r"RACEWAY|PULLBOX|ELBOW|C-찬넬"),
(
"전기·통신",
"제어·계측기기",
r"카메라|렌즈|검지|제어장치|전원장치|서브랙|단자대|제어함체|철구조물\((신호|과속)",
),
(
"시멘트·골재",
"모르타르",
r"모르터|폴리머(콘크리트|결합재)|SS섬유재|충전재|SMT표층|스틸화이바|네오스톤",
),
("기계·설비", "측정·시험기기", r"압력계|ALARMDOSIMETER|UVMETER|TEMPILSTIK|MEGA-CHECK"),
("기계·설비", "기계류", r"권양기|공기주입기|벨트\(|악취방지|UV살균기|예취기|스핀틀|공기배기구"),
("식생·종자", "수목", r"촉촉소일|나무여과상자|만병초"),
("석재", "경계석", r"빗물머금석"),
("잡재료", "소모품", r"마킹펜|크레용|세척제|WHITEPAINT|보조통|암등|이단철개|열수축시트"),
]
RX = [(a, b, re.compile(c, re.I)) for a, b, c in R]
@@ -389,6 +503,7 @@ NAME = re.compile(r'"이름": "((?:[^"\\]|\\.)*)"')
SRC_ = re.compile(r'"출처": "((?:[^"\\]|\\.)*)"')
NOTE_OLD = "구분 · 상세구분 = 원문에 대·중분류 칸이 없어 비움(지어내지 않음)"
NOTE_NEW = "구분 · 상세구분 = 품명 글자 규칙으로 채움(scripts/build_자재품목_분류.py · 묶음 목록 ref/_묶음_자재품목.md) · 조달청 줄은 조달청 품명을 따름 · 못 가린 줄은 「미분류」"
NOTE_EMPTY = "이름 없음 — 원문 품명 칸이 빈 줄이라 분류하지 않음"
def q(s):
@@ -406,6 +521,8 @@ def main():
sc = json.loads('"' + SRC_.search(ln).group(1) + '"')
a, b = 분류(nm, sc)
ln = LINE.sub(lambda _: f'"구분": {q(a)}, "상세구분": {q(b)}', ln, count=1)
if not nm:
ln = ln.replace('"비고": null', f'"비고": "{NOTE_EMPTY}"', 1)
res.append((a, b, nm))
out.append(ln.replace(NOTE_OLD, NOTE_NEW))
assert len(res) == len(rows), (len(res), len(rows))
@@ -444,6 +561,14 @@ def 묶음_md(res):
return "\n".join(L)
def apply():
"""빌더가 JSON 을 새로 쓴 뒤 부름 — 두 칸 · 머리 비고를 다시 채움."""
new, res = main()
SRC.write_text(new, encoding="utf-8", newline="\n")
OUT_MD.write_text(묶음_md(res), encoding="utf-8", newline="\n")
return res
if __name__ == "__main__":
new, res = main()
if "--미분류" in sys.argv:
@@ -6,7 +6,7 @@ Cost2..5 = 물가지 넷 · Page2..5 = 면수. TC(채택) · Cost6(견적가)는
품명에 「관급」 인 줄의 Cost1(가격정보) = 조달청 관급 단가 — 「관급」 열 · 기간은 비고 「조달 26.7」.
그 밖의 줄에 남은 Cost1 은 출처가 조달인지 물가지인지 원문이 안 가름 — 값 열에 넣지 않고 비고 「가격정보 ○○」 로만.
0 · 미저장 = 값 없음(null). 이름·규격은 원문 그대로(띄어쓰기·오자 포함). 코드 없는 빈 줄은 뺌.
ESTX 에 대·중분류 칸이 없어 구분·상세구분은 비움(지어내지 않음).
ESTX 에 대·중분류 칸이 없어 구분·상세구분은 build_자재품목_분류.py 가 품명 글자 규칙으로 채움(빌더 끝에서 부름).
쓰기: ./venv/Scripts/python.exe resources/master_data/scripts/build_재료_자재품목.py
쓴 뒤 원본과 대조.
@@ -140,12 +140,15 @@ def main():
"관급 = 원문 「가격정보」 칸의 조달청 관급 단가(철근 · 레미콘 · 아스콘 · H형강 등) · 기간은 비고 「조달 26.7」",
"조달청에만 있는 품목 380 줄은 관급 열만 채움 — 출처 「자재품목 조달청 …」 · 원문번호는 _키대장.json 에만",
"원문 「가격정보」 칸에 시중 값이 남은 줄은 값 열에 넣지 않고 비고 「가격정보 ○○」 로만 둠 — 출처가 조달인지 물가지인지 원문이 안 가름",
"구분 · 상세구분 = 원문에 대·중분류 칸이 없어 비움(지어내지 않음)",
"구분 · 상세구분 = 품명 글자 규칙으로 채움(scripts/build_자재품목_분류.py · 묶음 목록 ref/_묶음_자재품목.md) · 조달청 줄은 조달청 품명을 따름 · 못 가린 줄은 「미분류」",
"면수 = 물가지 값의 원문 면수 · 화면에는 접어 둠",
],
}
dump_master(OUT, head, build(rows))
check(rows)
import build_자재품목_분류 as cls # noqa: E402
print("구분·상세구분 채움", len(cls.apply()), "")
print("새 틀로 받음", mk.adopt()) # 열쇠 → 키
File diff suppressed because it is too large Load Diff
@@ -119,3 +119,14 @@ def test_품셈재료_이름과_같은_품명_줄이_한_묶음():
p["이름"],
collections.Counter(x["구분"] for x in hit),
)
def test_이름_빈_줄은_비고에_까닭():
for x in ROWS:
if not x["이름"]:
assert x["구분"] == "미분류" and "이름 없음" in (x["비고"] or ""), x[""]
def test_빌더가_분류를_부름():
src = (MD / "scripts" / "build_재료_자재품목.py").read_text(encoding="utf-8")
assert "cls.apply()" in src