fix(845-2): sub2 단위 받은 뒤 표시 셋 — 「줄 따름」 = 고른 표 줄 단위 · 단위 TeX 글 안전(%) · 노임 원/일 × 인 = 원/인
- 「줄 따름」 표 값 = 지금 조건으로 고른 표 줄의 「단위」 칸(rowUnit · 화면 캐시 표 읽기) — 오른쪽 · 왼쪽 값 칸 · 수량 꼬리표 - 식 줄 결과 단위 = TeX 글 안전(「%」 가 주석으로 먹혀 「가산 = 0 %」 가 안 보이던 것) - 단가 분모가 수량 단위와 같은 뜻이면 수량 글로(원/일 × 인 → 원/인 · ㎏ ↔ kg · ℓ ↔ L) · kWh = ㎾h · 기계 칸 전력 = ㎾h/hr(845-1 문서 단위와 같게) - 왼쪽 만약이 수 하나로 접힌 식 줄 = 단위 남김 - 전수(845-1 단위 채움 뒤) 표시 탓 0 · 시험 test_845_2_unit_show 줄 따름 · % · 원/인 더함 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -47,7 +47,7 @@ import {
|
||||
tableAlias,
|
||||
unswap,
|
||||
} from "../common_util/common_util_line_stack_pick";
|
||||
import { varUnit } from "../common_util/common_util_line_stack_unit";
|
||||
import { shownUnitOf, type TableLook } from "../common_util/common_util_line_stack_unit";
|
||||
import { createUnitPick, NO_UNIT } from "../M02_MasterTemplete/DataFlow/M02_DF_UnitPick";
|
||||
import { reach } from "./formula_doc_render";
|
||||
import { attachDrag } from "./line_stack_drag";
|
||||
@@ -80,6 +80,8 @@ export interface EditHooks {
|
||||
calc?: (doc: FormulaDoc, given: Record<string, unknown>) => DocAnswer;
|
||||
/** 842-3 그 기계 줄 인력 · 잡품 목록(기본값 바탕) */
|
||||
lists?: (given: Record<string, unknown>) => Record<string, unknown> | null;
|
||||
/** 845-2 표 한 칸 읽기(캐시) — 「줄 따름」 값의 고른 줄 단위 */
|
||||
look?: TableLook;
|
||||
}
|
||||
|
||||
const field = (
|
||||
@@ -325,8 +327,10 @@ function qtyBox(
|
||||
// 838-3 공식 · 표 값 묶음에 이미 보이는 기호 = 줄 쪽 표 칩 걷음(묶음에서 고름) · 묶음에 없으면 줄에서 고름
|
||||
const inBlock = h.items.some((it) => it.줄.some((l) => l.꼴 === "공식" && l.기호.includes(text)));
|
||||
const tag = v && !inBlock ? sourceTag(h, text, v.연결) : null;
|
||||
if (tag && isNum(val))
|
||||
tag.title = `${eqText(val)}${varUnit(v) ? ` ${varUnit(v)}` : ""} — ${tag.title || tag.textContent}`;
|
||||
if (tag && isNum(val)) {
|
||||
const u = shownUnitOf(v, (h.answer.값 ?? {}) as Record<string, unknown>, h.look);
|
||||
tag.title = `${eqText(val)}${u ? ` ${u}` : ""} — ${tag.title || tag.textContent}`;
|
||||
}
|
||||
return el("span", { className: "lstk-qty", children: tag ? [f, tag] : [f] });
|
||||
}
|
||||
|
||||
|
||||
@@ -48,10 +48,10 @@ import {
|
||||
machineUnit,
|
||||
moneyUnits,
|
||||
unitText,
|
||||
varUnit,
|
||||
shownUnitOf,
|
||||
} from "../common_util/common_util_line_stack_unit";
|
||||
import { partName } from "../common_util/common_util_machine_symbol_name";
|
||||
import { katexNode, symTex, tex, valTex, type TexCtx } from "./line_stack_tex";
|
||||
import { katexNode, symTex, tex, txt, valTex, type TexCtx } from "./line_stack_tex";
|
||||
import { lt } from "./line_stack_text";
|
||||
|
||||
type Cols = Partial<Record<"sum" | (typeof COSTS)[number], number>>;
|
||||
@@ -127,7 +127,8 @@ function rows(
|
||||
const shown = new Set(reach(doc, vals)); // 지금 탄 갈래로 닿는 기호만
|
||||
const steps = lineMap(doc);
|
||||
const place = placeNames(doc, stackOf(doc)); // 번지 읽는 이름(804-5)
|
||||
const unit = (id: string): string => varUnit(vars.get(id)); // 845-2 단위 규칙 한 벌
|
||||
const look = (p: Record<string, unknown>): unknown => h.cache.links.table(p);
|
||||
const unit = (id: string): string => shownUnitOf(vars.get(id), vals, look); // 845-2 단위 규칙 한 벌(줄 따름 = 고른 표 줄 단위)
|
||||
const alias = tableAlias(doc); // 표 값 기호 화면 이름(요구 683)
|
||||
const machine = doc.부품?.갈래 === "기계경비식"; // 845-2 한 줄 분수 한 층(중간 줄로 나눔)
|
||||
const taken = new Set([...vars.keys(), ...lines.keys(), ...Object.values(alias)]);
|
||||
@@ -144,7 +145,7 @@ function rows(
|
||||
more: Partial<TexCtx>,
|
||||
): (string | HTMLElement)[] => {
|
||||
const res = isNum(v)
|
||||
? katexNode(`${code(id) ? String(v) : valTex(v)}\\ ${u ? `\\text{${u}}` : ""}`)
|
||||
? katexNode(`${code(id) ? String(v) : valTex(v)}\\ ${u ? txt(u) : ""}`) // 단위 글 = TeX 안전(「%」 주석 · 「^」 첨자 막음)
|
||||
: typeof v === "string" // 글 값(기계 원문번호 등 · 838-3) = 그 글 · 기계면 이름
|
||||
? el("span", { text: machineText(v, () => h.redraw?.()) ?? v })
|
||||
: missing(a, id);
|
||||
|
||||
@@ -44,7 +44,7 @@ import {
|
||||
pickCell,
|
||||
tableAlias,
|
||||
} from "../common_util/common_util_line_stack_pick";
|
||||
import { unitText, varUnit } from "../common_util/common_util_line_stack_unit";
|
||||
import { shownUnitOf, unitText } from "../common_util/common_util_line_stack_unit";
|
||||
import { openFindPicker } from "../M02_MasterTemplete/M02_MasterTemplete_Find_Pick";
|
||||
import type { EditHooks } from "./line_stack_edit";
|
||||
import { openTablePick } from "./line_stack_pick";
|
||||
@@ -157,14 +157,16 @@ export function buildBlock(
|
||||
const show = (id: string): string => alias[id] ?? id;
|
||||
const shownText = (t: string): string => aliasText(t, alias);
|
||||
const realText = (t: string): string => aliasText(t, alias, true);
|
||||
/** 845-2 단위 한 벌 — 변수 단위 › 기계 칸 › 고른 표 줄 단위(줄 따름) */
|
||||
const unitOf = (id: string): string => shownUnitOf(vars.get(id), vals, h.look);
|
||||
const valText = (id: string): string => {
|
||||
const v = vals[id];
|
||||
const mach = machineText(v, () => h.change(() => undefined)); // 838-3 기계 원문번호 = 이름
|
||||
if (mach) return mach;
|
||||
if (isNum(v) || typeof v === "string") return `${eqText(v)} ${varUnit(vars.get(id))}`.trim();
|
||||
if (isNum(v) || typeof v === "string") return `${eqText(v)} ${unitOf(id)}`.trim();
|
||||
if (v && typeof v === "object") {
|
||||
const key = vars.get(id)?.연결?.키; // 845-2 묶음 값 = 그 문서 결과 단위(원/시간 등)
|
||||
const u = varUnit(vars.get(id)) || unitText(key ? h.subDoc(key)?.결과단위 : "");
|
||||
const u = unitOf(id) || unitText(key ? h.subDoc(key)?.결과단위 : "");
|
||||
return `${["노무비", "재료비", "경비"].map((c) => `${c} ${eqText((v as Record<string, unknown>)[c])}`).join(" · ")} ${u}`.trim(); // prettier-ignore
|
||||
}
|
||||
return `— ${h.answer.빈값?.[id] ?? ""}`.trim();
|
||||
@@ -340,7 +342,9 @@ export function buildBlock(
|
||||
...(expr ? [tap(el("span", { className: "lstk-expr", text: shownText(expr) }), id)] : []),
|
||||
// 결정된 식이 수 하나면(만약이 수를 탄 줄) 값을 또 적지 않음
|
||||
...(expr && iffy && tryParse(expr)?.[0] === "num"
|
||||
? []
|
||||
? unitOf(id) // 수 하나 = 값 다시 안 적고 단위만(845-2)
|
||||
? [el("span", { className: "lstk-unit", text: unitOf(id) })]
|
||||
: []
|
||||
: [...(expr ? ["="] : []), el("span", { className: "lstk-val", text: valText(id) })]),
|
||||
];
|
||||
else
|
||||
@@ -350,7 +354,7 @@ export function buildBlock(
|
||||
input(shownText(valueOf), valText(id), "lstk-f-m", (t) =>
|
||||
h.change((doc) => setRow(doc, id, realText(t))),
|
||||
),
|
||||
...(varUnit(v) ? [el("span", { className: "lstk-unit", text: varUnit(v) })] : []),
|
||||
...(unitOf(id) ? [el("span", { className: "lstk-unit", text: unitOf(id) })] : []),
|
||||
];
|
||||
const why = iffy
|
||||
? whyText(tree!, vals, {
|
||||
|
||||
@@ -377,6 +377,7 @@ export function createStackScreen(opt: StackScreenOptions) {
|
||||
machine: machineCtx(),
|
||||
calc: calcSub,
|
||||
lists: (g) => listsOf((q) => cache.links.element(q), g),
|
||||
look: (p) => cache.links.table(p),
|
||||
before: saved ? lineMap(JSON.parse(saved) as StackDoc) : undefined,
|
||||
}),
|
||||
]
|
||||
|
||||
@@ -61,7 +61,7 @@ const PREC: Record<string, number> = {
|
||||
const prec = (n: Node): number => (n[0] === "bin" ? PREC[n[1]] : n[0] === "neg" ? 6 : 9);
|
||||
|
||||
/** TeX 글 안전 — \text{} 안 */
|
||||
const txt = (s: string): string => `\\text{${s.replace(/[\\{}$&#^_%~]/g, (c) => `\\${c}`)}}`;
|
||||
export const txt = (s: string): string => `\\text{${s.replace(/[\\{}$&#^_%~]/g, (c) => `\\${c}`)}}`;
|
||||
const word = (s: string): string =>
|
||||
/^[A-Za-z]$/.test(s) ? s : /^[A-Za-z]+$/.test(s) ? `\\mathit{${s}}` : txt(s);
|
||||
|
||||
|
||||
@@ -5,14 +5,16 @@
|
||||
* ㉢ 비목 · 금액 줄 = 「단가 원/단위 × (수량 식) 단위 = 금액 원」(`moneyUnits` — 수량이 식이면 괄호로 식 전체에 단위) ·
|
||||
* 소계 · 합계 = 원(머리 [원/㎥] = 결과 하나당)
|
||||
* ㉣ 무차원 = 빈 칸 ㉤ 율 = %(「%(인력품 대비)」 등 설명 괄호 뗌) ㉥ 왼쪽 값 칸 = 칸 바로 뒤 한 자리
|
||||
* 메타 단위(「구분 따름」 · 「줄 따름」 · 「수(…)」 · 「원문 단위 없음」) = 단위 아님 → 안 그림 · 「10^-7」 = 10⁻⁷
|
||||
* 메타 단위(「구분 따름」 · 「줄 따름」 · 「수(…)」 · 「원문 단위 없음」) = 단위 아님 → 안 그림 · 「10^-7」 = 10⁻⁷ · kWh = ㎾h
|
||||
* 「줄 따름」 표 값 = 지금 조건으로 고른 표 줄의 「단위」 칸(`rowUnit`) · 단가 분모 = 같은 뜻이면 수량 단위 글(원/일 × 인 → 원/인)
|
||||
* 기계 칸 연결(요소 `EQ:` 칸) 변수 = 변수 단위가 빈 칸이면 기계 표 칸 단위(`MACHINE_UNIT` — 기계 표 빌더 · 내 기계와 같은 글)
|
||||
* 그리기만 — 자료 · 식 · 금액 불변 · 화면 없음(시험이 Node 로 돌림)
|
||||
* ========================================================================== */
|
||||
|
||||
import type { DocVar, MoneyLine, Node } from "./common_util_formula_doc";
|
||||
import { evalNode, tryParse, type Values } from "./common_util_formula_doc_view";
|
||||
|
||||
/** 기계 표 칸 단위(`build_기계_건설품셈.py` UNIT · `M02_MyMachine.py` UNITS 와 같은 글) */
|
||||
/** 기계 표 칸 단위(`build_기계_건설품셈.py` UNIT · `M02_MyMachine.py` UNITS · 845-1 문서 단위와 같은 글) */
|
||||
export const MACHINE_UNIT: Record<string, string> = {
|
||||
가격: "천원",
|
||||
내용시간: "시간",
|
||||
@@ -22,7 +24,7 @@ export const MACHINE_UNIT: Record<string, string> = {
|
||||
관리비계수: "10^-7/시간",
|
||||
손료계수: "10^-7/시간",
|
||||
주연료: "ℓ/hr",
|
||||
전력: "kWh/hr",
|
||||
전력: "㎾h/hr",
|
||||
잡재료율: "%",
|
||||
잡품: "%",
|
||||
조종원: "인/일",
|
||||
@@ -39,9 +41,17 @@ export const AMOUNT_UNIT = "원";
|
||||
export function unitText(u: unknown): string {
|
||||
const s = String(u ?? "").trim();
|
||||
if (!s || /따름|원문 단위 없음/.test(s) || /^수(\(| 또는|$)/.test(s)) return "";
|
||||
return s.replace(/^%\(.*\)$/, "%").replace(/10\^-7/g, "10⁻⁷");
|
||||
return s
|
||||
.replace(/^%\(.*\)$/, "%")
|
||||
.replace(/10\^-7/g, "10⁻⁷")
|
||||
.replace(/kWh/g, "㎾h");
|
||||
}
|
||||
|
||||
/** 같은 뜻 다른 표기(단가 단위 분모 ↔ 수량 단위) — 노임 원/일 ↔ 인(인·일) · ㎏ ↔ kg · ℓ ↔ L */
|
||||
const SAME: [string, string][] = [["일", "인"], ["㎏", "kg"], ["ℓ", "L"]]; // prettier-ignore
|
||||
const same = (a: string, b: string): boolean =>
|
||||
a === b || SAME.some(([x, y]) => (a === x && b === y) || (a === y && b === x));
|
||||
|
||||
/** 기계 칸 이름의 화면 단위 */
|
||||
export const machineUnit = (col: string): string => unitText(MACHINE_UNIT[col]);
|
||||
|
||||
@@ -53,6 +63,29 @@ export function varUnit(v: DocVar | undefined): string {
|
||||
return k?.갈래 === "요소" && /^EQ:/.test(String(k.키 ?? "")) && k.칸 ? machineUnit(k.칸) : "";
|
||||
}
|
||||
|
||||
/** 표 한 칸 읽기(화면 캐시 `links.table`) */
|
||||
export type TableLook = (p: Record<string, unknown>) => unknown;
|
||||
|
||||
/** 「줄 따름」(줄마다 다른 단위) 표 값 = 지금 조건으로 고른 표 줄의 「단위」 칸 · 못 읽으면 빈 글 */
|
||||
export function rowUnit(v: DocVar | undefined, vals: Values, look?: TableLook): string {
|
||||
const k = v?.연결;
|
||||
if (!look || !k?.표 || !/따름/.test(String(v?.단위 ?? ""))) return "";
|
||||
const 조건: Record<string, unknown> = {};
|
||||
for (const [c, t] of Object.entries(k.조건 ?? {})) {
|
||||
const n = tryParse(t);
|
||||
if (n) 조건[c] = evalNode(n, vals);
|
||||
}
|
||||
try {
|
||||
return unitText(look({ 표: k.표, 칸: "단위", 조건 }));
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/** 값 줄 단위 한 벌 — 변수 단위 › 기계 칸 › 고른 표 줄 단위 */
|
||||
export const shownUnitOf = (v: DocVar | undefined, vals: Values, look?: TableLook): string =>
|
||||
varUnit(v) || rowUnit(v, vals, look);
|
||||
|
||||
const HIDE = new Set(["반올림", "올림", "버림"]);
|
||||
/** 한 덩이(기호 · 수 · 칸 — 감싸개 안 한 덩이 포함) */
|
||||
export function isAtom(n: Node | null | undefined): boolean {
|
||||
@@ -83,6 +116,8 @@ export function moneyUnits(
|
||||
const q = has ? unitText(line.단위) : "";
|
||||
const wrap = !!q && !!qty && !isAtom(qty);
|
||||
const own = [sub?.결과단위, priceVar?.단위].map(unitText).find((u) => u.startsWith("원"));
|
||||
const p = has && isAtom(price) ? (own ?? (q ? `${AMOUNT_UNIT}/${q}` : "")) : "";
|
||||
// 단가 분모가 수량 단위와 같은 뜻이면 수량 단위 글로(「원/일 × 인」 대신 「원/인 × 인」)
|
||||
const mine = own && q && same(own.slice(2), q) ? `${AMOUNT_UNIT}/${q}` : own;
|
||||
const p = has && isAtom(price) ? (mine ?? (q ? `${AMOUNT_UNIT}/${q}` : "")) : "";
|
||||
return { price: p, qty: q, wrap };
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ function left(c) {
|
||||
const root = edit.buildEdit({
|
||||
doc, answer: a, items: ls.stackOf(doc), change: noop, table: async () => null, subDoc: sub,
|
||||
name: () => "", open: new Set((doc.금액 || []).map((_, i) => `mctl:${i}`)), pair: noop,
|
||||
machine: { scope: "x" }, calc: (d, g) => calc.calcDoc(d, cache.links, g, [], new Map(), {}), lists: () => null,
|
||||
machine: { scope: "x" }, calc: (d, g) => calc.calcDoc(d, cache.links, g, [], new Map(), {}), lists: () => null, look: (p) => cache.links.table(p),
|
||||
}); // prettier-ignore
|
||||
const rows = [];
|
||||
const walk = (n) => {
|
||||
|
||||
@@ -56,7 +56,9 @@ def world():
|
||||
}
|
||||
)
|
||||
names = [c["문서"].get("이름") for c in cases if c["기계"]]
|
||||
got = _js({"할일": "전수", "문서들": cases, "보기": ["GC000088"], "기계이름": names})
|
||||
got = _js(
|
||||
{"할일": "전수", "문서들": cases, "보기": ["GC000088", "GC000006"], "기계이름": names}
|
||||
)
|
||||
return {g["키"]: g for g in got}
|
||||
|
||||
|
||||
@@ -70,20 +72,35 @@ def test_전수_규칙_어긋남_0(world):
|
||||
def test_GC000088_비목_줄_단위_자리(world):
|
||||
rows = [r["t"] for r in world["GC000088"]["오른쪽"]]
|
||||
labor = next(t for t in rows if t.startswith("노무비 : ") and "×" in t)
|
||||
assert labor.startswith("노무비 : 59,020 원/시간 × ⟦\\left(1 \\times 8 \\div 560\\right)⟧ 시간 = ")
|
||||
assert labor.startswith(
|
||||
"노무비 : 59,020 원/시간 × ⟦\\left(1 \\times 8 \\div 560\\right)⟧ 시간 = "
|
||||
)
|
||||
assert labor.endswith(" 원")
|
||||
assert any(t.startswith("소 계 : ") and t.endswith(" 원") for t in rows)
|
||||
assert any(t.startswith("계 : ") and t.endswith(" 원") for t in rows)
|
||||
# 펼친 굴착기 시간당 경비 — 겹분수 대신 중간 줄
|
||||
sub = "\n".join(rows)
|
||||
assert "⟦\\text{상여}⟧ = ⟦\\dfrac{\\text{상여분자}}{\\text{상여분모}}⟧ = ⟦\\dfrac{16}{12}⟧" in sub
|
||||
assert "⟦\\text{휴지}⟧ = ⟦\\dfrac{\\text{휴지분자}}{\\text{휴지분모}}⟧ = ⟦\\dfrac{25}{20}⟧" in sub
|
||||
assert (
|
||||
"⟦\\text{상여}⟧ = ⟦\\dfrac{\\text{상여분자}}{\\text{상여분모}}⟧ = ⟦\\dfrac{16}{12}⟧" in sub
|
||||
)
|
||||
assert (
|
||||
"⟦\\text{휴지}⟧ = ⟦\\dfrac{\\text{휴지분자}}{\\text{휴지분모}}⟧ = ⟦\\dfrac{25}{20}⟧" in sub
|
||||
)
|
||||
assert "\\dfrac{1}{8} \\times 1.333333 \\times 1.25⟧ = ⟦0.208333" in sub
|
||||
assert "⟦\\text{손료계수}⟧ = " in sub and "= ⟦2{,}085\\ \\text{10⁻⁷/시간}⟧" in sub
|
||||
assert "\\dfrac{142{,}069 \\times 1{,}000 \\times 2{,}085}{10{,}000{,}000}⟧ = ⟦29{,}621" in sub
|
||||
assert "⟦\\text{가격}⟧ = 142,069 천원" in sub
|
||||
assert "⟦\\text{직종}⟧ = 1048" in sub # 코드 값 = 쉼표 없음
|
||||
assert "조종원 : ⟦283{,}297⟧ 원/인 × ⟦\\left(1 \\times 0.208333\\right)⟧ 인 = 59,020.2 원" in sub
|
||||
assert (
|
||||
"조종원 : ⟦283{,}297⟧ 원/인 × ⟦\\left(1 \\times 0.208333\\right)⟧ 인 = 59,020.2 원" in sub
|
||||
)
|
||||
assert "⟦\\text{가산}⟧ = ⟦0\\ \\text{\\%}⟧" in sub # % = TeX 글(주석으로 안 먹힘)
|
||||
|
||||
|
||||
def test_줄_따름_고른_표_줄_단위(world):
|
||||
rows = "\n".join(r["t"] for r in world["GC000006"]["오른쪽"])
|
||||
assert "⟦Q_{\\text{비계공2}}⟧ = 3 인" in rows # 변수 단위 「줄 따름」 = 고른 줄(비계공) 단위 칸
|
||||
assert "비계공 : ⟦281{,}939⟧ 원/인 × ⟦0.03⟧ 인 = 8,458.1 원" in rows # 노임 원/일 = 인 하루 값
|
||||
|
||||
|
||||
def test_왼쪽_제어_구역_단위_오른쪽과_같은_글(world):
|
||||
@@ -98,23 +115,40 @@ def test_단위_규칙_낱개():
|
||||
got = _js(
|
||||
{
|
||||
"할일": "단위",
|
||||
"글": ["구분 따름", "줄 따름", "수(단위는 줄의 단위 칸 따름)", "수", "원문 단위 없음",
|
||||
"%(주연료비의)", "10^-7/시간", "㎥/hr", "인", ""], # fmt: skip
|
||||
"글": [
|
||||
"구분 따름",
|
||||
"줄 따름",
|
||||
"수(단위는 줄의 단위 칸 따름)",
|
||||
"수",
|
||||
"원문 단위 없음",
|
||||
"%(주연료비의)",
|
||||
"10^-7/시간",
|
||||
"㎥/hr",
|
||||
"인",
|
||||
"",
|
||||
], # fmt: skip
|
||||
"변수": [
|
||||
{"단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
|
||||
{"단위": "", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "잡재료율"}},
|
||||
{"단위": "%", "연결": {"갈래": "요소", "키": "EQ:{S_기계}", "칸": "가격"}},
|
||||
{"단위": "", "연결": {"갈래": "요소", "키": "LB:{S_직종}"}},
|
||||
{"단위": "kWh/hr"},
|
||||
],
|
||||
"금액": [
|
||||
[{"단위": "시간", "수량": "Q × 8 ÷ Q2"}, ["var", "P"], ["bin", "/", ["var", "a"], ["var", "b"]], {"단위": ""}, {"결과단위": "원/시간"}], # fmt: skip
|
||||
[{"단위": "인", "수량": "Q"}, ["var", "w"], ["var", "Q"], {"단위": ""}, None],
|
||||
[
|
||||
{"단위": "시간", "수량": "Q × 8 ÷ Q2"},
|
||||
["var", "P"],
|
||||
["bin", "/", ["var", "a"], ["var", "b"]],
|
||||
{"단위": ""},
|
||||
{"결과단위": "원/시간"},
|
||||
], # fmt: skip
|
||||
[{"단위": "인", "수량": "Q"}, ["var", "w"], ["var", "Q"], {"단위": "원/일"}, None],
|
||||
[{"단위": "식"}, ["bin", "*", ["var", "a"], ["var", "b"]], None, None, None],
|
||||
],
|
||||
}
|
||||
)
|
||||
assert got["글"] == ["", "", "", "", "", "%", "10⁻⁷/시간", "㎥/hr", "인", ""]
|
||||
assert got["변수"] == ["천원", "%", "%", ""]
|
||||
assert got["변수"] == ["천원", "%", "%", "", "㎾h/hr"]
|
||||
assert got["금액"] == [
|
||||
{"price": "원/시간", "qty": "시간", "wrap": True},
|
||||
{"price": "원/인", "qty": "인", "wrap": False},
|
||||
|
||||
Reference in New Issue
Block a user