SECTION 1
Why Explaining Code Matters
Programming has never been a solo activity. From the earliest days of computing, engineers had to communicate what their code does to teammates, managers, and future developers who would maintain it. Writing code that works is only half the job — the other half is being able to explain why it works, step by step, using the correct vocabulary. This skill is called code tracing or code narration, and it is one of the most important abilities you can develop as a programmer.
1842 • Ada Lovelace's Notes
1972 • Literate Programming Proposed
1991 • Python Released
2000s • Code Reviews Become Standard
2020s • AI and Communication
The central question this lesson addresses is: How do you take a piece of Python code and explain, line by line, exactly what happens when the computer runs it — using precise Python terminology? Whether you are preparing for an AP exam, participating in a code review, or debugging a tricky function, this skill will be your foundation.
SECTION 2
Core Principles of Code Explanation
Explaining code behavior is not simply restating the code in English — it means describing what the Python interpreter does at each step, using the correct terminology. A strong code explanation uses words like assignment, evaluation, call, return, and iteration rather than vague phrases like "the computer does stuff." Here are five foundational principles.
Use Precise Python Vocabulary
x is assigned the integer 5" instead of "x becomes 5." Use terms like expression, statement, and object.Follow Execution Order
Track State Changes
Distinguish Expressions from Statements
3 + 4). A statement performs an action (like x = 7). Understanding this distinction sharpens your explanations.Explain the 'Why,' Not Just the 'What'
KEY TAKEAWAY
SECTION 3
Visualizing Code Execution Flow
The diagram below shows how the Python interpreter processes a simple program that includes a variable assignment, a conditional statement, and a function call. Each numbered step shows the execution flow — the actual path through the code — with arrows indicating the order of operations. Notice how the interpreter evaluates the condition before deciding which branch to execute.
Notice that the program has eight lines of code, but only five steps actually execute. When you explain code behavior, you must follow the interpreter's path, not just read the source file from top to bottom. In this example, line 1 performs an assignment, lines 2 and 4 perform conditional evaluation, line 5 performs another assignment, and line 8 makes a function call. Lines 3, 6, and 7 are never reached because their conditions were not met.
SECTION 4
The Vocabulary of Python Execution
To explain code well, you need a toolkit of precise Python terms. Think of these as the "grammar" of code narration. Each term describes a specific action the interpreter performs. Let's break down the most essential vocabulary, organized by category.
Variable Operations
Assignment is when a variable name is bound to a value using the = operator. For example, x = 10 means "the variable x is assigned the integer value 10." When a variable name is used on the right side of an expression, we say it is evaluated or referenced — the interpreter looks up the current value bound to that name.
Expressions and Evaluation
An expression is any piece of code that evaluates to a value. Examples include 3 + 4 (evaluates to 7), len("hello") (evaluates to 5), and x > 0 (evaluates to True or False). When you describe an expression, say what it evaluates to, not what it "equals" — because evaluation is an active process performed by the interpreter.
Control Flow
Control flow describes how the interpreter decides which lines to run next. An if statement performs a conditional check — it evaluates a Boolean expression and enters the indented block only if the result is True. A for loop performs iteration — it repeats its body once for each element in an iterable (like a list or range).
Functions
When you use a function like print("hello"), you are making a function call. The value inside the parentheses is the argument. When a function is defined with def, the names in parentheses are called parameters. The function may execute a return statement, which sends a value back to the caller.
| Python Term | What It Means | Example Narration |
|---|---|---|
assignment | Binding a value to a variable name | "The variable count is assigned the integer 0." |
evaluation | Computing the result of an expression | "The expression x + 1 evaluates to 6." |
iteration | Repeating a block for each item in a sequence | "The for loop iterates over the list, assigning each element to item." |
function call | Invoking a function with arguments | "The function len() is called with the list as its argument, returning 4." |
return | Sending a value back from a function | "The function returns the string "B" to the caller." |
conditional check | Testing a Boolean expression to decide which branch to take | "The condition n > 0 evaluates to True, so the if-block executes." |
Essential Python Terminology for Code Explanation
SECTION 5
Building a Trace Table
A trace table is a structured way to track exactly what happens at each step of program execution. You create columns for each variable and for any output, then fill in a new row each time the state changes. This is especially helpful for loops, where variables change value multiple times. Let's trace through a loop-based program using a trace table.
num and total through each step of the loop. The rightmost column provides a narration using proper Python terminology for each state change.A well-built trace table reveals patterns that might be invisible from reading the code alone. In the example above, you can clearly see how total grows with each iteration — from 0, to 2, to 7, and finally to 10. Each iteration of the for loop assigns the next element from the list [2, 5, 3] to the loop variable num, then the body evaluates total + num and reassigns the result back to total. This pattern is called an accumulator pattern, and being able to name it shows a deeper level of understanding.
Pro Tip: Building Your Own Trace Tables
SECTION 6
Worked Example: Narrating a Function
Let's walk through a complete code narration for a program that defines and calls a function. The code below defines a function called is_even and uses it inside a loop to filter a list of numbers. We will explain every step using proper Python terminology.
Narrating: Function Definition, Call, and Loop
- 1
Step 1 — Read the Code
The program consists of the following lines:def is_even(n):return n % 2 == 0numbers = [4, 7, 2, 9]evens = []for num in numbers:if is_even(num):evens.append(num)print(evens) - 2
Step 2 — Function Definition (Line 1–2)
The interpreter encounters thedefkeyword and defines a function namedis_evenwith one parameter calledn. The function body is not executed yet — it is simply stored in memory for later use.Functionis_evenis defined and stored. - 3
Step 3 — Variable Assignments (Lines 3–4)
The variablenumbersis assigned a list containing four integers:[4, 7, 2, 9]. The variableevensis assigned an empty list[]. This empty list will serve as an accumulator for even numbers.numbers → [4, 7, 2, 9],evens → [] - 4
Step 4 — First Iteration (num = 4)
Theforloop begins iterating overnumbers. The loop variablenumis assigned the value 4. Theifstatement callsis_even(4). Inside the function,nreceives the argument 4. The expression4 % 2 == 0evaluates toTrue(since 4 modulo 2 is 0). The function returnsTrue. Because the condition isTrue, the methodevens.append(4)is called, adding 4 to the list.evens → [4] - 5
Step 5 — Remaining Iterations
Iteration 2:num = 7. The function callis_even(7)evaluates7 % 2 == 0→False. The if-block is skipped. Iteration 3:num = 2.is_even(2)returnsTrue, soevens.append(2)is called. Iteration 4:num = 9.is_even(9)returnsFalse. The if-block is skipped.evens → [4, 2] - 6
Step 6 — Output (Final Line)
After the loop completes (no more elements in the list), execution moves to theprint(evens)statement. The built-in functionprint()is called with the list[4, 2]as its argument. The output displayed to the console is[4, 2].Output:[4, 2]
PATTERN RECOGNITION
SECTION 7
Good Explanations vs. Common Mistakes
Not all code explanations are created equal. Beginners often fall into common traps: using vague language, restating the code word-for-word without adding understanding, or skipping over important state changes. The table below contrasts weak explanations with strong ones so you can recognize the difference.
| Code | ❌ Weak Explanation | ✅ Strong Explanation |
|---|---|---|
x = 5 | "x is 5." | "The variable x is assigned the integer value 5." |
if x > 3: | "It checks if x is bigger than 3." | "The condition x > 3 is evaluated. Since x is 5, the expression evaluates to True, so the if-block executes." |
for i in range(3): | "It loops 3 times." | "The for loop iterates over range(3), which produces the sequence 0, 1, 2. On each iteration, i is assigned the next value." |
print(len(s)) | "It prints the length." | "The function len() is called with s as its argument, returning the number of characters. That return value is then passed to print(), which outputs it." |
result = f(x) | "result gets the answer." | "The function f is called with x as the argument. The return value of f(x) is then assigned to the variable result." |
Comparison of Weak vs. Strong Code Explanations
THE LITMUS TEST
- ✓ Name the operation: assignment, evaluation, function call, iteration, conditional check, return
- ✓ Specify the data type: "the integer 5" not just "5"; "the string 'hello'" not just "hello"
- ✓ State the result: what value was produced, what variable changed, or what was output
- ✓ Mention skipped code: explicitly note when branches are not taken or loops terminate early
SECTION 8
Connecting to Advanced Communication Skills
The ability to explain code behavior step-by-step is not just a classroom exercise — it's the foundation of several professional skills. As you progress in computer science, you will encounter situations where precise code narration becomes even more critical: debugging sessions, code reviews, documentation writing, and technical interviews.
| This Lesson's Skill | Advanced Application | Why It Matters |
|---|---|---|
| Tracing execution order | Debugging — stepping through code with a debugger | You can't fix a bug if you can't describe what the code actually does vs. what you expected it to do. |
| Using precise vocabulary | Code reviews — giving feedback on teammates' code | Clear, specific language prevents misunderstandings and helps the author understand your feedback. |
| Tracking state changes | Unit testing — verifying expected vs. actual outputs | Tests are assertions about state: "After calling this function with input X, the result should be Y." |
| Explaining purpose (the "why") | Documentation & comments — writing for future developers | Good documentation explains intent, not just mechanics. This starts with the ability to articulate both. |
| Step-by-step narration | Technical interviews — explaining your solution aloud | Interviewers evaluate your thought process. Narrating your code demonstrates understanding beyond just getting the right answer. |
How Step-by-Step Explanation Connects to Professional Skills
In more advanced courses, you will also learn about time complexity analysis (describing how many operations a program performs), recursion tracing (explaining functions that call themselves), and object-oriented design communication (describing how classes and objects interact). All of these build directly on the step-by-step explanation skills you are developing now.
SECTION 9
Practice Problems
Question 1: CONCEPTUAL
Show answer
3 + 4 (which evaluates to 7) or x > 0 (which evaluates to True or False). A statement is a complete instruction that performs an action, such as x = 10 (an assignment statement) or print('hi') (a function call statement). The distinction matters because when narrating, you should say an expression "evaluates to" a value, while a statement "performs" an action like assignment or output. Confusing the two leads to imprecise explanations.Question 2: BASIC
a = 3
b = a * 2
a = a + b
print(a)Show answer
a is assigned the integer 3. Step 2: The expression a * 2 is evaluated — since a references the value 3, this evaluates to 6. The variable b is assigned the integer 6. Step 3: The expression a + b is evaluated — 3 + 6 evaluates to 9. The variable a is reassigned to the integer 9. Step 4: The built-in function print() is called with the current value of a (9) as its argument. Output: 9.Question 3: INTERMEDIATE
result = ""
for ch in "cat":
result = result + ch.upper()
print(result)Show answer
result is assigned an empty string "". Step 2 (iter 1): The for loop assigns ch = "c". The method ch.upper() is called, returning "C". String concatenation "" + "C" evaluates to "C", which is assigned to result. Step 3 (iter 2): ch = "a", .upper() returns "A", result becomes "CA". Step 4 (iter 3): ch = "t", .upper() returns "T", result becomes "CAT". Step 5: print(result) outputs CAT. This is an accumulator pattern that builds a new string by concatenating uppercase versions of each character.Question 4: APPLIED
def find_max(lst):
biggest = 0
for num in lst:
if num > biggest:
biggest = num
return biggest
print(find_max([-3, -1, -7]))
Expected output: -1. Actual output: 0Show answer
find_max is defined with parameter lst. When called with [-3, -1, -7], biggest is assigned 0. During iteration, each element (−3, −1, −7) is compared to biggest (0). Since all three values are less than 0, the condition num > biggest is never True, so biggest is never reassigned. The function returns 0 — a value that wasn't even in the list. The logic error is in the initialization: biggest = 0 assumes all numbers are non-negative. The fix is to initialize biggest = lst[0] (the first element of the list), so the comparison starts from an actual list value.Question 5: CRITICAL THINKING
nums = [1, 2, 3, 4, 5]
squares = []
for n in nums:
squares.append(n ** 2)
Snippet B:
nums = [1, 2, 3, 4, 5]
squares = [n ** 2 for n in nums]Show answer
nums is assigned the list [1, 2, 3, 4, 5]. An empty list squares is created. The for loop iterates 5 times. In each iteration, n is assigned the next element, n ** 2 is evaluated (1, 4, 9, 16, 25), and the result is appended to squares. Snippet B: nums is assigned the same list. Then a list comprehension evaluates n ** 2 for each n in nums and constructs the new list [1, 4, 9, 16, 25] in a single expression, which is then assigned to squares. Both produce [1, 4, 9, 16, 25]. The key difference is that Snippet A uses an explicit loop with mutable state (the accumulator pattern), while Snippet B uses a list comprehension — a more concise, Pythonic expression. Snippet B is generally recommended for simple transformations because it's more readable to experienced Python developers and slightly more efficient, since it avoids repeated .append() method calls. However, Snippet A is clearer for beginners or when the loop body is complex.SUMMARY
Lesson Summary
Summary
Explaining code behavior step-by-step means following the execution order that the Python interpreter takes and describing each action using precise Python terminology. Key terms include assignment (binding a value to a variable), evaluation (computing the result of an expression), iteration (repeating a block over a sequence), function call (invoking a function with arguments), return (sending a value back from a function), and conditional check (evaluating a Boolean to decide which branch to take).
A strong code explanation identifies the type of operation on each line, specifies the concrete values and data types involved, and states the resulting state change or output. Tools like trace tables help you track how variables change across multiple steps, especially in loops. This foundational skill directly supports debugging, code reviews, technical interviews, and every other professional communication task in software development.