Concepts / Debugging Comparison Errors

Debugging Comparison Errors

Using = when a comparison is intended is a common and critical error.

  • 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 Question Behind Every Comparison

When a program compares two operands, it is asking a question about their relationship. The answer is a boolean expression: an expression that evaluates to True or False. True and False are the two possible values of the bool data type.

In the real world

Suppose a program needs to decide whether a score is at least 50. The comparison asks whether the score meets that condition. Python evaluates the comparison and produces either True or False, which the program can then use as an answer.

5 == 5value comparisonTruebool value5 > 8value comparisonFalsebool valueevaluates toevaluates to
What boolean value does each comparison produce before the program continues?

Reading Comparison Structure

Every comparison expression has the same basic structure: a left operand, a comparison operator, and a right operand. The operator sits between the two values being compared. Python examines both operands, applies the operator's rule, and produces True or False.

Worked example

Evaluating a comparison

Determine the result of 12 >= 12.

  1. 1
    Identify the operands

    The left operand is 12 and the right operand is 12.

  2. 2
    Identify the operator

    The operator is >=, which allows the left operand to be larger than or equal to the right operand.

  3. 3
    Compare the values

    The two operands are equal, so the inclusive comparison succeeds.

Result

12 >= 12 evaluates to True.

Assignment Versus Equality

The symbols = and == are not interchangeable in Python. The = operator assigns a value. The == operator compares values and produces a boolean result. Using = when a comparison is intended is a common and critical error.

scorenamescoreleft operandTrue or Falsebool result=assigns==compares values50value50right operandstoresproduces
Does the symbol store a value, or does it compare two values and produce a boolean result?
Before
score = 50

The value 50 is assigned.

After
score == 50

The value of score is compared with 50, producing True or False.

The Eight Comparison Operators

Python provides eight operators that compare two operands and produce a boolean result. The first six primarily describe value relationships. The final two test object identity: whether operands refer to the exact same object in memory.

OperatorQuestion it asksImportant distinction
==Do the operands have equal values?Value equality
!=Do the operands have different values?Value inequality
>Is the left operand larger than the right?Exclusive; equality does not qualify
<Is the left operand smaller than the right?Exclusive; equality does not qualify
>=Is the left operand larger than or equal to the right?Inclusive; equality qualifies
<=Is the left operand smaller than or equal to the right?Inclusive; equality qualifies
isDo the operands refer to the exact same object?Object identity
is notDo the operands refer to different objects?Object identity

Python's eight comparison operators and the relationship each one tests.

The distinction between exclusive and inclusive comparisons matters when the operands are equal. The > operator is True only when the left operand is strictly larger. The >= operator is True when the left operand is larger or when both operands are equal. The same pattern applies to < and <=.

Worked example

Testing equal operands

Compare 7 and 7 using >, >=, <, and <=.

  1. 1
    Apply >

    7 is not strictly larger than 7, so 7 > 7 is False.

  2. 2
    Apply >=

    The operands are equal, and >= includes equality, so 7 >= 7 is True.

  3. 3
    Apply <

    7 is not strictly smaller than 7, so 7 < 7 is False.

  4. 4
    Apply <=

    The operands are equal, and <= includes equality, so 7 <= 7 is True.

Result

For equal operands, the inclusive comparisons are True and the exclusive comparisons are False.

Equality and Object Identity

The operators == and is look related, but they ask different questions. The == operator compares the values of two operands. The is operator checks whether two operands refer to the exact same object in memory. Therefore, two objects can contain equal values while still being different objects.

Object Avalue: 42True== compares valuesObject Bvalue: 42Falseis checks same object== Object Bsame valueis Object Bdifferent object
How can two objects contain equal values but still be different objects in memory?

Debugging Practice

What do you think happens?

Predict the result of each expression before checking the answers: 9 == 9, 9 != 9, 9 > 9, and 9 >= 9.

  • True, False, False, True

  • False, True, True, False

  • True, True, False, False

Reveal answer
Answer:

True, False, False, True

The values are equal, so == is True and != is False. The left value is not strictly larger, so > is False. The inclusive operator >= accepts equality, so it is True.

EASY

For each expression, identify the operands, identify the operator, and predict whether the result is True or False: 3 < 8; 8 <= 8; 4 != 5; and value == 10 when value has the value 10.

Hints
  • Check whether the comparison is exclusive or inclusive.
  • For !=, ask whether the values are different.
  • For ==, compare values rather than asking whether the operands are the same object.
  • Common mistake

    Using = when you mean ==.

    What it looks like

    Writing score = 50 when the intention is to ask whether score has the value 50.

    Why it fails

    The = operator assigns a value; it does not compare two values.

    Do this instead
    Use == when the expression must compare values and produce True or False.
  • Common mistake

    Treating > as though it includes equality.

    What it looks like

    Expecting 7 > 7 to be True.

    Why it fails

    The > operator is exclusive and requires the left operand to be strictly larger.

    Do this instead

    Use >= when equality should also count.

  • Common mistake

    Treating == and is as interchangeable.

    What it looks like

    Using is whenever two operands contain equal values.

    Why it fails

    == tests value equality, while is tests whether the operands refer to the exact same object.

    Do this instead
    Choose == for equal values and is for exact object identity.
  • Common mistake

    Skipping prediction and checking only the final output.

    What it looks like

    Reading a comparison without identifying its operator or operands.

    Why it fails

    Each operator asks a different question, so overlooking the operator can hide the source of an incorrect result.

    Do this instead

    Read every comparison as left operand, operator, right operand, then apply the operator's rule.

A Reliable Debugging Routine

  1. 1
    Separate assignment from comparison: decide whether the statement stores a value or asks a question.
  2. 2
    Identify the left operand and the right operand.
  3. 3
    Name the operator exactly: ==, !=, >, <, >=, <=, is, or is not.
  4. 4
    Check whether the operator tests values or object identity.
  5. 5
    For >, <, >=, and <=, check whether equality is excluded or included.
  6. 6
    Predict True or False before executing or inspecting the result.

This routine turns a vague comparison error into a sequence of smaller checks. Most importantly, it makes the operator visible. A comparison cannot be interpreted correctly until you know which question its operator asks.

Key Takeaways

  1. 1
    A boolean expression evaluates to True or False, the two values of the bool data type.
  2. 2
    The = operator assigns a value, while == compares values.
  3. 3
    Python has eight comparison operators: ==, !=, >, <, >=, <=, is, and is not.
  4. 4
    The > and < operators exclude equality; >= and <= include equality.
  5. 5
    The == operator tests value equality, while is tests whether two operands refer to the exact same object.
  6. 6
    To debug a comparison, identify both operands and the operator, apply the operator's rule, and predict the boolean result.

At a glance

  • Boolean expressions produce True or False.
  • Assignment uses =; comparison uses ==.
  • The eight comparison operators ask different questions about values or object identity.
  • Inclusive operators accept equality, while exclusive operators do not.
  • A dependable debugging method is to identify the operands and operator, then predict the result before execution.

Related concepts

More concepts starting with D