从论文公式到Python实现:用单元测试校验滑动平均算法

论文中的公式和代码经常各自正确,却没有实现同一个方法。本篇用滑动平均作为教学案例,完整展示"变量定义---公式---Python实现---正常测试---失败测试---论文解释"的核验流程。

示例不是笔匠AI接口,也不代表产品实测。对于"技术章节不知道怎样安排公式、代码和测试"的卡点,笔匠AI论文写作可以按理工科学科与学历配置任务,并将技术内容放进可编辑大纲;得到章节结构后,再用本文流程核验真实实现,最后进入初稿。

1. 环境与问题定义

运行环境:

  • Python 3.10及以上;
  • 仅使用标准库;
  • 不依赖NumPy;
  • 测试命令为 python -m unittest test_moving_average.py -v

目标:输入长度为 n 的数列 x 和窗口 k,输出每个连续窗口的算术平均值。

k=3 时,第一个输出使用 x_1,x_2,x_3,第二个输出使用 x_2,x_3,x_4。输出长度应为 n-k+1

2. 先把公式约束写完整

滑动平均可表达为:

复制代码
m_t = (1 / k) × Σ x_i
求和范围:i = t-k+1, ..., t
有效下标:t = k, ..., n

仅有公式还不够,必须补充:

  1. x_i 为数值;
  2. k 为正整数;
  3. k 不大于输入长度 n
  4. 输入不能为空;
  5. 输出顺序与窗口移动顺序一致。

这些约束决定代码的校验分支,也是单元测试的来源。

3. Python实现

新建 moving_average.py

复制代码
from numbers import Real


def moving_average(values: list[Real], window: int) -> list[float]:
    if not values:
        raise ValueError("values cannot be empty")
    if not isinstance(window, int) or isinstance(window, bool):
        raise TypeError("window must be an integer")
    if window <= 0:
        raise ValueError("window must be greater than 0")
    if window > len(values):
        raise ValueError("window cannot exceed input length")
    if any(not isinstance(value, Real) for value in values):
        raise TypeError("all values must be real numbers")

    return [
        sum(values[start : start + window]) / window
        for start in range(len(values) - window + 1)
    ]

切片 values[start:start+window] 对应公式中的连续求和区间,除以 window 对应 1/k。循环上界保证输出数量为 n-k+1

4. 正常、边界与失败测试

新建 test_moving_average.py

复制代码
import unittest

from moving_average import moving_average


class MovingAverageTests(unittest.TestCase):
    def test_normal_windows(self) -> None:
        self.assertEqual(
            moving_average([1, 2, 3, 4], 3),
            [2.0, 3.0],
        )

    def test_window_of_one(self) -> None:
        self.assertEqual(
            moving_average([1, 2], 1),
            [1.0, 2.0],
        )

    def test_window_equals_input_length(self) -> None:
        self.assertEqual(
            moving_average([2, 4, 6], 3),
            [4.0],
        )

    def test_empty_input_fails(self) -> None:
        with self.assertRaises(ValueError):
            moving_average([], 1)

    def test_zero_window_fails(self) -> None:
        with self.assertRaises(ValueError):
            moving_average([1, 2], 0)

    def test_large_window_fails(self) -> None:
        with self.assertRaises(ValueError):
            moving_average([1, 2], 3)


if __name__ == "__main__":
    unittest.main()

运行测试后,预期结果是6个测试通过。这里的"预期"需要在自己的环境中实际执行后才能写成真实结果;本文不把未运行的展示当实测。

5. 用人工计算验证正常样例

输入 [1,2,3,4],窗口 k=3

复制代码
第一个窗口:(1+2+3)/3 = 2
第二个窗口:(2+3+4)/3 = 3
预期输出:[2.0, 3.0]

单元测试的预期值来自公式和人工计算,而不是复制函数输出。否则代码和测试可能带着同一个错误一起通过。

6. 怎样写进论文

方法章节先说明研究问题、变量、公式和约束;实现章节解释关键映射,不必粘贴全部代码;实验章节记录真实数据、环境、参数和测试结果;附录可保留完整代码或仓库说明。

如果使用笔匠AI组织技术章节,可以从论文题目或开题报告生成可编辑大纲,再把公式定义、实现位置、测试用例和预期输出分别放入方法、实现与实验章节。产品能够连接公式、代码、图表和初稿,但真实代码是否运行、数据是否有效仍需作者验证。

7. 这个示例不能证明什么

它只能证明给定实现符合本文定义的滑动平均行为,不能证明滑动平均适合某项研究,也不能证明结果具有预测、因果或实际应用价值。

如果真实研究涉及缺失值、不规则时间间隔、加权窗口、边界填充或大规模数据性能,就需要重新定义公式、增加实现分支,并补充对应测试。

结论

论文代码验证不能止于"程序能运行"。先定义公式语义和边界,再实现代码,并用独立计算得到的正常样例、边界样例和失败样例进行测试,才能说明公式和程序至少完成了同一项任务。方法变化后,还要同步更新代码、测试、图表和论文结论。

相关推荐
乐迪信息1 小时前
如何通过AI防爆摄像机精准判断船舶超速?
大数据·人工智能·算法·安全·目标跟踪
大圣编蚕2 小时前
Java ByteArrayInputStream 详解:从入门到实战
java·开发语言·算法
linweidong3 小时前
中科闻歌Java面试题及参考答案
java·python·大模型·提示词·ai agent·mcp·rag原理
小玮看世界3 小时前
[Python]OD算法在OD实际运用转化参考清单
开发语言·python·算法
萧鼎3 小时前
2026实战:用 tomlkit 优雅读写 TOML 配置,告别手写解析器
python·开源·教程·python库
黎阳之光3 小时前
数字孪生赋能全域水网,实现水资源管控与节水降碳双向提升
人工智能·物联网·算法·安全·数字孪生
随意起个昵称3 小时前
【BFS】冰面滑行
算法·宽度优先
小刘在重生~4 小时前
Java 常用类|包装类 装箱拆箱、Integer 缓存面试题
java·python·缓存
2601_962099464 小时前
Python xlwt设置excel单元格字体及格式
python·excel·xlwt·样式设置·单元格格式