fix(m02-df): 36-2 마지막 대조 99.8% — 표 찾기 글은 대소문자까지 같아야(옛 find)
- 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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VBToTCGk5dqDKeXCEP3vhk
This commit is contained in:
@@ -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),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user