模块化顺序计算 · QuartoPub + PyScript
运行顺序管线 ▶
<label for="d1">距离 d₁</label>
<input id="d1" type="number" step="any" placeholder="例如 100">
<label for="t1">时间 t₁</label>
<input id="t1" type="number" step="any" placeholder="例如 10">
<label for="d2">第二段距离 d₂</label>
<input id="d2" type="number" step="any" placeholder="例如 250">
<button id="run" class="btn">运行顺序管线</button>
<p class="hint">步骤:先计算速度 v = d₁ / t₁,再计算时间 t₂ = d₂ / v。</p>
<pre id="log">填入数值并点击“运行顺序管线”。</pre>
class SpeedModule: def call(self, distance: float, time: float) -> float: if time == 0: raise ValueError(“time 不能为 0”) return distance / time
class TimeModule: def call(self, distance: float, speed: float) -> float: if speed == 0: raise ValueError(“speed 不能为 0”) return distance / speed
class SequentialPipeline: def init(self, *modules): self.modules = modules
def run(self, **inputs):
"""
约定:
- 第 1 个模块显式取参(本例为 SpeedModule(distance=d1, time=t1))。
- 后续模块接收前一步输出 prev 以及自身需要的入参(本例 TimeModule(distance=d2, speed=prev))。
返回:steps 日志与 final 结果。
"""
log = []
prev = None
for i, m in enumerate(self.modules, start=1):
if i == 1:
if isinstance(m, SpeedModule):
result = m(inputs.get('d1', 0.0), inputs.get('t1', 0.0))
else:
raise NotImplementedError("未适配的首个模块类型:%s" % m.__class__.__name__)
else:
if isinstance(m, TimeModule):
result = m(inputs.get('d2', 0.0), prev)
else:
raise NotImplementedError("未适配的后续模块类型:%s" % m.__class__.__name__)
log.append((i, m.__class__.__name__, result))
prev = result
return {"steps": log, "final": prev}
def run_pipeline(event=None): q = lambda x: document.getElementById(x).value try: d1 = float(q(‘d1’) or 0) t1 = float(q(‘t1’) or 0) d2 = float(q(‘d2’) or 0) pipe = SequentialPipeline( SpeedModule(), # 步骤 1:算速度 v = d1 / t1 TimeModule() # 步骤 2:算时间 t2 = d2 / v ) res = pipe.run(d1=d1, t1=t1, d2=d2) lines = [“—— 运行完成 ——”] for i, name, val in res[“steps”]: lines.append(f”Step {i} · {name} → {val}“) lines.append(f”Final Result: {res[‘final’]}“) document.getElementById(‘log’).innerText =”“.join(lines) except Exception as e: document.getElementById(‘log’).innerText = f”错误:{e}”
绑定按钮
document.getElementById(‘run’).addEventListener(‘click’, run_pipeline)