CSPIQ · AP Computer Science Principles · Lesson 14 of 25
CSPIQ · AP Computer Science Principles

Lesson 14: Procedures: Calling, Developing & Abstracting

Big Idea 3 (AAP) · Phase 3

Objectives

Warm-Up

You already use procedural abstraction daily. When you tell a friend "text me the address," you don't specify: unlock phone, open messages, find our thread, type, hit send. You name the task; they handle the steps.

Code works the same way:

DISPLAY (LENGTH(scores))

You've been calling LENGTH for six lessons without once wondering how it counts elements. Somebody wrote those steps; you use the name. That's a procedure: named code you invoke without re-reading its insides.

Today you move from calling other people's procedures to writing your own — which happens to be the exact skill the Create Performance Task grades hardest.


Core Concept

Anatomy of a procedure

PROCEDURE applyDiscount(price, percent)
{
    amount ← price * percent / 100
    RETURN (price − amount)
}

Calling it:

sale ← applyDiscount(80, 25)

The arguments (80, 25) are copied into the parameters in order: price = 80, percent = 25. The body computes amount = 20, returns 60. The call expression applyDiscount(80, 25) becomes 60, which is assigned to sale.

Parameter vs. argument (the exam does test the vocabulary): parameters are the names in the definition; arguments are the values in the call. Order is everything — applyDiscount(25, 80) computes a very different discount.

Not every procedure returns a value; some just do things (display output, move a robot):

PROCEDURE greet(name)
{
    DISPLAY ("Hello,")
    DISPLAY (name)
}

Tracing calls — the flow

PROCEDURE triple(x)
{
    RETURN (x * 3)
}

a ← 4
b ← triple(a + 1)
DISPLAY (b + triple(2))

Trace: a + 1 evaluates first → 5 → becomes x inside triple → returns 15 → b = 15. Then triple(2) → 6. Display 15 + 6 = 21.

Rules that earn points: 1. Arguments are evaluated, then copied. The parameter is a new variable; changing it inside the procedure does not change the caller's variable (Lesson 7's copies-not-links, again). 2. RETURN exits NOW. Code after an executed RETURN is dead. A RETURN inside a loop ends the whole procedure mid-loop — the favorite trick:

PROCEDURE findFirst(list, target)
{
    i ← 0
    FOR EACH item IN list
    {
        i ← i + 1
        IF (item = target)
        {
            RETURN (i)        ← exits on the FIRST match
        }
    }
    RETURN (-1)               ← runs only if the loop finishes with no match
}

This is Lesson 12's first-occurrence search, cleaner: the early RETURN is the guard. findFirst(["a","b","a"], "a") → 1, not 3.

Procedural abstraction: why procedures exist

Procedural abstraction = giving a name to a computational process and using the name instead of the steps. The CED's claims:

Exam phrasing to expect: "Which is a benefit of using the procedure?" Correct answers say manage complexity, avoid duplication, single point of change. Wrong answers say runs faster, uses less memory, prevents all errors — procedures do none of that automatically.

Developing a procedure from a spec

Spec: "Write a procedure countAbove(nums, cutoff) returning how many values in nums exceed cutoff."

Recipe: (1) name + parameters from the spec; (2) pick the silhouette (count-matches, Lesson 12); (3) adapt the condition; (4) RETURN the result:

PROCEDURE countAbove(nums, cutoff)
{
    count ← 0
    FOR EACH n IN nums
    {
        IF (n > cutoff)
        {
            count ← count + 1
        }
    }
    RETURN (count)
}

Sequencing ✓ selection ✓ iteration ✓ parameter ✓ return ✓ — this shape is the Create PT procedure requirement satisfied in nine lines.


Worked Examples

Example 1 (easy): Basic call trace

Problem: What is displayed?

PROCEDURE square(n)
{
    RETURN (n * n)
}

DISPLAY (square(3) + square(4))

Solution: square(3) → 9; square(4) → 16; displays 25.

Example 2 (medium): Copies, not links

Problem: What is displayed?

PROCEDURE bump(x)
{
    x ← x + 10
    RETURN (x)
}

n ← 5
result ← bump(n)
DISPLAY (n)
DISPLAY (result)

Solution: bump receives a copy: inside, x becomes 15 and is returned → result = 15. The caller's n was never touched → displays 5, then 15.

Interpretation: "Does the original variable change?" No — arguments are copied into parameters. The distractor (15, 15) bets you think x is n.

Example 3 (medium): Early RETURN

Problem: What does check([4, 9, 12, 15]) return?

PROCEDURE check(nums)
{
    FOR EACH n IN nums
    {
        IF (n MOD 2 = 1)
        {
            RETURN (n)
        }
    }
    RETURN (0)
}

Solution: 4 even → continue. 9 odd → RETURN 9 — procedure over. 12 and 15 never examined. Returns 9.

Interpretation: The trap answer is 15 (the last odd) for students who let the loop "finish." An executed RETURN is a trapdoor, not a bookmark.

Example 4 (AP-style): Two procedures deep

Problem: What is displayed?

PROCEDURE f(a)
{
    RETURN (a + g(a))
}

PROCEDURE g(b)
{
    RETURN (b * 2)
}

DISPLAY (f(3))

Solution: f(3): a = 3 → needs g(3) → b = 3 → returns 6 → f returns 3 + 6 = 9.

Interpretation: Nested calls resolve inside-out, like parentheses. Keep a small call stack on scratch paper: f(3) waiting… g(3) = 6… f = 9. Two levels is as deep as the exam goes — with the trace habit it's mechanical.


Common Mistakes

  1. Believing the procedure changes the caller's variable. Arguments are copied into parameters. After bump(n), n is unchanged unless the caller assigns the returned value: n ← bump(n).
  2. Ignoring that RETURN exits immediately. Especially inside loops: an early RETURN means later elements are never seen (Example 3).
  3. Swapping argument order. applyDiscount(25, 80)applyDiscount(80, 25). Match positions to parameters — the exam plants swapped-order distractors on any two-parameter procedure.
  4. Claiming performance benefits for abstraction. Procedures organize code; they don't speed it up. Benefit answers: complexity management, reuse, single point of change — never "runs faster."
  5. Forgetting a RETURN for the not-found path. A search procedure needs a final RETURN after the loop (the "no match" answer). The exam shows this as "what does the procedure return when target is absent?" — if the only RETURN is inside the IF, the procedure returns nothing meaningful; well-written versions return a sentinel like −1 or false.

Practice Problems

Question 1
In PROCEDURE area(w, h) called as area(3, 7), the values 3 and 7 are the:
Question 2

What is displayed?

PROCEDURE half(n)
{
    RETURN (n / 2)
}
DISPLAY (half(10) + half(6))
Question 3

What is displayed?

PROCEDURE mystery(a, b)
{
    IF (a > b)
    {
        RETURN (a − b)
    }
    RETURN (b − a)
}
DISPLAY (mystery(4, 9))
Question 4

What does this display?

PROCEDURE update(val)
{
    val ← val * 100
    RETURN (val)
}
x ← 7
update(x)
DISPLAY (x)
Question 5
In problem 4, what single change makes the program display 700?
Question 6

What does locate([7, 2, 7], 7) return?

PROCEDURE locate(list, t)
{
    i ← 0
    FOR EACH item IN list
    {
        i ← i + 1
        IF (item = t)
        {
            RETURN (i)
        }
    }
    RETURN (-1)
}
Question 7
In problem 6, what does locate([4, 6, 8], 5) return?
Question 8
Which is a benefit of replacing three identical blocks of code with one procedure called three times? *(Select two answers.)
Question 9

What is displayed?

PROCEDURE outer(n)
{
    RETURN (inner(n) + 1)
}
PROCEDURE inner(m)
{
    RETURN (m * m)
}
DISPLAY (outer(5))
Question 10
A procedure's internals are rewritten to use a more efficient algorithm; its name, parameters, and returned results are unchanged. What happens to programs that call it?
Question 11

What does tally([3, 8, 3, 3], 3) return?

PROCEDURE tally(nums, target)
{
    c ← 0
    FOR EACH n IN nums
    {
        IF (n = target)
        {
            c ← c + 1
        }
    }
    RETURN (c)
}

12 (short response, PT-style). Write a procedure bestScore(scores) that returns the highest value in the non-empty list scores. Your procedure must use a parameter, selection, and iteration. State what bestScore([71, 94, 82]) returns.


Create PT Connection

This lesson is the Create PT. The rubric requires a student-developed procedure that:

The countAbove / tally / bestScore shapes in this lesson satisfy every requirement. Three PT-saving specifics:

  1. The parameter must matter. A procedure that ignores its parameter (or takes none) fails the rubric row outright. Your parameter should change the result when its value changes — be ready to say how.
  2. Selection and iteration must be inside the procedure, not just elsewhere in the program.
  3. Screenshot both definition and call for the Personalized Project Reference — scorers verify the call exists.

Written Response 2(c) rehearsal: "My procedure tally(nums, target) implements procedural abstraction: the main program calls it by name to count matches without containing the counting logic itself. Because the logic lives in one procedure, I fixed a comparison bug in one place and every feature using the count was corrected simultaneously." — Note it hits name, abstraction claim, and single-point-of-change. Build your own version of this paragraph the day your procedure works.


Show answer key & explanations

(g) Answer Key

1. (C). Values in the call = arguments; names in the definition (w, h) = parameters. Flashcard it.

2. (A). 5 + 3 = 8.

3. (B). a = 4, b = 9: 4 > 9 false → skip to second RETURN → 9 − 4 = 5. The procedure computes absolute difference; (A) forgets the ELSE-path flips the subtraction.

4. (B). update works on a copy; the returned 700 is discarded (the call isn't assigned to anything). x remains 7. The exam loves the unassigned-return: computing a value ≠ storing it.

5. (A). Capture the returned value back into x. (D) tempts, but a procedure can't assign to the caller's variable — x doesn't exist inside update; that change makes the procedure invalid.

6. (C). Early RETURN fires at the FIRST match: i = 1. (A) is the last-occurrence misread; (D) counts matches instead of locating.

7. (A). Loop completes with no match → the final RETURN (-1) runs. The sentinel path is real code, not decoration.

8. (A) and (C). Single point of change + readability = procedural abstraction's actual benefits. (B) invents speed; (D) invents safety.

9. (C). inner(5) = 25, outer returns 25 + 1 = 26. (A) stops one level early; (D) adds instead of squaring.

10. (B). Interchangeable internals — the abstraction contract. Callers see name/parameters/results only; same interface, same behavior, zero caller changes.

11. (D). Count the 3s: positions 1, 3, 4 → 3. No early exit here — this one counts every match (contrast problem 6; the presence or absence of RETURN inside the IF is the entire difference between find and count).

12. (Model answer.)

PROCEDURE bestScore(scores)
{
    best ← scores[1]
    FOR EACH s IN scores
    {
        IF (s > best)
        {
            best ← s
        }
    }
    RETURN (best)
}

bestScore([71, 94, 82]) returns 94. Full credit needs: parameter used (scores), selection (IF), iteration (FOR EACH), honest initialization (scores[1], not 0 — Lesson 12!), and a RETURN outside the loop.

Answer letter distribution check: C, A, B, B, A, C, A, A+C, C, B, D — singles: A×3, B×3, C×3, D×1 + multi (A,C). Balanced. Cumulative through L14 ≈ A 24%, B 30%, C 26%, D 20%.


Exam tip: On any procedure trace, write the call's argument values above the parameter names before reading the body — x=5 in the margin — and the moment you hit RETURN, draw a line: nothing below it executes. Those two pencil habits (bind, then trapdoor) cover every procedure distractor the exam owns.

← All lessons
Lesson 15 ›
Score: 0/0 correct