Topic 3.13: Developing Procedures | AP CSP Big Idea 3 | APCSExamPrep.com

AP CSP Course Big Idea 3 3.13 Developing Procedures
3.13
Big Idea 3 • Algorithms & Programming

Developing Procedures

🕐 ~40 min FREE 📖 6 MCQ questions 🎮 Procedure Builder game 💻 Live Python editor AAP-3.B • AAP-3.C

After this lesson, you will be able to:

  • Define a procedure in Python with def and in AP pseudocode with PROCEDURE
  • Add a parameter that generalizes a procedure so one definition works for many inputs
  • Return a computed value with return, and know a missing return hands back None
  • Explain that a parameter is a local placeholder, not the caller's variable
  • Describe procedural abstraction and its benefits: reuse, readability, and hiding detail
  • Write a Create Task procedure with a parameter, selection, and iteration
📈 Exam weight: Writing procedures with parameters and return values (AAP-3.B) and explaining procedural abstraction (AAP-3.C) appear on the MCQ and are directly scored on the Create Task. The None trap and the local-parameter trap are frequent MCQ targets.
💡 Think about this first

You have called print hundreds of times without knowing how it works inside. That is abstraction: a name you trust, details you ignore. Now you become the author. When you write def double(n): return n * 2, you create a name others can call the same way, once, and reuse forever. This lesson is about building your own procedures with parameters and return values, and knowing exactly what comes back.

Writing Your Own Procedure

A procedure is a named block of code that you can call by name. Until now you have mostly called procedures other people wrote, like print or len. Now you will define your own. In Python you write def name(parameters): and then the indented body. The definition does not run on its own. The body only executes when the procedure is called.

Two pieces make a procedure powerful. A parameter is a placeholder listed in the header that stands for a value the caller will supply. A return value is the result the procedure hands back with the return keyword, so the caller can store it or print it. Python uses def and return; AP pseudocode uses PROCEDURE name(param) and RETURN(...). They express the same idea.

def double(n):
    return n * 2

print(double(5))
PROCEDURE double(n)
{
    RETURN(n * 2)
}

DISPLAY(double(5))

Here double is defined once with a parameter n. The call double(5) sends the value 5 into n, the body computes 5 * 2, and return hands 10 back to the caller, which then prints 10. The parameter is what lets one definition work for any number you pass.

🎯 What the exam expects

The CED (AAP-3.B) asks you to write a procedure with a parameter and a return value. On the AP reference sheet the shape is PROCEDURE name(param){ ... RETURN(expression) }. Know that RETURN both hands back a value and ends the procedure.

✍ Mini Exercise 1 • Predict the output
The procedure has a parameter and a return. What does this print?
def double(n):
    return n * 2
print(double(6))

Return vs No Return: the None Trap

A procedure only hands back a value if you actually write return. If the body computes something but never returns it, the procedure finishes and hands back the special value None. This is one of the most common bugs in early code: you compute the right answer inside the procedure, but forget to return it, so storing or printing the call gives None.

# forgot to return
def area(s):
    a = s * s

x = area(5)
print(x)
# fixed: hand back the value
PROCEDURE area(s)
{
    a <- s * s
    RETURN(a)
}

DISPLAY(area(5))

On the left, area computes a but never returns it, so x receives None and the program prints None instead of 25. The fix on the right adds RETURN(a) so the value actually leaves the procedure. Always ask: does the value I computed ever get returned?

⚠ None means "no return"

A procedure with no return statement returns None by default. So print(f(3)) shows None, and y = f(3) stores None. If your output is mysteriously None, the first thing to check is whether the procedure returned its result.

✍ Mini Exercise 2 • Why None?
Why does the segment below print None instead of 4?
def f(n):
    result = n + 1
print(f(3))

Parameters Are Local Placeholders

A parameter is a local name that exists only inside the procedure while it runs. When you call double(5), the parameter n becomes 5 for that call, then disappears when the procedure ends. A parameter is not the same variable as the one in the caller, even if they happen to share a name. Reassigning a parameter inside the body does not change the caller's variable.

The whole point of a parameter is to generalize. Instead of writing one block for a square of side 4 and another block for a square of side 7, you write one procedure with a parameter and call it with 4, then 7, then any value. One definition, many uses. That is exactly the repetition that procedures remove.

def label(score):
    if score >= 60:
        return "pass"
    else:
        return "fail"

print(label(72))
PROCEDURE label(score)
{
    IF (score >= 60)
    {
        RETURN("pass")
    }
    ELSE
    {
        RETURN("fail")
    }
}

The label procedure has a parameter score and uses selection to return one of two results. Calling label(72) returns "pass"; calling label(40) returns "fail". The parameter is what makes the single procedure answer for every possible score.

Procedural Abstraction and Its Benefits

Procedural abstraction (AAP-3.C) means giving a name to a process and then using that name without worrying about the details inside. Once double exists, you write double(5) and think "double it," not "multiply by two." The details are hidden behind the name. This is the same idea as calling print: you use it constantly without knowing how it works internally.

The benefits are practical, and the exam names them directly:

  • it removes duplicate code by naming a process once and reusing it
  • it makes a program easier to read, because a good name explains intent
  • it makes a program easier to change, because you fix the logic in one place
  • it hides the implementation detail so you can reason about what, not how

Notice what abstraction does not do: it does not change the result the program computes. Replacing three copied blocks with one procedure produces the exact same output; it just organizes the program better. That distinction is a favorite exam trap.

🎯 Say it the exam's way

If asked why a programmer wrote a procedure, strong answers mention reuse and readability: "the procedure lets the same logic be called from several places without duplicating code, and the name makes the program easier to read and modify."

✍ Mini Exercise 3 • Fill in the blank
Type the exact number this prints.
def square(n):
    return n * n
print(square(4))
prints:

Key Vocabulary

Term Definition Example
Procedure A named block of code you can call by name def double(n):
Parameter A local placeholder in the header for a value the caller supplies n in double(n)
Argument The actual value passed in at the call 5 in double(5)
Return value The result handed back with return return n * 2
None What a procedure hands back when it has no return bug: forgot return
Procedural abstraction Naming a process and hiding its details to reuse it call double, ignore how
📋 Create Performance Task • The student-developed procedure

This topic is the heart of a scored Create Task requirement. You must include a student-developed procedure that has a parameter which affects its behavior, and whose body includes both selection and iteration. A built-in call like print does not count. You have to define it yourself.

A point-earning example

A procedure that counts how many values in a list are above a cutoff, where the cutoff is the parameter that changes the result:

PROCEDURE countAbove(values, cutoff) { total <- 0 FOR EACH v IN values { IF (v > cutoff) { total <- total + 1 } } RETURN(total) }

This one procedure earns the point because it has a parameter, iteration, and selection all working together. In your written response, use these sentence stems:

  • "My procedure countAbove(values, cutoff) takes a parameter cutoff; calling it with a different cutoff produces a different count, so the parameter affects the result."
  • "The procedure uses iteration, the FOR EACH loop over values, and selection, the IF (v > cutoff) test, to build up the total."
  • "The procedure returns total, which the main program uses to decide what to display."

The trap to avoid

Do not describe a procedure that ignores its parameter, and do not forget the return. A parameter that never changes the behavior, or a procedure that computes but returns None, will not earn the point. See the full Create Task module →

📈
MCQ Practice
6 questions • Exam difficulty and above • Predict before you peek
Question 1 of 6Trace
Predict first: what value does return hand back?
What does this code segment display?
def g(x): return x * x + 1 print(g(3))
Incorrect. That would be 3 * 3 minus 2. The body is 3 * 3 + 1, which is 10.
Incorrect. 3 * 3 is 9, but the body adds 1, so it returns 10.
Correct. The call sends 3 into x, the body computes 3 * 3 + 1 = 10, and return hands 10 back to be printed.
Incorrect. There is a return statement, so the procedure hands back 10, not None.
Question 2 of 6Spot the bug
This segment is meant to print the area 25, but it does not. What does it actually print?
def area(s): a = s * s print(area(5))
Incorrect. The value 25 is computed inside a, but a is never returned, so the caller never receives it.
Correct. area computes a but has no return statement, so it hands back None by default. print(area(5)) displays None.
Incorrect. The parameter s is 5, but s itself is never printed. The call result is what prints, and that is None.
Incorrect. Forgetting return is not a syntax error. The procedure runs fine and simply returns None.
Question 3 of 6Spot the bug
Predict first: does calling f change the outer x?
What does this segment print?
x = 5 def f(x): x = x * 2 return x f(x) print(x)
Incorrect. The parameter x is a local placeholder. Doubling it inside f does not change the outer x, and the returned value was not stored.
Correct. f(x) returns 10 but that value is discarded because it is not assigned. The outer x is a separate variable and stays 5, so 5 prints.
Incorrect. The outer x was assigned 5 and is never reassigned from the call, so it prints 5, not None.
Incorrect. Reusing the name x as a parameter is legal. The outer x simply keeps its value of 5.
Question 4 of 6I, II, III
Which of the following correctly define a procedure that returns the square of its parameter?
  • I. def sq(n): return n * n
  • II. def sq(n): n * n
  • III. PROCEDURE sq(n) { RETURN(n * n) }
Incorrect. I is correct, but III also returns the square using the AP pseudocode RETURN.
Correct. I and III both hand back n * n. II computes n * n but has no return, so it returns None, not the square.
Incorrect. II lacks a return, so it hands back None instead of the square. It is not correct.
Incorrect. II has no return statement, so it does not return the square. Only I and III are correct.
Question 5 of 6NOT question
Which of the following is NOT a benefit of procedural abstraction?
Incorrect. Removing duplicate code through reuse is a real benefit of abstraction.
Incorrect. Improved readability and easier changes are genuine benefits of abstraction.
Incorrect. Hiding implementation detail is exactly what abstraction provides.
Correct. Abstraction reorganizes a program without changing what it computes. The output stays the same, so this is not a benefit it provides.
Question 6 of 6Abstraction
A programmer replaces three nearly identical blocks that each compute a different rectangle's area with one procedure area(w, h) called three times. What is the main role of the parameters w and h?
Correct. Parameters generalize a procedure. One definition of area(w, h) handles any rectangle, which is why the three duplicate blocks collapse into one.
Incorrect. Parameters generalize the code; they do not make it inherently faster. The purpose is reuse, not speed.
Incorrect. The computed areas are the same as before. Abstraction reorganizes the program without changing its output.
Incorrect. Parameters are local placeholders inside the procedure, not global variables shared with the whole program.
🎮 Lesson Game
Procedure Builder
Trace each procedure call and predict what it returns and displays. 8 rounds.
0
Correct
1/8
Round
0
Streak 🔥
🐛 Python • what does it return?
0/8
correct answers

Bonus Game: Robot Director

The dreaded robot problems, made playable. Plan a sequence of MOVE_FORWARD, ROTATE_LEFT, and ROTATE_RIGHT commands to steer the AP robot to the flag in as few commands as possible.

Robot Director

Program the AP CSP robot with MOVE_FORWARD, ROTATE_LEFT, and ROTATE_RIGHT to reach the flag.

How to play: Build a command sequence, then press Run. The robot moves one cell per MOVE_FORWARD and turns in place. It may NOT move off the grid or into a wall - solve each level in as few commands as possible.
Level
1 / 4
Stars earned
0
Program length
0 commands
Program queue (click a command to remove it)
Plan your route, then run the program. Trace each command before you press Run.
💻 Live Python Code Editor
Practice Problems
Real Python runs right here in your browser. The first time you press Run, the Python engine loads (a few seconds); after that it is instant. Problems build from guided to Create-Task level. Use Hint if you are stuck, and check your output against the target.
Hints used: 0 • Solutions viewed: 0
Level 1 • Guided
Problem 1 of 8 • define and return
Define a procedure double(n) that returns n * 2, then print the result of calling it with 6. Target output: 12
Level 2 • Parameter
Problem 2 of 8 • one definition, any input
Define square(n) that returns n * n. Print the square of 5. The parameter is what lets the same procedure square any number. Target output: 25
Level 3 • Reuse
Problem 3 of 8 • call it several times
Define cube(n) that returns n * n * n, then call it on three inputs and print each on its own line:
  • cube of 2
  • cube of 3
  • cube of 4
Target output (three lines): 8, then 27, then 64
Level 4 • Fix the bug
Problem 4 of 8 • the None trap
This should print 42, but it prints None because the procedure computes the answer without returning it. Add the missing return so it prints correctly. Target output: 42
Level 5 • Selection inside
Problem 5 of 8 • decide, then return
Define sign(n) that returns a label using selection:
  • n greater than 0: positive
  • n less than 0: negative
  • otherwise: zero
Print the result of sign(-4). Target output: negative
Level 6 • Create Task style
Problem 6 of 8 • parameter + selection + iteration
Define count_passes(scores, cutoff) that loops over the list and returns how many values are at or above cutoff. This is the kind of procedure your Create Task needs. Call it on the given list with a cutoff of 70. Target output: 3
Level 7 • Challenge
Problem 7 of 8 • you write the whole procedure
Open ended. Write the entire program yourself. Define a procedure sum_above(values, limit) that uses iteration and selection to add up only the values greater than limit, and returns that sum. Then call it on the given inputs and print the result. Target output: 38
Level 8 • Challenge
Problem 8 of 8 • one procedure, many inputs
Open ended. Write the entire program yourself. Define a procedure grade(s) that returns a letter using selection:
  • 90 or above: A
  • 80 or above: B
  • 70 or above: C
  • otherwise: F
Then loop over the given list and print the grade for each score, one per line. Target output (four lines): A, B, C, F

Frequently Asked Questions

A parameter is the placeholder name in the procedure header, like n in def double(n). An argument is the actual value you pass at the call, like 5 in double(5). The argument is copied into the parameter for that call.
It returns the special value None. So if you print or store the result of a procedure that never returns, you get None. If your output is unexpectedly None, check whether the procedure actually returned its computed value.
No. A parameter is a local placeholder that exists only while the procedure runs. Reassigning it does not affect the caller's variables, even if they share the same name. To send a result back, you must return it and the caller must store it.
Procedural abstraction means giving a name to a process and using that name without worrying about the details inside. It removes duplicate code, makes programs easier to read and change, and hides implementation detail. It does not change what the program computes; it just organizes it better.
It must be a procedure you wrote yourself with a parameter that affects its behavior, and its body must include selection and iteration. In your written response, name the parameter, point to the loop and the conditional, and explain what the procedure returns.
📦
AP CSP Teacher SuperpackSlides, lesson plans, unit tests for all 5 Big Ideas, $249
Get the Superpack →
🏫
For teachers

The Superpack includes an editable Topic 3.13 slide deck with animated call-and-return traces, a None-trap and local-parameter bug bank, a print-ready procedure-writing worksheet, and a unit quiz. View what's included →

Get in Touch

Whether you're a student, parent, or teacher — I'd love to hear from you.

Just want free AP CS resources?

Enter your email below and check the subscribe box — no message needed. Students get daily practice questions and study tips. Teachers get curriculum resources and teaching strategies.

Typically responds within 24 hours

Message Sent!

Thanks for reaching out. I'll get back to you within 24 hours.

🏫 Welcome, fellow educator!

I offer curriculum resources, practice materials, and study guides designed for AP CS teachers. Let me know what you're looking for — whether it's classroom materials, a guest speaker, or Teachers Pay Teachers resources.

Email

[email protected]

📚

Courses

AP CSA, CSP, & Cybersecurity

Response Time

Within 24 hours

Prefer email? Reach me directly at [email protected]