Week 6: For Loops, Lists, and Ranges
Heads up: submit PA1 to Gradescope
If you don't submit to Gradescope and get a nonzero score, you will receive a reflection grade of no higher than 15/30 points. Good news: that's an easy bar to clear! Pick either PA1 option, submit as soon as Part A works, and you're set.
🎯 Objectives
Last week your programs got cut into functions, and each function ran once per call. This week a piece of your program runs over and over, and how many times it runs is decided by the data rather than by you.
A list holds any number of values in order under one name, and a for loop runs its body once for every value in a list, or once for every number that range() produces.
Neither is complicated on its own.
What takes the week is being able to look at a loop and say, without running it, how many times it will run and what every variable holds at the end of each pass.
That is a different skill from writing loops, and it is the one the next quiz on this material checks.
By the end of the week you should be able to:
- Trace and write a
forloop over the values of a list, and over arange()of integers given one, two, or three arguments. - Predict how many times a loop runs and what it produces, including loops that run zero times.
- Tell the difference between looping over values and looping over indexes, and say when only the index version will do.
- Build a new list with a loop, by accumulating every value or filtering only some of them, and compute a total, a maximum, and a minimum with a loop rather than a built-in.
- Change a list in place with
append(), index assignment,pop(),remove(), andsort(), and say what each one hands back.
Quiz 2 is this week, on a computer, and covers last week
Quiz 2 is on Wednesday or Thursday this week, depending on your section: 25 minutes, on a computer, covering Weeks 4 and 5, with no AI. None of this week's material is on it. Last week's guide is where the advice for it lives.
This week's material is on Quiz 3, and Quiz 3 is on paper
Quiz 3 is in Week 9 and covers this week together with Week 8. It is on paper, 30 minutes, no AI, and no computer: you will be handed loops and asked what they print, how many times they run, and what a list holds afterward. So the balance flips back to what it was before Quiz 1. Write loops at the keyboard, by all means, but most of the practice that counts this week is done with a pencil, before you let Python tell you the answer. A loop you ran is a loop you did not trace.
First, a five-minute self-check
Answer these on paper before you open anything. Nothing here is graded; the point is to find out which items on the menu below deserve your time.
- What numbers does
range(2, 11, 3)produce, and how many are there? - How many times does the body of
for i in range(5, 1):run? itemshas 7 values. What is the index of the last one?- What does
print([4, 2, 9].sort())print, and why? nums = [3, 1, 3]. What isnumsafternums.remove(3)?- A loop is meant to add up a list. Where does
total = 0go — before the loop, inside it, or after it — and what goes wrong in each of the other two places? - You need to compare each temperature with the one the day before. Can you do that with
for temp in temps:? Why or why not?
If 1, 2, and 6 were comfortable, skip ahead to "Trace an accumulator by hand." If 4 or 5 surprised you, start with "Draw the list after every line."
📚 Study menu
Class covers three things this week: lists and the for statement on Monday, range() and values-versus-indexes on Wednesday, and building, filtering, and changing lists on Friday.
Wednesday is also Quiz 2, so the first half of your week probably belongs to last week's guide, and this menu to the second half.
This is a menu, not an assignment. Nobody does all of it. But with a paper quiz ahead, at least one item you pick should be one where the computer stays closed until you have written your answer down.
If you only have an hour
- Ten minutes. The self-check above, on paper.
- Fifteen minutes. "Count the iterations before you run," below. Do the table with a pencil, then check it in the Shell.
- Twenty minutes. "Trace an accumulator by hand," on one function you wrote for PA1.
- Fifteen minutes. Ex6.5 from the practice page, which is three loop bugs in a row. Find all three on paper before you run it.
Read about it
All three books teach the for loop and the list in separate chapters, and all three wander into while loops and slicing along the way, so read the note below before you start.
Pick one option; the third is a skim to pair with either.
Python for Everybody — 6. Loops and Iterations and 9. Lists
- 6.5 Definite loops using for and 6.6 Loop patterns. 6.6 is the counting, summing, maximum, and minimum loops, which is Friday's class in five pages.
- Then 9.1 through 9.4, skip 9.5, and finish with 9.6 List methods and 9.7 Deleting elements.
How to Think Like a Computer Scientist — 8. More About Iteration and 10. Lists
- 8.1 Iteration Revisited, 8.2 The for loop revisited, and 6.5 The Accumulator Pattern, the section last week's guide told you to hold for now.
- Then 10.1 through 10.4, 10.8 Lists are Mutable, 10.9 List Deletion, 10.14 List Methods, 10.17 Lists and for loops, and 10.18 The Accumulator Pattern with Lists.
- If the
forloop itself is not clicking, 4.4 The for Loop through 4.7 The range Function teach it again with turtle graphics, which is a gentler way in. The CodeLens boxes in this book step through a loop one pass at a time and are the closest thing in any of the three to a trace table that fills itself in.
W3Schools — the reference-style skim
- Python For Loops and Python Range.
- Python Lists with its Access, Change, Add, Remove, and Sort subpages.
Where to stop reading, and what the books leave out
Skip every while loop. PY4E 6.1–6.4 and TCS 8.3 onward are Week 9, and the W3Schools Loop Lists page switches to while halfway down.
Skip slicing — PY4E 9.5, TCS 10.7, and the [2:5] examples on the W3Schools Access and Change pages. It is Week 10.
Skip list comprehensions too (the W3Schools subpage of that name, and the one-line examples at the bottom of Loop Lists); they are Week 11.
Skip TCS 10.10–10.13 and the W3Schools Copy Lists page. They are about aliasing, which is Week 10, and they will make more sense once strings have shown you what "immutable" means. The one thing you need from them this week is in Ex6.6 on the practice page.
Several of the books' examples loop over a string (for letter in "banana"). That works, and it is Week 8. This week, loop over lists and ranges.
PY4E 6.6 starts its maximum loop at None and tests largest is None. That is correct Python, but the approach this course uses is to start at the first item of the list, which is what Ex6.5 asks for.
Count the iterations before you run
This drill is built like a Quiz 3 question. Copy the table onto paper, cover nothing, and fill in both blank columns with a pencil before you touch the Shell.
| Loop header | Values the loop variable takes | Times the body runs |
|---|---|---|
for i in range(5): |
||
for i in range(1, 5): |
||
for i in range(0, 10, 3): |
||
for i in range(10, 0, -3): |
||
for i in range(5, 1): |
||
for i in range(4, 4): |
||
for i in range(len(temps)): |
(temps has 7 values) |
|
for i in range(1, len(temps)): |
(temps has 7 values) |
|
for word in ["a", "b", "a"]: |
||
for n in []: |
Then check each row in the Shell with list(range(...)), one at a time, and write the right answer beside any you got wrong.
The rules you should be able to state afterward:
rangestops before its stop value, in every form.range(a, b)runs \(b - a\) times when \(b > a\).- With a step, count the values rather than dividing:
range(0, 10, 3)is 0, 3, 6, 9, which is four, not three. - A range that cannot get from start to stop in the direction of its step is empty, and a loop over it runs zero times without any error.
range(5, 1)is empty;range(5, 1, -1)is not. - A loop over a list runs once per item, duplicates included, and zero times over an empty list.
range(len(items))produces exactly the valid indexes ofitems. Anything you add to either end is whereIndexErrorcomes from.
Draw the list after every line
A list changes in place, which means a line of code can change a variable without that variable's name appearing on the left of an =.
That is new this week, and it is easy to lose track of on paper.
Cover the two right-hand columns, and for each line write down what nums holds afterward and what the line itself hands back (or the error it raises).
Each line starts from wherever the line above left nums.
| Line | nums afterward |
Hands back |
|---|---|---|
nums = [3, 1, 3, 2] |
[3, 1, 3, 2] |
— |
nums.append(5) |
[3, 1, 3, 2, 5] |
None |
nums[1] = 8 |
[3, 8, 3, 2, 5] |
— |
nums.remove(3) |
[8, 3, 2, 5] |
None |
nums.pop() |
[8, 3, 2] |
5 |
nums.sort() |
[2, 3, 8] |
None |
nums.remove(7) |
[2, 3, 8] |
ValueError |
nums[3] = 1 |
[2, 3, 8] |
IndexError |
nums.append(len(nums)) |
[2, 3, 8, 3] |
None |
nums = nums.sort() |
None |
— |
Then type the lines into the Shell in order and see which row surprised you.
What the table is there to show:
append,remove, andsortchange the list and hand backNone. Of the methods this week, onlypophands back something useful.removetakes out the first matching value, not every one, and not the one at that index.- Index assignment replaces a value that is already there; it cannot add one past the end. Adding is
append's job. - The last row is the most common list bug of the semester:
sortalready changed the list, and assigning itsNoneback over the name throws the list away.
Trace an accumulator by hand
Most loops this week keep one or more variables alive from one pass to the next — a running total, the best value so far, a list being built up. Tracing a loop means tracking those variables, one row per pass.
Take season_stats from Ex6.5 once you have repaired it, or in_interval from Ex6.4, and a short input: three or four values, one of which sits on a boundary.
On paper, make a table with one column for the loop variable and one for every variable that survives between passes, and write one row per pass through the loop, after the body has run.
Add a row at the top for the values before the loop starts, and write the returned value underneath.
Then check yourself with Thonny's debugger rather than with print: set a breakpoint on the first line of the loop body and press Resume once per pass, comparing the variables pane with each row.
The debugger lets you see the table fill in one row at a time, which is the thing a paper quiz asks you to do in your head.
Afterward, do the same with the broken box_score.py from the practice page, before you fix it.
A trace of a broken loop is where you find out that total = 0 inside the loop body does run every time — the table shows it on the second row.
Values or indexes? Write it both ways
Every loop over a list can be written two ways, for item in items: or for i in range(len(items)):, and the choice is a real one.
Pick three functions you wrote this week — print_list, in_interval, and print_board work well — and rewrite each one using the other kind of loop.
Then try the same with daily_changes from Ex6.3 and notice that one direction does not work.
Write one sentence for each that finishes "the value version is better here because…" or "only the index version works here because…". What you should end up with is a rule you can apply on a quiz in five seconds: when you only need each value, loop over values; when you need the position, a neighbor, or a second list at the same position, loop over indexes. Loops over indexes are where off-by-one errors live, which is one more reason not to use them when you do not have to.
Break it deliberately
Each of these fails in a different way. Write down, before running it, whether it crashes (and with which error) or runs and gives a wrong answer, and what that answer is.
- Change
range(1, len(temps))inswings.pytorange(len(temps)). What doesdaily_changesreturn now, and which of the two functions crashes? (Think carefully about whattemps[-1]is before you decide.) - Change it to
range(1, len(temps) + 1). - In
addressing.py, movereturn addressesso it is indented inside the loop. - In
packing.py, changelast_itemto returnitems[len(items)]. - In
leaderboard.py, addboard = board.sort(reverse=True). - Call
in_intervalwith the bounds the wrong way round,in_interval(values, 5.0, 0.0, True).
The first one is the lesson: a loop that runs one pass too many does not always crash where the mistake is, because a negative index is legal. daily_changes quietly hands back seven changes with a wrong one at the front, and the crash only comes later, in a different function, when something trusts that list to be the right length.
Try an AI tutor
Loops are a topic where AI tools help a lot and hurt quietly.
They help because they can generate a new tracing problem every time you ask.
They hurt because AI writes modern, compact Python: ask it to add up a list and it will write sum(scores); ask it to filter and it will write a one-line list comprehension; ask for the last three items and it will slice.
All of that is fine Python and none of it is what Quiz 3 asks you to read or write.
Tell it so up front.
"I am a CS1 student who knows
forloops over lists andrange(),append,pop,remove,sort, and index assignment, and nothing else — nowhile, no slicing, no comprehensions, nosum/max/min. Write me a ten-line function that uses aforloop and an accumulator, and an input for it. Do not tell me the output. After I trace it on paper and give you my answer, tell me only whether each variable's final value is right.""Give me eight
range()calls with one, two, and three arguments, including at least two that are empty and one with a negative step. List the calls only. When I reply with the values and the counts, tell me which ones I got wrong and nothing else.""Here is a loop I wrote: [paste it]. Do not fix it and do not rewrite it. Tell me how many times its body runs for the input [x], and what [variable] holds after the second pass."
The specific thing to be skeptical about this week is range endpoints.
AI tools are unreliable about off-by-one counts — they will say range(1, 10, 3) produces four values, or describe a loop as running n times when it runs n − 1.
Check every count an AI gives you against the Shell, and when they disagree, the Shell wins.
✍️ Reflection
Instructions
Download the Week 6 reflection template, type your answers into it, and submit the completed document.
The first three questions are quick; the short answers are the ones that matter. Question 4 is about Quiz 2, which you will have just taken, and it is worth answering while it is fresh. A few sentences each is plenty. Be specific and be honest.
1. What did you do this week? (Check all that apply.)
- Read the sections listed for one or more of the textbooks
- Filled in the
range()table on paper, then checked it in the Shell - Filled in the list-changes table on paper, then checked it in the Shell
- Traced a loop by hand, one row per pass, and checked it with the debugger
- Rewrote loops over values as loops over indexes, or the other way round
- Broke programs deliberately and predicted the result first
- Wrote programs from the practice page
- Asked an AI tutor to drill me with tracing problems
- Something else (tell us in the short answers)
2. Roughly how much time did you spend on CS 149 outside of class this week?
- Under 1 hour
- 1–2 hours
- 3–4 hours
- 5–6 hours
- 7+ hours
3. Quiz 3 will hand you a loop on paper. How confident are you that you could say how many times it runs and what it prints, without a computer?
- Confident — I have traced loops on paper and checked myself
- Fine with simple loops, less sure with
range()steps or a list that changes - I can write loops that work, but I usually find out what they do by running them
- Not confident, and I know which part is missing
- Not confident, and I am not sure what is missing
4. You have now taken one paper quiz and one computer quiz. What did Quiz 2 show you about how you prepared? Name one thing you did before Quiz 2 that paid off in the room, and one thing that cost you time or points — a missing return, a ruff violation found late, a function you started before you knew what it should return. Then say what you will do differently to prepare for Quiz 3, keeping in mind that it is back on paper.
5. Give one loop this week that did not do what you expected. Write what you expected, what actually happened, and the rule you were using that turned out to be wrong — about where range stops, about what a list method hands back, about where an accumulator is initialized, or about which line was inside the loop. The wrong rule is the useful part. Then say which of this week's objectives feels shakiest and what you plan to do about it.
6. What is one thing you want gone over in class? Be as specific as you can: "why range(5, 1) runs zero times but range(5, 1, -1) does not" is useful, and "loops" is not. Answer this even if you feel confident, by naming the kind of loop you would least like to trace on Quiz 3. Class time gets spent on whatever shows up most often in these answers.
7. Did you use an AI tool this week, and did it build your understanding or replace it? The honest test for this week is concrete: given a ten-line function with a for loop, an accumulator, and an if inside it, could you write its trace table on paper — every variable after every pass — with no computer and no notes? If a video, article, or tutorial made something click, drop the link and one line on why it helped; we collect these to improve the study menu for future students.
8. Paste one or two programs you wrote outside of class this week. Pick the ones with the most loops in them, and if tracing one on paper turned up something that running it did not, say what.