What sequence of integers does range(1, 10, 3) produce?
A1, 4, 7, 10
B1, 4, 7
C0, 3, 6, 9
D1, 3, 6, 9
range(start, stop, step) generates values starting at 1, incrementing by 3, and stopping before 10. So: 1, 4, 7 — the next value would be 10, which is excluded because range's stop is a half-open bound (start <= value < stop). Option A is the classic off-by-one error: including the stop value as if the bound were closed. Option C applies the step incorrectly and starts at 0. The half-open convention means the count of values equals (stop - start) / step, rounded down.
Question 2 Multiple Choice
A programmer writes: `for item in my_list: if item < 0: my_list.remove(item)`. What problem can this cause?
AA syntax error — you cannot call remove() on a list during iteration
BThe loop variable 'item' becomes undefined after the first removal
CElements may be silently skipped — removing an item shifts subsequent elements to earlier positions, causing the loop's internal index to jump past the next element
DThe condition item < 0 is only evaluated once, before the loop begins, so only the first negative item is removed
When you remove an element from a list mid-iteration, Python's internal index advances normally — but the list has shrunk by one. The element that was immediately after the removed item slides into the removed item's old position, and the loop skips over it. For example, in [-1, -2, 3], removing -1 shifts -2 to index 0; the loop then moves to index 1 (which is 3) and never sees -2. The fix is to iterate over a copy (`my_list[:]`) or build a new filtered list.
Question 3 True / False
range(5) produces the sequence 1, 2, 3, 4, 5.
TTrue
FFalse
Answer: False
range(5) produces 0, 1, 2, 3, 4 — five integers starting at 0 and stopping before 5. This half-open, zero-indexed convention is consistent throughout Python: range(n) always produces exactly n values. Starting at 1 instead of 0 is a persistent misconception, likely carried over from everyday counting. To get 1 through 5, use range(1, 6).
Question 4 True / False
A Python for loop can iterate directly over a string, binding the loop variable to each character in sequence.
TTrue
FFalse
Answer: True
In Python, strings are iterable sequences of characters. Writing `for char in 'hello':` binds char to 'h', then 'e', then 'l', 'l', 'o' — one character per iteration. This is the same mechanism used for lists, tuples, files, and any other iterable. The for loop's power is precisely this generality: it doesn't care what kind of sequence it traverses, only that the object is iterable.
Question 5 Short Answer
Describe a situation where a while loop is clearly more appropriate than a for loop, and explain why.
Think about your answer, then reveal below.
Model answer: A while loop is more appropriate when you don't know in advance how many iterations are needed — for example, reading user input until a valid entry is received, or searching for a condition in a data stream of unknown length. For loops are designed for iterating over a known sequence; while loops are designed for 'repeat until this condition is met' logic where the exit condition is determined at runtime.
The for loop abstracts away the counter precisely because traversal over a known sequence is the common case. When the termination condition depends on what happens *during* execution — a user action, a network response, convergence of a computation — a while loop puts that condition front and center, making the logic clearer. Using a for loop in these cases forces awkward workarounds like break statements or flags that obscure the real intent of the code.