Concepts / Debugging Techniques for Variable State

Debugging Techniques for Variable State

Variable updates are not special operations; they follow the same evaluation rules as all assignments: Python evaluates the right side first, then stores the result in the variable on the left.

  • Programming
Interactive lab

Try it: Debug by Tracing Execution

How to debug a program that runs but gives the wrong answer: compare expected and actual output, trace the lines in the order they really run with a variable watch table (or an inserted debug print), find the first line where a value goes wrong, then choose a fix and re-run to check it.

How it works

  1. State the expected output from the specification, run the program and compare: a difference is the evidence you debug from.
  2. Trace in execution order, not file order: loops repeat lines, if/elif picks one branch, and the watch table records every variable before each line runs.
  3. An inserted print('debug: ...', value) shows the same state in the output; it must not change what the program itself prints.
  4. Look for the first place a value differs from what it should be (an off-by-one range, > instead of >=, a total reset inside the loop, two names for one list, a str from input()). Where the wrong value shows up is only the symptom.
  5. Change one thing with a reason, re-run, and compare again: a fix that makes an error disappear can still leave the output wrong.

Default run (14 steps): Sum 1..n: Add up the whole numbers from 1 to n (n included) and print the sum. Press Play to trace it line by line. … Finished, but the output is wrong: got sum of 1 to 5 is 10, expected sum of 1 to 5 is 15.

Simplified: The lab's own small Python interpreter runs fixed, hand-written programs (you pick the program, the fix and a value; your text is never executed). Every program the lab can show was run in CPython 3.12 and the lab reproduces its output, its traceback text and its line-by-line trace. Six short programs, one editable value each; input() receives the value you type in the lab. Lines starting with "debug:" are ignored when comparing the output with the expected output.

Educational simulation

Loading the simulation…

The Hidden Order of an Update

An assignment such as count = count + 1 can look as if Python changes count while it is still calculating the expression. That is not what happens. Python first evaluates the entire right-hand side, using the current value of count. Only after that calculation does it store the result in count. This evaluation order is the key to debugging variable state.

What do you think happens?

When Python processes count = count + 1, which happens first?

  • Python stores 1 in count and then adds the old value

  • Python looks up count and evaluates count + 1

  • Python updates count without reading its current value

Reveal answer
Answer:

Python looks up count and evaluates count + 1.

The right side is evaluated first. The resulting value is then stored in the variable on the left.

countcurrent valuecount + 1calculated resultcountnew valuereadstore result
What happens first when Python evaluates count = count + 1?

Tracing the Current Value

To debug an update, separate it into three actions. First, look up the variable's current value. Second, perform the arithmetic on the right side. Third, store the result in the variable on the left. For an increment, the arithmetic adds 1. For a decrement, it subtracts 1. The variable therefore moves from one state to the next rather than changing mysteriously.

current valuevalue in variablearithmeticadd 1 or subtract 1next valuestored in variablereadstore result
How does the current value move through an expression and become the variable's next value?
Worked example

Following an Increment

Suppose score has already been initialized with the value 4. Trace the update score = score + 1.

  1. 1
    Look up

    Python finds the current value of score: 4.

  2. 2
    Calculate

    Python evaluates the right side using that value: 4 + 1 produces 5.

  3. 3
    Store

    Python stores the result, 5, in score.

Result

score now has the value 5.

Initialization Before Change

Definition

Initialization means giving a variable an initial value before trying to update it. An update depends on reading the variable's current value, so the variable must already exist. If Python cannot find the variable while evaluating the right side, it raises a NameError.

scoreinitial value existsnew scorearithmetic result storeduninitialized namecurrent value unavailableNameErrorupdate cannot be evaluatedupdateread fails
What value exists before an update, and what happens when Python tries to update a variable that has not been initialized?
Worked example

Why the Starting Value Matters

Compare an update to a variable that has an initial value with an update to a variable that has not been initialized.

  1. 1
    Initialized case

    If total has an initial value, Python can look up total, perform the arithmetic on the right side, and store the result.

  2. 2
    Uninitialized case

    If total does not already exist, Python cannot obtain the current value needed to evaluate total + 1.

  3. 3
    Debugging conclusion

    Check whether the variable was initialized before investigating the arithmetic in its update.

Result

Initialization is required because an update reads the variable's current value.

Increment and Decrement

OperationPatternEffect on current value
Incrementx = x + 1Adds 1
Decrementx = x - 1Subtracts 1

Both patterns require x to have an existing value before the update.

Incrementing and decrementing use the same evaluation process. The difference is the arithmetic performed after the current value is read. An increment adds 1 to the current value. A decrement subtracts 1. In both cases, the result replaces the previous value stored in the variable.

Worked example

Tracing Two Directional Updates

A variable begins with the value 7. Trace one increment followed by one decrement.

  1. 1
    Initial state

    The variable's current value is 7.

  2. 2
    Increment

    The update reads 7, adds 1, and stores 8.

  3. 3
    Decrement

    The next update reads 8, subtracts 1, and stores 7.

Result

After the two updates, the variable is back at 7, but each update still followed its own read, calculate, and store sequence.

Mistakes in State Tracing

  • Common mistake

    Treating an update as a special operation that changes the variable before evaluating the expression.

    What it looks like

    Reading count = count + 1 as if count becomes 1 before the addition.

    Why it fails

    Python evaluates the right side first and stores that result afterward.

    Do this instead

    Trace the old value, perform the arithmetic, and then record the new value.

  • Common mistake

    Updating a variable before giving it an initial value.

    What it looks like

    Trying to evaluate x = x + 1 when x does not yet exist.

    Why it fails

    Python cannot look up x to evaluate the right side, so it raises a NameError.

    Do this instead

    Initialize the variable before using its current value in an update.

  • Common mistake

    Confusing an increment with a decrement.

    What it looks like

    Describing x = x - 1 as adding to x.

    Why it fails

    The minus operation subtracts 1 from the current value.

    Do this instead

    Check the operator: plus 1 increments, while minus 1 decrements.

Best practice

When debugging several assignments, write down the variable's value after each completed assignment. For every update, record the value read, the arithmetic performed, and the value stored. This makes it possible to identify the exact step where the state becomes incorrect.

initial valuestarting statefirst resultafter assignment 1second resultafter assignment 2checked statecompare with expected valueupdateupdateinspect
How does a variable's value change after each assignment, and at which step does it become incorrect?

Practice the Three-Step Trace

EASY

A variable begins with the value 3. Trace an increment followed by a decrement. For each update, write the value Python reads, the arithmetic it performs, and the value it stores.

Hints
  • The increment reads the initial value and adds 1.
  • The decrement reads the result of the increment and subtracts 1.
  • Do not calculate the second update from the original value; use the variable's current state.
Worked example

Practice Check

A variable begins with the value 3. What is its value after an increment and then a decrement?

  1. 1
    Increment

    Read 3, add 1, and store 4.

  2. 2
    Decrement

    Read 4, subtract 1, and store 3.

Result

The final value is 3.

A Reliable Debugging Routine

  1. 1
    Initialize a variable before updating it so Python can find its current value.
  2. 2
    Read the right side of an assignment from left to right as an expression to be evaluated before storage occurs.
  3. 3
    Trace every update as three actions: look up the current value, perform the arithmetic, and store the result.
  4. 4
    An increment adds 1 to the current value, while a decrement subtracts 1.
  5. 5
    When a state becomes incorrect, inspect the value after each assignment to locate the first incorrect transition.

Key Takeaways

  • A variable update is an ordinary assignment: Python evaluates the right side first and stores the result on the left.
  • The variable must already be initialized because the update needs its current value.
  • Debugging becomes clearer when each update is traced as read, calculate, and store.
  • Incrementing adds 1, while decrementing subtracts 1.
  • Recording the state after each assignment reveals where an incorrect value first appears.

Related concepts

More concepts starting with D