feat(m02-df): 36-2 덧 — 재료 조건 찾기 「검색어」 틀 · 표 범위 경계 규칙 칸
- Model CfMaterialRule field 「검색어」 + template(「레미콘 {a}-{b}-{c}」) + slots(자리마다 알약) · materialSources · depends · 흐름 따라가기에 자리 알약도
- Compute 재료 조건 찾기 검색어 = 틀에 자리 알약 값을 끼운 글(옛 fill)을 dv.slot_price 값으로 넘김(서버 찾기는 sub4)
- 표 찾기: 표 블록 「·범위규칙」 칸(줄마다 초과·이하 · 이상·이하 · 이상·미만 · 이하)을 Rule lookup · Compute _lookup 이 따름 · 없으면 초과·이하
- 변환: 재료 검색어 자리 = 검색어 틀 · scope 구분 · 상세구분 · 조건 찾기 요소로 들어가는 선은 안 만듦(depends 로 이음)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VBToTCGk5dqDKeXCEP3vhk
This commit is contained in:
@@ -216,9 +216,17 @@ def test_꼴_상자_선_규칙_배치() -> None:
|
||||
assert keyed and all(e["rule"]["field"] == "키" and "{" in e["ref"] for e in keyed)
|
||||
machine = [e for e in keyed if e["ref"].startswith("EQ:{기계}#")]
|
||||
assert machine and {e["rule"]["from"]["name"] for e in machine} == {"기계"}
|
||||
# 레미콘 {a}-{b}-{c} = 글 잇는 함수(&) → 재료 조건 찾기
|
||||
# 「MO:경유:{지역}」 = 원문번호 글을 잇는 함수(&) → 유가 조건 찾기
|
||||
assert any("&" in str(b.get("func")) for b in got["GC000267"]["flow"]["boxes"])
|
||||
# 레미콘 {a}-{b}-{c} = 재료 조건 찾기 field 검색어 · 틀 · 자리 셋 · 구분 범위(정함 · 선 없음)
|
||||
remi = got["GC000264"]["flow"]
|
||||
assert any("&" in str(b.get("func")) for b in remi["boxes"])
|
||||
found = [e for b in remi["boxes"] for e in (b.get("input") or {}).get("elements", [])]
|
||||
word = [e for e in found if (e.get("rule") or {}).get("field") == "검색어"]
|
||||
assert word and word[0]["rule"]["template"] == "레미콘 {굵은골재최대치수}-{강도}-{슬럼프}"
|
||||
assert [x["name"] for x in word[0]["rule"]["slots"]] == ["굵은골재최대치수", "강도", "슬럼프"]
|
||||
assert word[0]["scope"]["구분"] == "레미콘"
|
||||
groups = {b["id"] for b in remi["boxes"] if (b.get("input") or {}).get("mode") == "group"}
|
||||
assert not [ln for ln in remi["links"] if ln["to"]["box"] in groups]
|
||||
# 덧줄 줄.'이름' · 비목 합
|
||||
assert got["GF000185"]["notes"] == [] or all(
|
||||
not n.startswith("못 옮김") for n in got["GF000185"]["notes"]
|
||||
|
||||
@@ -895,3 +895,23 @@ def test_표_찾기_여럿이면_위_끝_가장_작은_줄() -> None:
|
||||
)
|
||||
assert got == [[11, None], [10, None], [9, None], [None, "표에 없는 조건"]]
|
||||
assert [list(cp._lookup(rule, block, {"x": x})) for x in (1, 30, 60, 70)] == got
|
||||
|
||||
|
||||
def test_표_찾기_범위_경계_규칙_칸() -> None:
|
||||
from M02_MasterTemplete.DataFlow import M02_DF_Compute as cp
|
||||
|
||||
head = ["h·아래", "h·위", "Q", "·범위규칙"]
|
||||
block = [head, [None, 10, 1, "이상·미만"], [10, 20, 2, "이상·미만"], [20, 30, 3, "이상·이하"]]
|
||||
rule = {
|
||||
"kind": "lookup",
|
||||
"conds": [{"col": "h", "from": {"box": "v", "name": "x"}}],
|
||||
"col": "Q",
|
||||
}
|
||||
xs = [5, 10, 20, 30, 31]
|
||||
got = _run(
|
||||
RULE
|
||||
+ f"const block = {json.dumps(block, ensure_ascii=False)};\nconst rule = {json.dumps(rule, ensure_ascii=False)};\n"
|
||||
f"out({json.dumps(xs)}.map(x => {{ const r = R.applyRule(rule, block, {{ x }}); return [r.value, r.why]; }}));"
|
||||
)
|
||||
assert got == [[1, None], [2, None], [3, None], [3, None], [None, "표에 없는 조건"]]
|
||||
assert [list(cp._lookup(rule, block, {"x": x})) for x in xs] == got
|
||||
|
||||
Reference in New Issue
Block a user