From 1ee16683683a1cb4b252c070b7033e83b30253f2 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Fri, 2 Oct 2026 01:34:53 +0900 Subject: [PATCH] =?UTF-8?q?fix(m02-df):=2036-2=20=EB=A7=88=EC=A7=80?= =?UTF-8?q?=EB=A7=89=20=EB=8C=80=EC=A1=B0=2099.8%=20=E2=80=94=20=ED=91=9C?= =?UTF-8?q?=20=EC=B0=BE=EA=B8=B0=20=EA=B8=80=EC=9D=80=20=EB=8C=80=EC=86=8C?= =?UTF-8?q?=EB=AC=B8=EC=9E=90=EA=B9=8C=EC=A7=80=20=EA=B0=99=EC=95=84?= =?UTF-8?q?=EC=95=BC(=EC=98=9B=20find)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Rule lookup 같음 = 글끼리 LEN + FIND(대소문자 가림) · Compute _lookup = _exact(글은 그대로 비교) — 「t_2」 「T_2」 · 「e」 「E」 줄이 둘 다 맞던 것 - 시험 test_m02_df_model 36 - 전수(sub4 범위규칙 칸 · 검색어 찾기 · 재료 입력 받은 뒤): 시험입력 1,469/1,472(99.8%) · 기본 입력 1,466(99.6%) · 남은 = 자료 빈 단가 · 없는 품목에서 옛 셈은 식째 비움 · 흐름은 0 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01VBToTCGk5dqDKeXCEP3vhk --- M02_MasterTemplete/DataFlow/M02_DF_Compute.py | 7 ++++++- M02_MasterTemplete/DataFlow/M02_DF_Rule.ts | 8 +++++++- resources/tester/test_m02_df_model.py | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/M02_MasterTemplete/DataFlow/M02_DF_Compute.py b/M02_MasterTemplete/DataFlow/M02_DF_Compute.py index 01f9c20c8..cef97b616 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_Compute.py +++ b/M02_MasterTemplete/DataFlow/M02_DF_Compute.py @@ -326,6 +326,11 @@ def _same(a: Any, b: Any) -> bool: return False +def _exact(a: Any, b: Any) -> bool: + """표 찾기 같음 — 글끼리는 대소문자까지(옛 find · Rule lookup FIND) · 그 밖은 엑셀 「=」.""" + return a == b if isinstance(a, str) and isinstance(b, str) else _same(a, b) + + def _compare(a: Any, op: str, b: Any) -> bool: if op in ("=", "≠"): return _same(a, b) == (op == "=") @@ -371,7 +376,7 @@ def _lookup(rule: dict, block: Any, conds: dict) -> tuple[Any, str | None]: col, want = str(c.get("col")), _cond_of(conds, c.get("from") or {}) if col in head: i = head.index(col) - tests.append(lambda row, i=i, want=want: row[i] is None or _same(row[i], want)) + tests.append(lambda row, i=i, want=want: row[i] is None or _exact(row[i], want)) elif col + dv.RANGE_LOW in head and col + dv.RANGE_HIGH in head: lo, hi, x = ( head.index(col + dv.RANGE_LOW), diff --git a/M02_MasterTemplete/DataFlow/M02_DF_Rule.ts b/M02_MasterTemplete/DataFlow/M02_DF_Rule.ts index df684c2d3..d5ee5b516 100644 --- a/M02_MasterTemplete/DataFlow/M02_DF_Rule.ts +++ b/M02_MasterTemplete/DataFlow/M02_DF_Rule.ts @@ -204,7 +204,13 @@ function lookup( const same = at(c.col); const low = at(`${c.col}·아래`); const high = at(`${c.col}·위`); - if (same) tests.push((r) => `OR(ISBLANK(${same}${r}),${same}${r}=${ref})`); + // 글끼리는 대소문자까지 같아야 맞음(옛 find · 「t_2」 ≠ 「T_2」) — FIND 는 대소문자를 가림 + if (same) + tests.push( + (r) => + `OR(ISBLANK(${same}${r}),IF(AND(ISTEXT(${same}${r}),ISTEXT(${ref})),` + + `AND(LEN(${same}${r})=LEN(${ref}),ISNUMBER(FIND(${ref},${same}${r}))),${same}${r}=${ref}))`, + ); else if (low && high) { ups.push(high); tests.push( diff --git a/resources/tester/test_m02_df_model.py b/resources/tester/test_m02_df_model.py index b3dbefa41..ad50754b2 100644 --- a/resources/tester/test_m02_df_model.py +++ b/resources/tester/test_m02_df_model.py @@ -949,3 +949,22 @@ def test_화면_값_물음_조건_찾기_인력기계유가_검색어_틀_다른 designs = {"기계": "0201-0020", "지역": "전국평균"} assert ["*", "기계", None, {"key": "GC000270", "designs": designs}, False] in qs assert server == {"노무비": 123} # 서버가 셈한 다른 로직 출력이 있으면 그것 + + +def test_표_찾기_글은_대소문자까지_같아야() -> None: + from M02_MasterTemplete.DataFlow import M02_DF_Compute as cp + + block = [["구분", "값"], ["T_2", 1], ["t_2", 3], ["e", 0.96], ["E", 0.45]] + rule = { + "kind": "lookup", + "conds": [{"col": "구분", "from": {"box": "v", "name": "g"}}], + "col": "값", + } + gs = ["t_2", "T_2", "E", "e", "x"] + got = _run( + RULE + + f"const block = {json.dumps(block)};\nconst rule = {json.dumps(rule, ensure_ascii=False)};\n" + f"out({json.dumps(gs)}.map(g => {{ const r = R.applyRule(rule, block, {{ g }}); return [r.value, r.why]; }}));" + ) + assert got == [[3, None], [1, None], [0.45, None], [0.96, None], [None, "표에 없는 조건"]] + assert [list(cp._lookup(rule, block, {"g": g})) for g in gs] == got