From fa50fe05d389e2615247cf1f2a69c5d939913ad8 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Wed, 4 Nov 2026 22:45:49 +0900 Subject: [PATCH] =?UTF-8?q?feat(785-6):=20=EB=B8=94=EB=A1=9D=20=EC=B9=A0?= =?UTF-8?q?=20=EC=83=88=20=ED=8C=90=EC=A0=95=20=E2=80=94=20Marks=20?= =?UTF-8?q?=EA=B0=80=20Make.judged=20=EC=A0=80=EC=9E=A5=EB=B3=B8=EC=9D=84?= =?UTF-8?q?=20=EC=9D=BD=EC=9D=8C=20=C2=B7=20SheetMap=20=EC=A0=9C=EC=95=88?= =?UTF-8?q?=20=EC=B9=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - M02_Hopyo_Marks.py: 블록 판정 = M02_Hopyo_Make.judged(folder, key) 파생 저장본(785-5) · 고를수 실음 · 저장본 없으면 옛 맞춤셈 판정(785-7 에서 걷음) - logic/Hopyo_SheetMap.ts: 기초로 풂 · 기초+덧 = 초록 · 줄 조합 · 고를 것 n = 파랑 · 일위대가 밖 글 - test_642_6_screen.py: 블록 칠 새 판정 · Marks 옛 길 대체 시험 Co-Authored-By: Claude Opus 5.5 --- M02_MasterTemplete/M02_Hopyo_Marks.py | 22 ++++++++-- .../M02_MasterTemplete_Hopyo_SheetMap.ts | 12 ++++++ resources/tester/test_642_6_screen.py | 43 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) diff --git a/M02_MasterTemplete/M02_Hopyo_Marks.py b/M02_MasterTemplete/M02_Hopyo_Marks.py index 5c852ca67..82ffd9ecf 100644 --- a/M02_MasterTemplete/M02_Hopyo_Marks.py +++ b/M02_MasterTemplete/M02_Hopyo_Marks.py @@ -1,7 +1,9 @@ """M02 불러오기 엑셀 보기 하이라이트 재료(PLAN 779-2 · 요구서 621 3장 5) — 읽기만(파일 · storage 변화 0). -블록 `[{번, 판정, SK, 갈래, 못옮김, 부름}]` = 단가산출 만들기 결과(`Sangeun.made`) + 맞춤셈 캐시(`Fit.result`)를 읽기만. -- `판정` = 그 블록을 부르는 첫 줄의 맞춤셈 판정 상태(맞음 · 다른 점 · 후보 …) · 안 불리거나 셈 전이면 None +블록 `[{번, 판정, 고를수, SK, 갈래, 못옮김, 부름}]` = 단가산출 만들기 결과(`Sangeun.made`) + 블록 판정을 읽기만. +- `판정` = 새 블록 판정(785-6 · `M02_Hopyo_Make.judged` 파생 저장본 = 기초로 풂 · 기초+덧 · 줄 조합 · 고를 것 · + `고를수`) · 그 저장본이 없으면(785-5 전 · 셈 전) 옛 판정 = 부르는 첫 줄의 맞춤셈 상태(맞음 · 다른 점 · 후보 …) · + 안 불리거나 셈 전이면 None - `부름` = 부르는 호표 번 [] = 일위대가 밖(780-1) · `어긋남` · `줄` = 모든 블록(밖 포함) - `SK` = 만든 SK 키 · 없으면 None / `갈래` · `못옮김` = 그 SK 본뜬(출처별) · 없으면 None · [] 줄 상태는 `Match.view` 호표마다 `줄상태 [[차례, 상태, 체크]]` · `만든`(SC 키)로 실려 감. @@ -120,6 +122,16 @@ def lines(block: dict[str, Any], units: hunits.Units) -> list[list[Any]]: return out +def _judged(folder: Path, key: str) -> dict[int, dict[str, Any]] | None: + """새 블록 판정 `{번: {판정, 고를수}}`(785-5 파생 저장본) · 없으면 None(셈 전 · 785-5 전).""" + try: + from M02_MasterTemplete import M02_Hopyo_Make as make + except ImportError: # ponytail: 785-5 Make 오기 전 = 옛 맞춤셈 판정 · 785-7 에서 걷음 + return None + got = make.judged(folder, key) + return None if got is None else {int(k): v for k, v in got.items()} + + def blocks(folder: Path, key: str, to: Path | None = None) -> list[dict[str, Any]]: """블록마다 `{번, 판정, SK, 갈래, 못옮김, 어긋남, 줄}` — `to` = 만든 SK 를 볼 층(없으면 파일 층).""" folder, to = Path(folder), Path(to or folder) @@ -130,6 +142,7 @@ def blocks(folder: Path, key: str, to: Path | None = None) -> list[dict[str, Any all_, first = sangeun.calls(hp) units = hunits.Units() if all_ else None call = sangeun.callers(hp) + judge = _judged(folder, key) out = [] for no in sorted(all_): line = first.get(no) @@ -137,10 +150,13 @@ def blocks(folder: Path, key: str, to: Path | None = None) -> list[dict[str, Any mark = sangeun.mark(key, no) sk = have.get(mark) origin = _origin(to, sk, mark, here) if sk else {} + new = (judge or {}).get(no) or {} + old = ((entry or {}).get("판정") or {}).get("상태") out.append( { "번": no, - "판정": ((entry or {}).get("판정") or {}).get("상태"), + "판정": new.get("판정") if judge is not None else old, + "고를수": new.get("고를수"), "SK": sk, "갈래": origin.get("갈래"), "못옮김": origin.get("못옮김") or [], diff --git a/M02_MasterTemplete/logic/M02_MasterTemplete_Hopyo_SheetMap.ts b/M02_MasterTemplete/logic/M02_MasterTemplete_Hopyo_SheetMap.ts index 2bc8098bf..f515ddd3e 100644 --- a/M02_MasterTemplete/logic/M02_MasterTemplete_Hopyo_SheetMap.ts +++ b/M02_MasterTemplete/logic/M02_MasterTemplete_Hopyo_SheetMap.ts @@ -43,7 +43,10 @@ export interface BriefMarks { } export interface BlockMark { 번: number; + /** 새 블록 판정(785-6 · 기초로 풂 · 기초+덧 · 줄 조합 · 고를 것) › 옛 부르는 첫 줄 맞춤셈 상태 */ 판정: string | null; + 고를수?: number | null; + 부름?: number[]; SK: string | null; 갈래: string | null; 못옮김: unknown[]; @@ -115,6 +118,9 @@ export function lineTone( export const worst = (tones: Tone[]): Tone => tones.reduce((a, b) => (RANK[b] > RANK[a] ? b : a), "muted"); +/** 새 블록 판정 칠(785-6) — 확인 전이라 제안 칠만(확인함 = 만든 SK) */ +const BLOCK_TONE: Record = { "기초로 풂": "success", "기초+덧": "success", "줄 조합": "info", "고를 것": "info" }; // prettier-ignore + /** 블록 칠 — 만든 SK 갈래 › 없으면 부르는 첫 줄 판정 「예상」 · 판정 없음 = 「일위대가 밖」 */ export function blockTone(m: BlockMark | undefined): { tone: Tone; 글: string } { if (!m) return { tone: "muted", 글: "안 불림" }; @@ -124,6 +130,12 @@ export function blockTone(m: BlockMark | undefined): { tone: Tone; 글: string } return { tone, 글: `${m.SK} · ${m.갈래 ?? ""}${lost ? ` · 못옮김 ${lost}` : ""}` }; } if (!m.판정) return { tone: "muted", 글: "일위대가 밖" }; // 부르는 일위대가 줄 없음(780-2) + const fresh = BLOCK_TONE[m.판정]; + if (fresh) { + const n = m.판정 === "고를 것" && m.고를수 ? ` ${m.고를수}` : ""; + const out = m.부름 && !m.부름.length ? " · 일위대가 밖" : ""; + return { tone: fresh, 글: `제안 — ${m.판정}${n}${out}` }; + } const tone: Tone = m.판정 === "맞음" ? "success" : m.판정 === "다른 점" ? "warning" : "info"; return { tone, 글: `예상 — 부르는 첫 줄 ${m.판정}` }; } diff --git a/resources/tester/test_642_6_screen.py b/resources/tester/test_642_6_screen.py index 206e30fd5..ae563978c 100644 --- a/resources/tester/test_642_6_screen.py +++ b/resources/tester/test_642_6_screen.py @@ -224,3 +224,46 @@ def test_고름바꾸면_확인풀림_칠(judged): assert got[3] == "success" assert got[4]["호표"]["1"]["0"]["확인"] is False assert got[5] == "danger" and got[6] == "info" + + +def test_블록칠_새판정(monkeypatch): + """SheetMap 블록 칠 = 새 판정(제안 칠) · Marks = `Make.judged` 저장본 › 없으면 옛 판정.""" + from M02_MasterTemplete import M02_Hopyo_Marks as mk + from resources.tester.test_779_4_sheet_map import _node + + def mark(v, n=None, call=(1,)): + return { + "번": 1, + "판정": v, + "고를수": n, + "부름": list(call), + "SK": None, + "갈래": None, + "못옮김": [], + } + + got = _node( + { + "blockTones": [ + mark("기초로 풂"), + mark("고를 것", 3), + mark("줄 조합", call=()), + {**mark("고를 것", 2), "SK": "SK-1", "갈래": "기초"}, + mark("맞음"), + ] + } + )["blocks"] + assert [b["tone"] for b in got] == ["success", "info", "info", "success", "success"] + assert got[1]["글"] == "제안 — 고를 것 3" and got[2]["글"] == "제안 — 줄 조합 · 일위대가 밖" + assert mk._judged(Path("."), "x") is None # 785-5 Make 전 = 옛 길 + + class Make: + @staticmethod + def judged(folder, key): + return {"10": {"판정": "기초로 풂", "고를수": 0}} + + import sys + + monkeypatch.setitem(sys.modules, "M02_MasterTemplete.M02_Hopyo_Make", Make) + monkeypatch.setattr(sys.modules["M02_MasterTemplete"], "M02_Hopyo_Make", Make, raising=False) + assert mk._judged(Path("."), "x") == {10: {"판정": "기초로 풂", "고를수": 0}}