What Is a Dry Run? Trace Your Code Before Running It



☰

开始北极星测评

Python DSA Notes

What Is a Dry Run? Trace Your Code Before Running It

Trace code with small inputs and variable tables to catch boundary, initialization, and update-order mistakes.

Python DSA 笔记

Dry run 是什么?写代码前先在纸上跑一遍

用小输入和变量表逐行模拟代码,在运行前发现边界、初始化和更新顺序错误。

分享这篇文章

复制链接、使用手机分享、用微信扫码,或通过邮件发送。




邮箱

Many students finish some code, press Run immediately, and add several print() statements when the answer is wrong. In algorithm problems, there is another habit that often saves more time: take a sample input and execute the code yourself on paper before running it.

This is called a dry run, or code tracing. It can expose boundary, initialization, and update-order mistakes before submission.

What Happens in a Dry Run?

A dry run is not a guess. You follow the program one line at a time and record the current values of important variables.

Suppose we want to find the largest value in a list:

numbers = [3, 1, 5, 2]
largest = numbers[0]

for number in numbers:
    if number > largest:
        largest = number

print(largest)

Trace it with a table:

Current number largest before number > largest largest after
3 3 False 3
1 3 False 3
5 3 True 5
2 5 False 5

The final result is 5. More importantly, the table shows how the algorithm's state changes instead of showing only its final output.

Why Does the Variable Table Help?

Algorithm mistakes are often logic errors, not syntax errors. The code runs, but one iteration updates the wrong value or an edge case produces an incorrect answer.

For every iteration, the table makes you identify the current input, the state before the decision, whether the condition is true or false, and the state after the update. When the trace first differs from your expectation, you have found the neighborhood of the bug.

Finding an Initialization Bug

Consider this version:

numbers = [-4, -2, -7]
largest = 0

for number in numbers:
    if number > largest:
        largest = number

print(largest)

Every comparison is false, so the program prints 0 even though 0 is not in the input. The loop is not the problem. Initializing largest to 0 introduced an invalid candidate when all values were negative.

Initialize from the data instead:

numbers = [-4, -2, -7]
largest = numbers[0]

for number in numbers[1:]:
    if number > largest:
        largest = number

print(largest)

The new trace finishes with -2. A small edge-case input revealed a mistake that an ordinary positive example would hide.

Checking Update Order

A dry run also catches mistakes when one iteration updates several variables:

a = 2
b = 5

a = b
b = a

After a = b, both values are already 5. The second assignment cannot recover the old value of a. Tracing each assignment shows exactly where that information was lost. In Python, the swap can be written as a, b = b, a.

A Five-Step Dry Run

  1. Choose a small but representative input.
  2. Identify the variables that can change.
  3. Create one table row for every loop iteration.
  4. Update values in the exact order used by the code.
  5. Repeat with an edge case such as a minimum input, duplicates, all-negative values, or a value exactly on a boundary.

The input should be small enough to trace clearly but varied enough to make important conditions become both true and false.

Dry Run vs. Runtime Debugging

Method When to use it Best at finding
Dry run Before running or submitting Idea, boundary, initialization, and update-order errors
print() debugging While the program runs Actual execution paths and values
Debugger When step-by-step pauses are useful More complex calls and program state

These methods complement one another. A useful sequence is to trace the idea first, run tests second, and then gather runtime evidence if a problem remains.

Practice

  1. Trace the maximum-finding code with numbers = [4, 2, 6] and record number and largest.
  2. Test the largest = 0 version with numbers = [-3] and explain the failure.
  3. Challenge: dry-run a loop that sums a list, then design an edge case for an empty list.

One-Sentence Takeaway

A dry run uses a small input to trace code and record changing variables, revealing boundary, initialization, and update-order errors before execution.

代码写完后立刻点 Run,看到错误再加几个 print(),是很多同学最熟悉的调试方式。但算法题里还有一个更省时间的习惯:先不运行程序,自己拿一组输入,按照代码顺序在纸上跑一遍。

这个过程叫 dry run,也常被称为手动模拟或 code tracing。它能帮你在提交前发现边界、变量初始化和更新顺序的问题。

Dry run 到底在做什么?

Dry run 不是凭感觉猜输出,而是像 Python 一样逐行执行代码。每执行一步,就记录重要变量当前的值。

假设我们要找出 list 中的最大值:

numbers = [3, 1, 5, 2]
largest = numbers[0]

for number in numbers:
    if number > largest:
        largest = number

print(largest)

不用运行代码,先画一张变量表:

当前 number 比较前 largest number > largest 比较后 largest
3 3 False 3
1 3 False 3
5 3 True 5
2 5 False 5

循环结束后,largest 是 5,所以程序输出 5。更重要的是,这张表让我们看见了算法的状态如何一步步变化,而不只是最后答案。

为什么变量表很有用?

算法中的错误经常不是语法错误。程序可以正常运行,却在某一轮更新错了变量,或者在边界输入下得到错误答案。

变量表会强迫我们回答四个问题:

  1. 这一轮处理哪个输入?
  2. 判断之前,关键变量是什么?
  3. 条件是 True 还是 False?
  4. 执行更新后,变量变成什么?

如果纸上的变化和你的预期不同,问题通常就在那一行附近。

Dry run 能发现初始化错误

再看一个看起来差不多的版本:

numbers = [-4, -2, -7]
largest = 0

for number in numbers:
    if number > largest:
        largest = number

print(largest)

用变量表模拟:

当前 number 比较前 largest number > largest 比较后 largest
-4 0 False 0
-2 0 False 0
-7 0 False 0

最后程序输出 0,但 0 根本不在输入里。问题不是循环,而是初始化:如果所有数字都是负数,largest = 0 就给算法放进了一个不属于数据的候选答案。

更稳妥的写法是从第一个元素开始:

numbers = [-4, -2, -7]
largest = numbers[0]

for number in numbers[1:]:
    if number > largest:
        largest = number

print(largest)

这次 dry run 会得到 -2。一个小小的边界输入,直接暴露了正常正数样例看不出来的错误。

Dry run 还能检查更新顺序

如果一轮循环会更新多个变量,顺序也可能改变结果。例如交换两个变量时这样写:

a = 2
b = 5

a = b
b = a

手动执行第一行后,a 已经变成 5。第二行再执行 b = a,得到的仍然是 5。最后两个变量都是 5,并没有完成交换。

变量表会清楚显示:

步骤 a b
初始 2 5
a = b 后 5 5
b = a 后 5 5

Python 可以直接写:

a, b = b, a

Dry run 的价值不只是找出“答案错了”,而是定位变量在哪一步失去了原来的值。

怎样做一次有效的 Dry run?

可以固定使用下面五步:

  1. 选择一个小而有代表性的输入。
  2. 圈出会变化的关键变量。
  3. 为循环的每一轮画一行表格。
  4. 严格按照代码顺序更新,不要在脑中跳步。
  5. 用边界输入再跑一次,例如最小规模、重复值、全负数或刚好卡在条件边缘的值。

输入要小,是因为你需要看清每一步;输入也要有变化,才能让条件既出现 True,也出现 False。

Dry run 和 print debugging 有什么区别?

方法 什么时候用 最适合发现什么
Dry run 运行或提交前 思路、边界、初始化、更新顺序错误
print() debugging 程序已经运行时 实际执行路径和真实变量值
Debugger 需要逐行暂停时 较复杂的调用和程序状态

它们不是互相替代。好的顺序通常是:先 dry run 检查思路,再运行测试;仍有问题时,使用 print() 或 debugger 收集证据。

小练习

  1. 对 numbers = [4, 2, 6] 手动模拟找最大值的代码,画出 number 和 largest 的变量表。
  2. 用 numbers = [-3] 测试 largest = 0 的版本,解释错误发生在哪里。
  3. 挑战题:对一个计算 list 总和的循环做 dry run,并设计一个能检查空 list 的边界测试。

一句话记住

Dry run 就是用小输入逐行模拟代码、记录变量变化,在真正运行前发现边界、初始化和更新顺序错误。

有问题或建议?

如果你对本文有疑问,或希望提出改进建议,请给我们发送私密留言。

发送反馈

有问题或建议?

如果你对本文有疑问,或希望提出改进建议,请给我们发送私密留言。

发送反馈

返回资源库
返回资源文章

滚动至顶部