Debugging Functions by Tracing Execution
The most important location to inspect is the overtime check. That is where execution separates into regular-pay logic or overtime-pay logic.
Why Trace a Function
When a program calculates employee pay repeatedly, placing the calculation in one reusable function avoids copying the same logic throughout the program. The computepay function receives hours and rate, decides whether overtime applies, calculates the total, and returns the result. Debugging this function means following its execution with specific inputs and checking where its decision and arithmetic match or diverge from what you expect.
The most important location to inspect is the overtime check. That is where execution separates into regular-pay logic or overtime-pay logic.
The Overtime Decision
The function has two possible paths. When hours is 40 or less, every hour uses the regular rate, so pay is hours multiplied by rate. When hours is greater than 40, the first 40 hours use the regular rate and the remaining hours use 1.5 times the rate. The branch is therefore not a minor detail: it determines which complete calculation is performed.
A First Execution Trace
Tracing Regular Hours
Trace computepay with hours = 38 and rate = 10.
- 1Receive inputs
The function receives hours equal to 38 and rate equal to 10.
- 2Evaluate the branch
Because 38 is 40 or less, execution follows the regular-pay path.
- 3Calculate pay
Regular pay is 38 multiplied by 10, which is 380.
- 4Return the result
The function returns 380 as the total pay.
For 38 hours at a rate of 10, the expected total pay is 380.
This trace gives you a debugging checkpoint at every stage: confirm the inputs, confirm the branch result, confirm the arithmetic, and confirm that the computed value is returned. If the expected result is wrong, these checkpoints help locate the first step where the execution no longer matches the plan.
Implementing the Calculation
The function has exactly two inputs: hours, the number of hours worked, and rate, the hourly pay rate. The conditional checks whether hours is 40 or less. The regular branch multiplies all hours by rate. The overtime branch separates the hours into 40 regular hours and hours minus 40 overtime hours, then pays the overtime portion at rate multiplied by 1.5. The final return makes the calculated value available to the code that called the function.
Tracing Overtime Execution
What do you think happens?
What total pay should computepay return for hours = 45 and rate = 10?
Reveal answer
475
The first 40 hours produce 40 * 10 = 400. The remaining 5 hours are overtime, producing 5 * 10 * 1.5 = 75. Adding the two portions gives 475.
Tracing the Overtime Branch
Trace computepay with hours = 45 and rate = 10.
- 1Receive inputs
The function receives 45 hours and a rate of 10.
- 2Evaluate the branch
Because 45 is greater than 40, execution follows the overtime path.
- 3Separate the hours
The first 40 hours are regular hours. The overtime portion is 45 minus 40, which is 5 hours.
- 4Calculate regular pay
The regular portion is 40 multiplied by 10, which is 400.
- 5Calculate overtime pay
The overtime portion is 5 multiplied by 10 multiplied by 1.5, which is 75.
- 6Combine and return
The total is 400 plus 75, so the function returns 475.
For 45 hours at a rate of 10, the expected total pay is 475.
For an overtime input, tracing should make the split visible. If the result is 450 instead of 475, the likely divergence is that all 45 hours were multiplied by the regular rate. If the result is 425, the overtime portion may have been added at the regular rate rather than at 1.5 times the rate. The branch and the overtime expression are the first places to inspect.
Mistakes Beginners Make
Common mistake Forgetting the overtime check
What it looks likeUsing hours * rate for every input, including hours greater than 40.
Why it failsThis pays overtime hours at the regular rate and ignores the time-and-a-half rule.
Do this insteadCheck whether hours exceeds 40, then split the calculation into regular and overtime portions.
Common mistake Calculating the overtime portion incorrectly
What it looks likeApplying the 1.5 multiplier to all hours instead of only to hours beyond 40.
Why it failsThe first 40 hours remain regular pay; only the additional hours receive the overtime rate.
Do this insteadUse 40 * rate for regular pay and (hours - 40) * rate * 1.5 for overtime pay.
Common mistake Forgetting to return the value
What it looks likeComputing pay inside the function without returning pay.
Why it failsThe calculated total is not made available as the function's result.
Do this insteadReturn the calculated pay after the selected branch completes.
Common mistake Testing only one kind of input
What it looks likeTesting an overtime value but never testing below 40 or exactly 40.
Why it failsA function can appear correct on one execution path while the other path or the boundary is wrong.
Do this insteadTest hours below 40, exactly 40, and above 40.
When debugging, write down the input values, the branch condition's result, each intermediate pay portion, and the value that should be returned. This trace turns a vague wrong answer into a specific checkpoint to inspect.
| Test input | Expected path | Expected calculation | Expected pay at rate 10 |
|---|---|---|---|
| 38 hours | Regular | 38 * 10 | 380 |
| 40 hours | Regular | 40 * 10 | 400 |
| 45 hours | Overtime | 40 * 10 + 5 * 10 * 1.5 | 475 |
A compact trace plan covering both branches and the 40-hour boundary.
Practice the Trace
Trace computepay for hours = 50 and rate = 12. Record which branch runs, how many overtime hours there are, the regular-pay portion, the overtime-pay portion, and the final returned value.
Hints
- Compare 50 with the 40-hour threshold.
- Find the overtime hours by subtracting 40 from 50.
- Calculate regular pay and overtime pay separately before adding them.
- 1Choose one input below 40, one input equal to 40, and one input above 40.
- 2Write the values of hours and rate before tracing.
- 3Evaluate the overtime condition before doing the pay arithmetic.
- 4Follow only the branch selected by that condition.
- 5Check that the function returns the calculated value.
- 6Compare the result with an independently calculated expectation.
Reusable Debugging Pattern
computepay illustrates a reusable debugging pattern: identify the function inputs, locate the conditional decision, trace the selected branch, verify each calculation, and confirm that the result is returned. For this pay rule, hours up to 40 use regular pay, while hours beyond 40 are split into regular hours and time-and-a-half overtime hours. Testing below 40, exactly 40, and above 40 checks both execution paths and the boundary between them.
- 1computepay uses hours and rate as its two parameters.
- 2The branch checks whether hours is 40 or less.
- 3Regular pay is hours multiplied by rate.
- 4Overtime pay combines 40 regular hours with the hours beyond 40 paid at 1.5 times the rate.
- 5Tracing inputs below 40, at 40, and above 40 helps reveal incorrect branching, arithmetic, or return behavior.
Key Takeaways
- A function centralizes pay logic so it can be tested and reused.
- The key debugging point is the conditional decision about whether hours exceeds 40.
- Regular hours use hours multiplied by rate, while overtime calculations separate the first 40 hours from the remaining hours.
- Execution tracing should verify inputs, branch selection, intermediate calculations, and the returned value.
- Testing below 40, exactly 40, and above 40 hours checks the complete behavior.