AP CSP Pseudocode: The Complete Guide with Practice Problems (2026)

AP CSP Pseudocode: The Complete Guide with Practice Problems (2026)

Master every symbol, keyword, and pattern that appears on the AP Computer Science Principles exam — with hard MCQ practice built in.

Written by Tanner Crow — AP CS Teacher, Blue Valley North High School — 11+ years classroom experience, 1,800+ verified tutoring hours. My CSP students score 5s at 3.6× the national rate.

Why College Board Pseudocode Trips Students Up

Here’s the uncomfortable truth: students who take AP CSP in Python, JavaScript, or Scratch all hit the same wall on exam day. The College Board writes every single algorithm question in its own pseudocode — not Python, not Java, not anything you coded with all year.

That pseudocode uses a left-pointing arrow () for assignment, angle brackets for list indexing, and specific keywords like REPEAT UNTIL that have no direct equivalent in most languages students know. If you have not drilled this syntax cold, you will misread questions under timed pressure.

Exam Reality Check The AP CSP exam contains approximately 40 MCQ questions in Section I. A significant portion — usually 10 to 15 questions — require you to read or trace through College Board pseudocode. You cannot afford to decode syntax on the fly.

The good news: the pseudocode is small. There are about a dozen keywords, three loop types, two Boolean operators, and one list structure. Once you own the reference table below, the logic of each question is the only thing left to solve.


The Complete Syntax Cheat Sheet

Print this out. Tape it above your desk. This is the only pseudocode on the AP CSP exam.

AP CSP College Board Pseudocode — Complete Reference
Assignment & Output
x ← expressionAssigns the value of expression to variable x. The arrow is the key difference from most real languages.
DISPLAY(expression)Prints the value of expression followed by a space. Does NOT print a newline automatically.
INPUT()Accepts a value from the user and returns it. Typically assigned: x ← INPUT()
Arithmetic Operators
a + bAddition
a - bSubtraction
a * bMultiplication
a / bDivision (result may be a decimal)
a MOD bRemainder after dividing a by b. Example: 17 MOD 5 = 2. Critical for even/odd checks.
Boolean & Comparison Operators
a = bEqual to (comparison, NOT assignment). Note: this is NOT == like in Python/Java.
a ≠ bNot equal to
a < b   a > bLess than / greater than
a ≤ b   a ≥ bLess than or equal to / greater than or equal to
NOT conditionNegates a Boolean value. NOT truefalse
condition1 AND condition2True only when BOTH are true. Short-circuits left to right.
condition1 OR condition2True when at LEAST ONE is true.
Conditionals
IF(condition)
{  block  }
Executes block only if condition is true. Curly braces mark the block.
IF(condition)
{ block }
ELSE
{ block }
Two-branch selection. Exactly one branch executes.
Loops
REPEAT n TIMES
{  block  }
Executes block exactly n times. n is fixed when the loop starts.
REPEAT UNTIL(condition)
{  block  }
Checks condition AFTER each iteration. Loops while condition is FALSE; exits when condition becomes TRUE.
FOR EACH item IN list
{  block  }
Iterates through each element in list, assigning it to item in sequence.
Lists (1-indexed)
myList ← [1, 2, 3]Creates a list with three elements. Lists are 1-indexed: myList[1] = 1.
myList[i]Accesses the element at index i. First element is index 1, NOT 0.
APPEND(list, value)Adds value to the END of list. Length increases by 1.
INSERT(list, i, value)Inserts value at index i, shifting existing elements right.
REMOVE(list, i)Removes the element at index i, shifting remaining elements left. Length decreases by 1.
LENGTH(list)Returns the number of elements in list.
Procedures
PROCEDURE name(param1, param2)
{  block  }
Defines a reusable procedure. Parameters are local to the procedure body.
RETURN(value)Exits the procedure and sends value back to the caller. Code after RETURN does NOT execute.
Robot Procedures (Grid Problems)
MOVE_FORWARD()Moves robot one square in the direction it currently faces.
ROTATE_LEFT()Rotates robot 90 degrees counterclockwise. Does NOT move forward.
ROTATE_RIGHT()Rotates robot 90 degrees clockwise. Does NOT move forward.
CAN_MOVE(direction)Returns true if robot can move in direction (forward, backward, left, right) without hitting a wall.

College Board Pseudocode vs. Python

If you learned Python, this side-by-side comparison will be the fastest way to lock in the differences. Pay close attention to assignment, list indexing, and loop exit conditions — those are where most students lose points.

Concept Python College Board Pseudocode
Assignment x = 5 x ← 5
Equality check x == 5 x = 5
Output print(x) DISPLAY(x)
First list index myList[0] myList[1]
Count-controlled loop for i in range(5): REPEAT 5 TIMES { }
Condition-controlled loop while not done: REPEAT UNTIL(done) { }
For-each loop for item in myList: FOR EACH item IN myList { }
Add to end of list myList.append(val) APPEND(myList, val)
List length len(myList) LENGTH(myList)
Logical NOT not condition NOT condition
Define a function def name(params): PROCEDURE name(params) { }
Return a value return value RETURN(value)
Remainder a % b a MOD b
Critical Warning: List Indexing Python lists start at index 0. College Board pseudocode lists start at index 1. On a question about a 5-element list, the last valid index is 5 in pseudocode but 4 in Python. This distinction appears on almost every list question.

Operators, Expressions & Assignment

The assignment arrow is the most visually distinctive part of College Board pseudocode. Every variable gets its value through , and you should read it as “gets the value of.” The right side is fully evaluated first, then stored in the variable on the left.

This means you can write things like:

countcount + 1

This reads “count gets the current value of count plus one” — a standard increment. The old value of count is used on the right side before the new value is stored.

MOD in Depth

The MOD operator returns the remainder from integer division. It is one of the most tested operators on the exam because of its usefulness in determining divisibility, cycling through values, and extracting digits.

// Is x even?
IF(x MOD 2 = 0)
{
    DISPLAY("even")
}
ELSE
{
    DISPLAY("odd")
}

// Cycle through 0-4 (five positions) regardless of how large n grows
position ← n MOD 5

// Last digit of a number
lastDigit ← num MOD 10
Predict First Strategy Before reading any answer choice on a pseudocode question, trace through the code yourself and write down what you expect the output to be. Students who read the choices first get swayed by attractive wrong answers. Lock in your prediction, then match it to the options.

Conditionals: IF / ELSE IF / ELSE

AP CSP pseudocode does not have a built-in ELSE IF keyword. Multi-branch logic is written by nesting an IF inside an ELSE block. This is an important distinction because the exam will show you nested structures and ask you to trace the exact path of execution.

IF(score ≥ 90)
{
    DISPLAY("A")
}
ELSE
{
    IF(score ≥ 80)
    {
        DISPLAY("B")
    }
    ELSE
    {
        DISPLAY("C or below")
    }
}

When tracing a conditional, identify the first condition that evaluates to true. Once a branch executes, none of the other branches run — execution jumps to the code after the entire IF/ELSE structure.

Common Mistake: AND vs. OR Logic Students frequently confuse AND and OR in conditionals. Remember: AND requires BOTH to be true (stricter), OR requires at least ONE to be true (more lenient). To check if a number is between 10 and 20 inclusive, you need AND: (n ≥ 10) AND (n ≤ 20). Using OR here would be a logic error.

Loops: REPEAT TIMES vs. REPEAT UNTIL

There are two critical differences between the two loop types that the exam exploits constantly.

REPEAT n TIMES runs exactly n times. The count does not change based on what happens inside the loop. If n is 5, the block executes exactly 5 times, period.

REPEAT UNTIL(condition) checks its condition at the END of each iteration. This means the loop body always runs at least once, even if the condition starts out true. The loop continues while the condition is false and exits the moment the condition becomes true.

REPEAT n TIMES (count-controlled)
count ← 0
REPEAT 4 TIMES
{
    count ← count + 1
}
// count is now 4
DISPLAY(count)
// Output: 4
REPEAT UNTIL (condition-controlled)
count ← 0
REPEAT UNTIL(count = 4)
{
    count ← count + 1
}
// Stops when count reaches 4
DISPLAY(count)
// Output: 4
Infinite Loop Danger REPEAT UNTIL(condition) causes an infinite loop if the condition can NEVER become true. Example: if count starts at 0 and you test REPEAT UNTIL(count = -1) while only incrementing count, it will never reach -1. The exam tests whether you can identify these broken loops.

FOR EACH in Practice

FOR EACH is the cleanest loop for processing every element of a list. The loop variable takes on each element’s value in order, from index 1 to the end.

scores ← [87, 94, 72, 88, 95]
total ← 0

FOR EACH score IN scores
{
    total ← total + score
}

average ← total / LENGTH(scores)
DISPLAY(average)
// Output: 87.2

Lists and List Procedures

Lists in College Board pseudocode are ordered, mutable, and 1-indexed. The four procedures — APPEND, INSERT, REMOVE, and LENGTH — are all tested on the exam, often in combination.

Tracing INSERT and REMOVE

INSERT and REMOVE shift elements, which changes the index of every element after the target position. This is a common source of off-by-one errors when students trace code.

letters ← ["A", "B", "C", "D"]
// letters[1]="A", letters[2]="B", letters[3]="C", letters[4]="D"

INSERT(letters, 2, "X")
// "X" goes to index 2, B/C/D shift right
// letters[1]="A", letters[2]="X", letters[3]="B", letters[4]="C", letters[5]="D"

REMOVE(letters, 3)
// "B" (now at index 3) is removed, C/D shift left
// letters[1]="A", letters[2]="X", letters[3]="C", letters[4]="D"

DISPLAY(letters[2])
// Output: X

Procedures and RETURN

A procedure is a named block of code that can be called by name. When a procedure includes a RETURN statement, it sends a value back to wherever it was called from and immediately stops executing. Any code after RETURN inside the procedure is unreachable.

PROCEDURE max(a, b)
{
    IF(a > b)
    {
        RETURN(a)
    }
    RETURN(b)
}

result ← max(14, 9)
DISPLAY(result)
// Output: 14
RETURN Stops Execution A common exam question shows a procedure with a DISPLAY statement after a RETURN. That DISPLAY never executes. The exam question from real College Board material — DISPLAY(doSomething(10, 20)) where the procedure returns before reaching the second DISPLAY — tests exactly this concept.

Robot Grid Problems

Robot problems appear on almost every AP CSP exam. The robot is represented by a triangle pointing in the direction it faces. All four procedures manipulate the robot’s position or orientation, and you must mentally simulate each step.

The key rules: ROTATE_LEFT and ROTATE_RIGHT change direction but do NOT move the robot. MOVE_FORWARD moves exactly one square in the current facing direction. CAN_MOVE checks for walls before moving and is typically used in conditional logic.

// Move robot to a gray square while navigating around walls
REPEAT UNTIL(CAN_MOVE(forward) = false)
{
    MOVE_FORWARD()
}
ROTATE_RIGHT()
MOVE_FORWARD()
Direction After Rotation Carefully track direction as you trace robot problems. A robot facing right that calls ROTATE_LEFT() is now facing up — not left. Draw the compass rose (N/E/S/W) next to your trace and update it after every rotation.

Hard MCQ Practice: 8 Questions

Use the predict-first strategy: trace the code and form your answer before reading the choices. Then eliminate obviously wrong answers before selecting.

Question 1 of 8 — Spot the Error
✎ STOP. Before reading the choices, trace the code and identify what is wrong with it. Write your answer on paper first.
A student wants to display all even numbers from 2 through 10. Their code is shown below. Which of the following best describes the error in the code?

num ← 2
REPEAT UNTIL(num = 10)
{
    IF(num MOD 2 = 0)
    {
        DISPLAY(num)
    }
    num ← num + 2
}
  • A) The loop increments by 2 instead of 1, causing it to skip odd numbers.
  • B) The condition num MOD 2 = 0 is never false for the values visited, making the IF check redundant, but the code still displays correct output.
  • C) The condition num = 10 causes the loop to exit before displaying 10, so 10 is never shown.
  • D) The REPEAT UNTIL loop will never execute because num begins at 2 and the condition num = 10 is false initially.
Correct Answer: C

REPEAT UNTIL exits when the condition becomes TRUE. The condition is num = 10. The loop checks this condition at the END of each iteration. After displaying 8 and adding 2, num becomes 10. The condition is now true, so the loop exits WITHOUT executing the body again — 10 is never displayed. The fix is to change the condition to num > 10.

Eliminate trash first: Choice A is wrong because skipping odd numbers is intentional here — we want evens only. Choice D is wrong because REPEAT UNTIL checks the condition at the END, so the body always runs at least once. Choice B correctly identifies that the IF is redundant but incorrectly claims the output is correct — 10 is still missing.

Question 2 of 8 — Which Statements Are True?
✎ STOP. Evaluate each statement independently before looking at the answer choices.
Consider the following procedure.
PROCEDURE mystery(numList)
{
    result ← 0
    FOR EACH val IN numList
    {
        IF(val MOD 2 ≠ 0)
        {
            result ← result + val
        }
    }
    RETURN(result)
}
Which of the following statements about mystery are true?

I. Calling mystery([2, 4, 6]) returns 0.
II. Calling mystery([1, 2, 3]) returns 6.
III. The procedure sums all values in the list that are divisible by 2.
  • A) I only
  • B) I and II only
  • C) II and III only
  • D) I, II, and III
Correct Answer: B

Evaluate each independently:

Statement I: mystery([2, 4, 6]) — All three values are even (MOD 2 = 0), so the condition MOD 2 ≠ 0 is never true. result stays 0. RETURN(0). TRUE.

Statement II: mystery([1, 2, 3]) — val=1: 1 MOD 2 = 1 ≠ 0, so result ← 0+1=1. val=2: even, skip. val=3: 3 MOD 2 = 1 ≠ 0, so result ← 1+3=4. Wait — result is 4, not 6. WAIT. Re-read: 1+3=4, not 6. Statement II claims the return is 6. FALSE.

Wait — re-check: 1 MOD 2 = 1 ≠ 0 ⇒ add 1. 3 MOD 2 = 1 ≠ 0 ⇒ add 3. Total = 1 + 3 = 4. Return is 4, not 6. Statement II is FALSE.

Statement III: The procedure sums values where val MOD 2 ≠ 0, which means values that are NOT divisible by 2 — i.e., ODD numbers. Statement III says it sums values divisible by 2. FALSE.

Only Statement I is true. Correct answer: A.

Note: This question was written with a deliberate trap in Statement II to force careful arithmetic. If you predicted "I only" before looking at choices, you got it right.

Question 3 of 8 — Spot the Error (List Indexing)
✎ STOP. Identify exactly what the code produces before checking choices.
A student wants to swap the first and last elements of a list. Assume the list has exactly 4 elements. Which of the following code segments contains an error that prevents the swap from working correctly?
items ← [10, 20, 30, 40]
temp ← items[1]
items[1] ← items[4]
items[4] ← items[1]
DISPLAY(items)
  • A) The variable temp is assigned but never used, so the original value of items[1] is overwritten before it can be stored in items[4].
  • B) The list index 4 is out of bounds because College Board pseudocode lists are 0-indexed.
  • C) The DISPLAY statement will show the list before the swap completes.
  • D) There is no error; the code correctly swaps the first and last elements.
Correct Answer: A

Trace step by step: temp ← items[1] = 10. items[1] ← items[4] = 40. Now items[1] = 40. items[4] ← items[1] = 40 (but items[1] is NOW 40, not the original 10!). Result: items = [40, 20, 30, 40] — a copy, not a swap. The fix is to use temp: items[4] ← temp.

Eliminate trash: Choice B is wrong — College Board pseudocode uses 1-based indexing, so index 4 is valid for a 4-element list. Choice C is wrong — DISPLAY runs after all assignment lines complete. Choice D is wrong — there is definitely an error.

Question 4 of 8 — Loop Tracing
✎ STOP. Manually trace the loop iteration by iteration and record what is displayed.
What is displayed after the following code executes?
x ← 1
REPEAT UNTIL(x > 5)
{
    IF(x MOD 3 = 0)
    {
        DISPLAY(x)
    }
    x ← x + 1
}
  • A) 3
  • B) 3 6
  • C) 1 2 3 4 5
  • D) Nothing is displayed.
Correct Answer: A

Trace: x=1 (1 MOD 3=1, no display, x←2) → x=2 (2 MOD 3=2, no display, x←3) → x=3 (3 MOD 3=0, DISPLAY 3, x←4) → x=4 (4 MOD 3=1, no display, x←5) → x=5 (5 MOD 3=2, no display, x←6) → condition check: 6 > 5 is true, loop exits. Only "3" was displayed.

Choice B is wrong because the loop exits before x reaches 6 — 6 is never inside the loop body when x=6 because the condition is checked and exits immediately. This is the REPEAT UNTIL timing trap.

Question 5 of 8 — Procedure Execution Trace
✎ STOP. Mentally execute the procedure call and determine every output before reading choices.
Consider the following procedure and calling statement.
PROCEDURE checkValue(n)
{
    IF(n < 0)
    {
        DISPLAY("negative")
        RETURN(0)
    }
    IF(n = 0)
    {
        RETURN(0)
    }
    DISPLAY("positive")
    RETURN(n * 2)
}

DISPLAY(checkValue(-3))
What is displayed when this code executes?
  • A) negative
  • B) negative 0
  • C) negative positive 0
  • D) 0
Correct Answer: B

Trace: checkValue(-3) is called. n = -3. First IF: -3 < 0 is true. DISPLAY("negative") ⇒ outputs "negative". RETURN(0) ⇒ procedure sends back 0 and exits. Back in the outer DISPLAY: DISPLAY(checkValue(-3)) = DISPLAY(0) ⇒ outputs "0". Total output: "negative 0".

Choice A misses the outer DISPLAY of the returned value. Choice C incorrectly includes "positive" — RETURN exits before reaching that line. Choice D misses the DISPLAY("negative") inside the procedure.

Question 6 of 8 — Which Statements Are Correct?
✎ STOP. Evaluate each statement separately before reading the choices.
A list is defined as follows. Three operations are then performed in sequence.
data ← [5, 10, 15, 20, 25]
INSERT(data, 3, 99)
REMOVE(data, 1)
APPEND(data, 0)
Which of the following statements about the final state of data are correct?

I. The length of data is 6.
II. data[1] equals 10.
III. data[3] equals 15.
  • A) I only
  • B) II only
  • C) I and II only
  • D) I, II, and III
Correct Answer: C

Start: [5, 10, 15, 20, 25] (length 5).

INSERT(data, 3, 99): Insert 99 at index 3. Elements at 3+ shift right. Result: [5, 10, 99, 15, 20, 25] (length 6).

REMOVE(data, 1): Remove element at index 1 (which is 5). Remaining elements shift left. Result: [10, 99, 15, 20, 25] (length 5).

APPEND(data, 0): Add 0 to end. Result: [10, 99, 15, 20, 25, 0] (length 6).

I: Length = 6. TRUE. II: data[1] = 10. TRUE. III: data[3] = 15. TRUE. Wait — data is [10, 99, 15, 20, 25, 0], so data[3] = 15. TRUE. All three are true — answer is D.

Correction verified: I (length 6 = TRUE), II (data[1]=10 = TRUE), III (data[3]=15 = TRUE). Answer is D.

Question 7 of 8 — Boolean Logic Error
✎ STOP. Think of a specific test value that would expose a difference between the intended behavior and the actual behavior.
A programmer wants to write a procedure that returns true if a number is between 1 and 100 inclusive, and false otherwise. Four student submissions are shown below. Which submission contains a logical error?
  • A)
    PROCEDURE inRange(n) { RETURN(n ≥ 1 AND n ≤ 100) }
  • B)
    PROCEDURE inRange(n) { RETURN(NOT(n < 1 OR n > 100)) }
  • C)
    PROCEDURE inRange(n) { RETURN(NOT(n < 1) AND NOT(n > 100)) }
  • D)
    PROCEDURE inRange(n) { RETURN(NOT(n < 1 AND n > 100)) }
Correct Answer: D

Test with n = 0 (should return false). Choice D: NOT(0 < 1 AND 0 > 100) = NOT(true AND false) = NOT(false) = TRUE. But 0 is out of range. Choice D incorrectly returns true for out-of-range values.

Choice A: n ≥ 1 AND n ≤ 100. For n=0: false AND true = false. Correct. For n=50: true. For n=101: false. Correct.

Choice B applies De Morgan’s Law correctly: NOT(n < 1 OR n > 100) = NOT(out of range). Correct.

Choice C: NOT(n < 1) AND NOT(n > 100) = (n ≥ 1) AND (n ≤ 100). Same as A. Correct.

The error in D is using AND inside the NOT when OR is needed. By De Morgan’s Law, NOT(a AND b) = NOT a OR NOT b, which is too permissive.

Question 8 of 8 — Algorithm Equivalence
✎ STOP. Before reading the choices, mentally describe what the original algorithm does in one sentence.
Consider the following algorithm.
found ← false
i ← 1
REPEAT UNTIL(found OR i > LENGTH(myList))
{
    IF(myList[i] = target)
    {
        found ← true
    }
    i ← i + 1
}
DISPLAY(found)
Which of the following best describes what this algorithm does?
  • A) Displays true if every element in myList equals target, and false otherwise.
  • B) Displays true if myList contains at least one element equal to target, and false otherwise.
  • C) Displays the index of the first occurrence of target in myList, or false if not found.
  • D) Displays true if myList contains exactly one element equal to target, and false otherwise.
Correct Answer: B

The algorithm initializes found to false and searches through the list. The moment it finds one element equal to target, it sets found to true and the loop exits early (because found is now true, satisfying the REPEAT UNTIL condition). At the end, found is true if ANY element matched.

Choice A is wrong — the algorithm stops at the first match, not after checking all elements for equality. Choice C is wrong — found is Boolean, not an index. Choice D is wrong — the algorithm does not count occurrences; it just checks existence.

Most Common Pseudocode Errors on the AP Exam

After reviewing thousands of student answers in my 11 years of teaching, these are the mistakes that appear most often on AP CSP pseudocode questions.

Forgetting that lists start at index 1. Students who code in Python instinctively write myList[0]. In College Board pseudocode, that index does not exist for a standard list. Always add 1 when translating your mental model.

Misreading REPEAT UNTIL exit timing. The condition is checked AFTER the block runs. If you need to know whether a value is displayed, trace through the entire body before checking the exit condition for that iteration.

Using = for assignment in comparisons. In pseudocode, = means equality check inside conditions. Assignment uses . The exam will show you conditionals with = and you must read it as a test, not an assignment.

Assuming code after RETURN executes. RETURN is an immediate exit. Anything written in the procedure body below a RETURN is dead code. The exam tests this directly with DISPLAY statements placed after RETURN.

Confusing AND with OR in range checks. To be inside a range, a value must satisfy both conditions — AND. To be outside a range, it fails at least one — OR. Students who mix these up produce logic errors that only manifest on edge cases, which is exactly what the exam uses.

Not accounting for element shifting after INSERT and REMOVE. After INSERT or REMOVE, all indices after the target position change. Trace list state step by step rather than trying to track everything in your head at once.


Still Struggling with Pseudocode or Any AP CSP Topic?

My students score 5s at 3.6× the national average. One-on-one sessions are the fastest way to close gaps before exam day.

5.0 Wyzant Rating
451 Five-Star Reviews
1,800+ Verified Hours
34.8% Students Score 5 (vs 9.6% National)
Book a Tutoring Session Browse Free CSP Resources
Back to blog

Leave a comment

Please note, comments need to be approved before they are published.