8.3 Reading, Completing, and Modifying Code
Key Takeaways
- To describe what code does, trace it with two or three small inputs, then name the pattern, such as summing, counting, finding a maximum, or searching.
- To choose missing code, decide what each variable must mean at every step, then test each choice on a small case, including a boundary case.
- Statements must appear in dependency order: input before calculation, calculation before output, and initialization before a loop that uses the variable.
- Small edits have predictable effects: changing < to ≤ adds one iteration, moving a statement into a loop repeats it, and changing an initial value shifts every result.
- A loop that repeatedly adds n % 10 to a total and then sets n ← n / 10 computes the sum of the digits of n.
What this competency asks
ETS asks you to understand how to write and modify computer programs in a text-based programming language:
- Describe what a program does, or choose the code segment that correctly implements an intended purpose.
- Identify missing code in a code segment with a stated intended purpose.
- Place statements in an appropriate order to create a correct program.
- Identify how changing one part of a code segment will affect the output.
These four skills recur throughout the Programming category. ETS's sample questions include a missing condition in a find-the-maximum procedure, a missing recursive statement, and a mystery procedure whose purpose you must name.
Skill 1: Describing what code does
Strategy: trace with small, simple inputs, then name the pattern.
int mystery ( int[ ] a, int n )
int c ← 0
for ( int i ← 0; i < n; i ← i + 1 )
if ( a[i] > a[0] )
c ← c + 1
end if
end for
return c
end mystery
Try a = {5, 8, 2, 9}: the values greater than 5 are 8 and 9, so the procedure returns 2. Try {3, 1}: none, so it returns 0. Purpose: it counts how many elements are greater than the first element.
Patterns worth recognizing on sight
| Pattern | Telltale code | Purpose |
|---|---|---|
| Accumulator | total ← total + x inside a loop | Sum (or product, with * and a start of 1) |
| Counter | count ← count + 1 inside an if | How many items meet a condition |
| Extreme value | if ( a[i] > max ) max ← a[i] | Maximum (or minimum, with <) |
| Search with a flag | found ← true or return i when matched | Whether, or where, a value occurs |
| Filter | An if controls which items are added or printed | Keep only certain items |
| Digit loop | n % 10 then n ← n / 10 | Work with each digit |
| Swap | temp ← a, a ← b, b ← temp | Exchange two values |
Beware of answer choices that describe almost the right thing. "Returns the sum of the numbers from 1 to n" and "returns the sum of the multiples of 3 from 1 to n" differ by one if. ETS's own sample mystery procedure is exactly that case.
Skill 2: Identifying missing code
Strategy: state what each variable must hold at every point (its role), then test every choice on a small case, including a boundary case.
Purpose: return the average of the positive values in a, or 0 if there are none.
double avgPositive ( int[ ] a, int n )
int sum ← 0
int count ← 0
for ( int i ← 0; i < n; i ← i + 1 )
if ( a[i] > 0 )
/* missing code */
end if
end for
if ( count == 0 )
return 0
end if
return sum / count // assume floating-point division here
end avgPositive
sum must hold the total of the positive values seen so far, and count must hold how many there were. The missing code must update both: sum ← sum + a[i] and count ← count + 1. A choice that updates only sum leaves count at 0 and always returns 0. A choice that adds i instead of a[i] sums positions rather than values.
Boundary checks that eliminate wrong choices quickly:
- An empty array, or no qualifying values
- A single element
- Values equal to a threshold (tests
>versus≥) - The first and last positions (tests loop bounds)
Skill 3: Putting statements in order
Order follows dependencies: a value must exist before it is used.
- Declare and initialize variables.
- Get input.
- Compute, with any loops (accumulators initialized before the loop).
- Output the result.
Example: compute and print the average of three input values.
int a ← readInt ( )
int b ← readInt ( )
int c ← readInt ( )
int sum ← a + b + c
double avg ← sum / 3.0
print avg
Common ordering errors are printing before computing, computing an average before the sum is complete, updating a loop variable before it is used, and resetting an accumulator inside the loop. Swapping two variables needs the order temp ← a, a ← b, b ← temp. Any other order loses a value.
Skill 4: Predicting the effect of a change
Change one thing, then re-trace only what that change affects.
| Change | Typical effect |
|---|---|
< to ≤ in a loop condition | One more iteration (possibly out of bounds) |
> to ≥ in a comparison | Values equal to the threshold now count |
| Initial value of an accumulator (0 to 1) | Every sum shifts by 1; a product that starts at 0 stays 0 |
| Moving a statement inside a loop | It repeats every iteration |
| Moving a statement outside a loop | It runs once, before or after |
| Swapping two statements | Can change which value is used |
Changing the loop step (+1 to +2) | Skips every other item |
Example. In mystery above, changing a[i] > a[0] to a[i] ≥ a[0] makes the loop count a[0] itself, and any values equal to it. The result for {5, 8, 2, 9} becomes 3 instead of 2.
Reading code efficiently on the test
- Read the stated purpose first, and the preconditions (such as "n is positive").
- Identify the pattern before tracing everything.
- Trace only as much as you need. Often one or two iterations eliminate three choices.
- For "which choice works," find one input where each wrong choice fails.
Assume / performs integer division on int values and n is a positive integer. What does this procedure return?
int mystery ( int n )
int result ← 0
while ( n > 0 )
result ← result + n % 10
n ← n / 10
end while
return result
end mystery
The segment should count the values in a that are between low and high, inclusive. Which condition should replace /* missing condition */?
int count ← 0
for ( int i ← 0; i < n; i ← i + 1 )
if ( /* missing condition */ )
count ← count + 1
end if
end for
A loop for ( int i ← 0; i < n; i ← i + 1 ) adds list[i] to total for a list of length n. If the condition is changed to i < n - 1, what happens?
A program must read three numbers, compute their sum, compute the average, and print the average. The statements are: A: print avg, B: sum ← a + b + c, C: avg ← sum / 3.0, D: read a, b, and c. Which order is correct?