Python 构建时计算演示

本页演示 Quarto 的第二种创作形态:Python 计算块在构建时由 Jupyter 执行, 数值输出与图形直接嵌入静态 HTML——读者打开页面时看到的就是构建那一刻的计算结果, 浏览器端零计算、零后端。

数值计算:梯形法积分

用梯形法(把曲线下面积切成一列梯形求和的数值积分方法)计算 sin(x) 在 [0, π] 上的 积分——解析值恰为 2,数值结果应随采样加密逼近 2:

import numpy as np

xs = np.linspace(0.0, np.pi, 1001)
vals = np.sin(xs)
integral = np.trapezoid(vals, xs)
print(f"梯形法积分结果 = {integral:.6f}(1001 采样点)")
print(f"与解析值 2 的偏差 = {abs(integral - 2.0):.2e}")
梯形法积分结果 = 1.999998(1001 采样点)
与解析值 2 的偏差 = 1.64e-06

PIL 中文字形出图

用系统 PIL(Python 图像库)加 Noto 中文字体画一条衰减振荡曲线,图与坐标轴标签 全部在构建时生成并嵌入本页:

from PIL import Image, ImageDraw, ImageFont
from IPython.display import display

FONT = "/home/ubuntu/.fonts/NotoSansCJKsc-Regular.otf"
W, H = 720, 420
px, py = 70, 40          # 画布边距
x0, x1 = 0.0, 4.0        # x 域

def f(t):
    return np.exp(-0.6 * t) * np.cos(3.0 * t)

ts = np.linspace(x0, x1, 721)
ys = f(ts)
ymin, ymax = float(min(ys)), float(max(ys))

img = Image.new("RGB", (W, H), "white")
d = ImageDraw.Draw(img)
font_l = ImageFont.truetype(FONT, 22)
font_t = ImageFont.truetype(FONT, 26)

def sx(t): return px + (t - x0) / (x1 - x0) * (W - 2 * px)
def sy(v): return H - py - (v - ymin) / (ymax - ymin) * (H - 2 * py)

# 坐标轴
d.line([(px, H - py), (W - px, H - py)], fill="black", width=2)
d.line([(px, py), (px, H - py)], fill="black", width=2)
for tick in np.linspace(x0, x1, 5):
    d.text((sx(tick) - 8, H - py + 6), f"{tick:.1f}", fill="black", font=font_l)
for frac in np.linspace(0, 1, 5):
    v = ymin + frac * (ymax - ymin)
    d.text((6, sy(v) - 10), f"{v:+.1f}", fill="black", font=font_l)

# 曲线
pts = [(sx(t), sy(v)) for t, v in zip(ts, ys)]
d.line(pts, fill="#1f5fbf", width=3)

d.text((W // 2 - 130, 6), "衰减振荡曲线(构建时生成)", fill="black", font=font_t)
d.text((W - 60, H - py + 28), "t", fill="black", font=font_l)
d.text((30, 8), "幅值", fill="black", font=font_l)

display(img)

上图的每一个像素都在 quarto render 时生成:静态页面里没有一行运行时代码, 这就是「构建时执行」形态的全部含义。