Concepts / Testing and Debugging Code

Testing and Debugging Code

Debugging means comparing the expected path with the actual path.

  • Programming

From Script to Reusable Function

A grading program becomes easier to reuse and debug when its logic is placed inside a function named computegrade. The function accepts one score and returns a letter grade as a string. Once the function works, you can call it repeatedly without rewriting the grading logic. If a result is wrong, the function gives you one focused place to investigate.

Definition

computegrade is a function that takes a score as a parameter and returns a letter grade as a string. It checks score thresholds with if and elif conditions, beginning with the highest threshold.

Score conditionReturned grade
score >= 0.9A
score >= 0.8B
score >= 0.7C
score >= 0.6D
score < 0.6F

The grading scale uses decimal scores between 0 and 1, and each listed threshold is inclusive.

Following the Threshold Cascade

The conditions must be checked from highest to lowest. For a score of 0.85, the A condition is false because 0.85 is less than 0.9. The next condition, for B, is true because 0.85 is at least 0.8, so the function returns B. It does not continue checking later conditions after finding the first true condition.

score 0.87score >= 0.9falsescore >= 0.8trueBreturned gradecheckfalsetrue
Given a score such as 0.87, which condition is checked next and which branch returns the grade?
python

Tracing a Score of 0.75

Worked example

Tracing computegrade(0.75)

Determine which grade is returned for a score of 0.75.

  1. 1
    Check A

    The condition score >= 0.9 is false because 0.75 is below 0.9.

  2. 2
    Check B

    The condition score >= 0.8 is false because 0.75 is below 0.8.

  3. 3
    Check C

    The condition score >= 0.7 is true because 0.75 is at least 0.7.

  4. 4
    Stop

    The function returns C immediately and does not check the D or F branches.

Result

computegrade(0.75) returns C.

0.75scoreA conditionfalseB conditionfalseC conditiontrueCreturned gradecheckfalsefalsetrue
Which conditions evaluate to false or true, and where does the function stop?

Debugging means comparing the expected path with the actual path. For 0.75, the expected result is C. If the program instead returned A or B, tracing the conditions would show that the error is in the comparison logic or in the order of the branches. Because if and elif stop at the first true condition, an incorrectly ordered cascade can prevent the correct branch from ever being reached.

Checking Boundary Values

Every threshold is inclusive. That means a score exactly equal to 0.9 receives A, exactly 0.8 receives B, exactly 0.7 receives C, and exactly 0.6 receives D. Testing only ordinary values can miss mistakes in comparison operators, so boundary values deserve their own tests.

0.89B0.79C0.69D0.59F0.90A0.80B0.70C0.60D0.91A0.81B0.71C0.61D
What grade should the function return just below, exactly at, and just above each threshold?

Handling Invalid Input

A user may enter a non-numeric value such as the word perfect instead of a score. The function should handle this situation gracefully rather than allowing the program to crash. A try-except block can attempt to convert the input to a float. If that conversion fails, the except block returns the string A Bad score.

python
Output
computegrade("perfect") returns "A Bad score"

Testing the Function Systematically

A function is not verified by testing only one convenient score. Systematic testing uses several kinds of input: values from every grade range, values exactly on the thresholds, values just below thresholds, and invalid non-numeric input. Comparing each actual result with its expected result helps reveal incorrect conditions, incorrect branch order, and missing error handling.

Test inputExpected outputPurpose
0.95ARepresentative A-range value
0.90AExact A boundary
0.85BRepresentative B-range value
0.80BExact B boundary
0.75CRepresentative C-range value
0.70CExact C boundary
0.65DRepresentative D-range value
0.60DExact D boundary
0.50FF-range value
perfectA Bad scoreNon-numeric input

A compact test set covering grade ranges, inclusive boundaries, and invalid input.

python
  • Common mistake

    Checking thresholds from lowest to highest

    What it looks like

    Testing the F condition before the A condition

    Why it fails

    A broad low-threshold condition can become true before the function reaches the more specific higher-grade conditions.

    Do this instead

    Check from the highest threshold downward and rely on the first true condition.

  • Common mistake

    Forgetting that thresholds are inclusive

    What it looks like

    Treating 0.90 as not eligible for A

    Why it fails

    The grading criteria state that a score exactly equal to a threshold receives that grade.

    Do this instead

    Use greater-than-or-equal comparisons for the A, B, C, and D thresholds.

  • Common mistake

    Testing only ordinary scores

    What it looks like

    Testing 0.75 but not 0.70 or 0.80

    Why it fails

    A function can appear correct for middle-of-range values while still failing at boundaries.

    Do this instead

    Include exact thresholds and values around them in the test set.

  • Common mistake

    Allowing non-numeric input to crash the function

    What it looks like

    Passing "perfect" directly into numeric comparisons

    Why it fails

    The input cannot be used as a numerical score.

    Do this instead

    Attempt conversion inside try-except and return "A Bad score" when conversion fails.

Practice and Verification

MEDIUM

Write or inspect a computegrade function and predict the result for each input before running it: 0.99, 0.80, 0.79, 0.60, 0.59, and "unknown". Then compare every result with the grading scale and explain which condition stopped the function.

Hints
  • Start with the highest threshold for each numerical score.
  • Remember that a score exactly equal to a threshold receives that grade.
  • Treat the non-numeric input separately through the try-except path.

What do you think happens?

What does computegrade(0.80) return?

  • A

  • B

  • C

  • A Bad score

Reveal answer
Answer:

B

The A condition is false because 0.80 is below 0.9. The B condition is true because 0.80 is exactly equal to the inclusive 0.8 threshold, so the function returns B.

Reliable Grade Computation

  1. 1
    computegrade turns a numerical score into a reusable letter-grade result.
  2. 2
    Conditions must be checked from the highest threshold to the lowest because the function stops at the first true condition.
  3. 3
    Thresholds are inclusive: exact values of 0.9, 0.8, 0.7, and 0.6 receive A, B, C, and D respectively.
  4. 4
    A try-except block lets the function return A Bad score for non-numeric input instead of crashing.
  5. 5
    Systematic tests should cover representative values, boundaries, values around boundaries, and invalid input.

Key Takeaways

  • A grading function is easier to reuse and debug than repeated grading statements.
  • The first true condition determines the result, so threshold order is essential.
  • Boundary tests reveal whether inclusive comparisons are implemented correctly.
  • Invalid non-numeric input should be caught and reported as A Bad score.
  • Testing across grade ranges, boundaries, and invalid inputs provides stronger evidence that the function works correctly.

Related concepts

More concepts starting with T