Evaluate comparisons first, apply NOT, AND, OR in order, and walk one branch at a time; for lists, draw the index row, mutate, then recount before the next reference.
Start every trace by fixing the values
Tracing fails most often at the start, when a value is assumed instead of read. Before touching any statement, write each variable and its current value, and update that sheet after every assignment. The left arrow copies: once a variable receives a value, later changes to the right-hand expression do not reach it. Keep one line per step so that a wrong final answer can be traced back to the exact step where your sheet diverged from the code rather than re-reading everything.
A short worked pass shows the habit. Start from values ← [4, 1, 7] and pos ← 1. INSERT(values, 1, 5) shifts 4, 1, 7 one position right and yields [5, 4, 1, 7]; REMOVE(values, 4) then deletes the value now at index 4, which is 7, leaving [5, 4, 1]. The sheet reads values = [5, 4, 1] with LENGTH 3. Re-deriving the row after each mutation, instead of editing a mental picture, is what keeps the final DISPLAY checkable from the sheet alone.
Evaluate conditions in a fixed order
Evaluate every relational comparison to true or false first, then apply NOT, then AND, then OR. Two boundary habits prevent most condition errors: test the boundary value itself against >=, <=, > and <, and remember that = inside a condition compares while the left arrow assigns. When NOT appears, mark its exact scope, usually one parenthesized comparison, before evaluating anything outside that scope.
Try the gate IF(NOT (hours < 3) AND paid) with hours ← 2 and paid ← true. Inside the parentheses, hours < 3 is true; NOT turns it false; false AND true is false, so the IF block does not run. Repeat with hours ← 5: the comparison becomes false, the NOT true, and the AND true, flipping the branch. Re-running a trace with one changed value shows which operand actually controls the outcome, which is more informative than memorizing the first result.
Handle branches one decision at a time
Selection never splits: an IF/ELSE runs exactly one of its blocks, and a plain IF runs zero or one block. For nested selection, resolve the outer decision before reading the inner one, and note which branch owns the inner test. A false outer condition does not skip an ELSE that exists; it selects it. When two separate IF statements follow each other, both are tested independently, so an output of one line followed by a fallback line is entirely possible.
Practice on a parking rule: IF(hours < 3) { fee ← 7 } ELSE { fee ← 12 } with hours ← 2 selects the IF branch and sets fee to 7. Change only the comparison to hours <= 3: the outcome at 2 is unchanged, but at exactly 3 it flips, because <= includes 3 and < does not. Knowing where the boundary sits and testing that exact value turns an ambiguous-feeling conditional into two one-line checks.
Mutate lists on a drawn index row
Draw the index row 1 through LENGTH above the values, then apply one operation per line. INSERT shifts elements at indices >= i one position right and grows the length by 1; REMOVE shifts elements after i one position left and shrinks the length by 1; APPEND never shifts anything. After each operation, redraw the row before any later statement refers to a position, because the meaning of an index moves with every shift.
FOR EACH visits elements first to last and always makes LENGTH passes; the loop variable is a copy of the element, so updates must target positions rather than the loop variable. Close with one final habit: after finishing a trace, re-derive the answer once more from the first line without looking at your sheet. If the two passes disagree, the disagreement points at the exact step to restudy, which is far more useful than a third passive reread of the code.
Apply the guide
A library kiosk sets late ← false and runs IF(NOT late AND items < 5) { DISPLAY("borrow") } ELSE { DISPLAY("review") } with items ← 3. Which branch runs, and which single value change would flip it?Reveal explanation
The IF block runs: NOT false is true, 3 < 5 is true, so true AND true displays borrow. Setting late ← true makes the AND false and sends control to review without touching items.
Start from tray ← [6, 2, 8] and run INSERT(tray, 2, 4) followed by REMOVE(tray, 1). State the list and its length after each step.Reveal explanation
After INSERT the list is [6, 4, 2, 8] with LENGTH 4, because 2 and 8 shifted right. After REMOVE at index 1 it is [4, 2, 8] with LENGTH 3.
Turn the idea into practice.
Apply the rule to a new case, then explain your choice.
Practice this skillSources & authorship
Conceptual facts checked against linked references; all teaching scenarios, comparisons and tasks are original. No textbook prose, pictures or exercises reproduced.
Original OpenExam guide
Independent educator review is pending. This guide is not an official exam paper or a video transcript.
AP Computer Science Principles Exam Reference Sheet (PDF)