Back to the Introduction to Computer Science outline The Course Maker
Introduction to Computer Science outline
Week 9 · Coding Lab

Week 9 — Coding Lab / Programming Studio · "Build It, Mutate It, Alias It"

Introduction to Computer Science · CSCI 1101 Fall 2026 · Prof. Okafor Fictional sample

Course: Introduction to Computer Science — CS1 / Programming Fundamentals in Python (CSCI 1101) · Silver Oak University (fictional sample) · Prof. Okafor
Objective: Objective 6 — build & mutate a list with methods; trace list operations, slices, and aliasing and predict output; find & fix an aliasing / mutate-while-iterating bug · SLO A (write & run) + SLO B (trace & debug)
Worth 50 points · Coding Labs group = 15% of the grade · Coding Lab 9
Format: a hands-on programming studio worked in a free online Python environment — you'll (a) build & mutate a list, (b) trace list operations and predict their output, and (c) find and fix an aliasing / mutate-while-iterating bug — then watch b = a alias in Python Tutor and catch the AI's mistake when it assumes b = a is a copy.

This is the course's signature weekly component. Every instructional week has one Coding Lab. Everything runs in your browser — nothing to buy or install. The whole habit of this lab (and this course): don't guess what code does — run it and read what Python actually prints. This week that habit is the only reliable way to settle aliasing.


Part 1 — The Big Picture

This week you met Python's most-used collection — the list — and its most famous surprise: b = a makes two names for one list, not a copy. This lab puts the whole week through its paces: you'll build and change a list with methods, trace list operations and slices (predict, then run), and debug the two list traps (aliasing and mutate-while-iterating). By the end you'll have seen aliasing with your own eyes in Python Tutor — the single clearest way to understand it.

Your tools (both free, both in the browser):
- An online Python editor to write and run code: 🔗 https://www.online-python.com/ (or 🔗 https://www.programiz.com/python-programming/online-compiler)
- Python Tutor to watch code run step by step — and to see aliasing: 🔗 https://pythontutor.com/ — paste a program, click Visualize Execution, then step forward and watch the arrows.


Part 2 — Setup (2 minutes)

  1. Open the online Python editor in a new tab.
  2. Delete any sample code so you have a blank editor.
  3. Type and run:
    python nums = [10, 20, 30] nums.append(40) print(nums)
    You should see [10, 20, 30, 40]. You just built and changed a list. 🎉

Part 3 — (a) Build & Mutate: Your List Programs

Write each of these in the editor, run it, and paste your code and its output into your submission.

  1. Build a to-do list. Create a list with two tasks (e.g., todo = ["read", "code"]). Then append a third task, insert a task at the front (index 0), and remove one task by its value. print the list after each change and write down what you saw.
  2. Track scores & summarize by iterating. Make a list of five scores (your choice). Use a for loop to compute the average and to find the highest score by iterating (don't use the built-in max). Print both.
  3. Membership check. Using your scores list, print whether 100 is in the list and whether your first score is in the list (use the in operator). Run it and note the two True/False results.

Part 4 — (b) Trace: Predict, Then Run

For each program below, first write your predicted output in the table (don't run it yet!). Then run each one in the editor and fill in the "Actual" column. Where your prediction and the actual output differ, that's the lesson. Every program starts from nums = [10, 20, 30, 40] unless the code says otherwise.

# Program Your prediction Actual (after running)
1 nums = [10, 20, 30, 40]print(nums[2]) ______ ______
2 nums = [10, 20, 30, 40]print(nums[-1]) ______ ______
3 nums = [10, 20, 30, 40]print(nums[1:3]) ______ ______
4 nums = [10, 20, 30, 40]print(nums[:2]) ______ ______
5 nums = [10, 20, 30, 40]nums.append(50)print(nums) ______ ______
6 nums = [10, 20, 30, 40]nums.insert(1, 99)print(nums) ______ ______
7 nums = [10, 20, 30, 40]x = nums.pop()print(x) then print(nums) ______ ______
8 nums = [10, 20, 30, 40]print(30 in nums) ______ ______
9 a = [1, 2]b = ab.append(3)print(a) ______ ______
10 a = [1, 2]b = a[:]b.append(3)print(a) ______ ______

Hint for #3 and #4: remember the slice stop is excluded — same as strings.
Hint for #9 vs #10: these two differ by one character on the second line (b = a vs b = a[:]). Predict each carefully — the difference is the whole point of the week.

Visualize the headline: paste program #9 (a = [1, 2] / b = a / b.append(3) / print(a)) into Python Tutor and step through it. Watch both a and b draw arrows to the same list box. Then change line 2 to b = a[:] (program #10) and step again — now there are two boxes. That picture is this week's whole lesson.


Part 5 — (c) Find & Fix the Bug

Each program below is broken (it runs, but gives the wrong result — neither one crashes). For each: run it, figure out what's happening, then write (i) what's wrong, (ii) why, and (iii) the fixed program with its correct output.

Bug A — the wrecked backup. This is supposed to keep a unchanged while building a longer list b. It doesn't.

a = [1, 2, 3]
b = a
b.append(4)
print("a =", a)
print("b =", b)

Bug B — the survivor. This is supposed to remove every 0 from the list. One 0 survives.

nums = [1, 0, 0, 2, 0]
for n in nums:
    if n == 0:
        nums.remove(0)
print(nums)

Part 6 — Analysis Questions

Answer in a sentence or two each:
1. In the trace table, which prediction did you get wrong (if any)? What did you learn from the gap? (Programs #9 and #6 are the usual surprises.)
2. Programs #9 (b = a) and #10 (b = a[:]) differ by one character but print different results. Why? What did Python Tutor show you about the number of list "boxes" in each?
3. For Bug A, why did changing b also change a? What single change fixes it?
4. For Bug B, the loop was supposed to remove all the zeros but left one. Why does removing items while looping skip elements? Name one clean fix.
5. Connect it: both bugs run without any error message, yet both give the wrong answer. How does that show why "run it and read the output" isn't enough on its own — you also have to know what the right answer should be and check against it?


Part 7 — AI-Critique Moment (required — this is the BYOAI step)

Now bring in your approved chatbot (Gemini, Claude, or ChatGPT) and be the programmer who checks its work. This week the model has a favorite blind spot: aliasing.

  1. Paste this to the chatbot: "What does each of these Python programs print? (a) a = [1, 2] then b = a then b.append(3) then print(a); (b) nums = [3, 1, 2] then r = nums.sort() then print(r); (c) print([10, 20, 30, 40][1:3]). Give me the exact output of each."
  2. Check every claim by running each program yourself in the editor:
    - For (a): did it say print(a) is [1, 2] (treating b = a as a copy) — or the correct [1, 2, 3]? Chatbots very often get this wrong, insisting a is untouched.
    - For (b): did it say nums.sort() returns the sorted list [1, 2, 3] — or the correct None? (sort() returns None.)
    - For (c): did it include index 3 (a common slice mistake) — or the correct [20, 30]?
  3. Write 2–3 sentences reporting what the AI got right and at least one thing you had to correct or verify carefully (most likely the aliasing one). If it happened to get everything right, say how you confirmed each one by running it — that's the skill.

The habit all term: the tool drafts, you run it and judge. A chatbot will confidently tell you b = a leaves a alone — catching that by running the code (and watching it in Python Tutor) is the entire point of this week.


Part 8 — What to Submit

Submit a single document (or text entry) with: your Part 3 programs and their outputs; your completed Part 4 trace table (both columns); your Part 5 bug answers (what's wrong, why, and the fixed program + output for each); your Part 6 answers; and your Part 7 AI-critique paragraph. Due Sunday, Nov 1, 11:59 p.m. (50 points).


Instructor answer key & model outputs — REMOVE BEFORE PUBLISHING TO STUDENTS

Execution gate: PASS — every output below was produced by actually running the code in Python. Students' Part 3 wording varies; grade those on "does it run and produce the right kind of output."

Part 3 (model):
1. Build/mutate, e.g. todo = ["read", "code"].append("rest").insert(0, "wake").remove("code")['wake', 'read', 'rest']. ✓ (exact words vary; check the operations were applied and printed)
2. Five scores, average and highest by iterating (a loop, not max()). For [88, 92, 79, 95, 88]: highest 95, average 88.4. ✓ (their numbers vary)
3. in gives two Booleans, e.g. 100 in scoresFalse (unless 100 is present), first score in scoresTrue. ✓

Part 4 trace table (run-verified):

# Program Actual output
1 print(nums[2]) 30
2 print(nums[-1]) 40
3 print(nums[1:3]) [20, 30]
4 print(nums[:2]) [10, 20]
5 append(50)print(nums) [10, 20, 30, 40, 50]
6 insert(1, 99)print(nums) [10, 99, 20, 30, 40]
7 x = nums.pop()print(x) / print(nums) 40 then [10, 20, 30]
8 print(30 in nums) True
9 b = aappend(3)print(a) [1, 2, 3]
10 b = a[:]append(3)print(a) [1, 2]

Part 5 bugs (run-verified):
- Bug A (aliasing): (i) b = a did not copy the list — a changed too. Run-verified, the buggy version prints a = [1, 2, 3, 4] and b = [1, 2, 3, 4] (identical). (ii) b = a makes b a second name for the same list, so b.append(4) changes the one shared list. (iii) Fix with a real copy:
python a = [1, 2, 3] b = a[:] b.append(4) print("a =", a) print("b =", b)
Output (run-verified): a = [1, 2, 3] then b = [1, 2, 3, 4]. (b = list(a) works too.)
- Bug B (mutate-while-iterating): (i) one 0 survives — run-verified, the buggy version prints [1, 2, 0]. (ii) Removing an item shifts everything left, so the for loop (which walks by position) skips the shifted-down item. (iii) Fix by looping over a copy (or building a new list):
python nums = [1, 0, 0, 2, 0] for n in nums[:]: if n == 0: nums.remove(0) print(nums)
Output (run-verified): [1, 2]. (Building a new list of non-zeros also gives [1, 2].)

Part 6 (expected): (1) most commonly #9 ([1, 2, 3], not [1, 2]) or #6 (insert shifts, giving [10, 99, 20, 30, 40]). (2) b = a makes one list with two names (Python Tutor shows both arrows to one box); b = a[:] makes a separate copy (two boxes) — so appending through b only touches a in the first case. (3) b = a aliased the list; changing b changed the shared list; the fix is b = a[:] (or list(a)). (4) Removing shifts later items left, and the position-based loop skips the one that slid into the just-checked slot; fix by iterating over nums[:] or building a new list. (5) Both programs run and print something, but the something is wrong — so running isn't enough by itself; you must know the intended result (a should be [1, 2, 3]; all zeros should be gone) and compare. That's testing, not just running.

Part 7 (AI-critique): full credit for a specific catch — most commonly the AI claiming print(a) is [1, 2] (treating b = a as a copy) when it's actually [1, 2, 3], or saying nums.sort() returns [1, 2, 3] instead of None. Full credit also if the student verified each AI claim by running it.

Grading rubric — 50 points

Criterion Full Partial None
Part 3 — built & ran 3 programs (to-do list mutated; scores summarized by iterating; in membership shown) (14) 14 7–11 0–5
Part 4 — trace table (predictions attempted + all 10 actual outputs correct from running, incl. #9/#10 aliasing) (14) 14 7–11 0–5
Part 5 — found & fixed both bugs (what/why/fix + correct output for aliasing AND mutate-while-iterating) (12) 12 6–10 0–4
Part 6 — analysis (aliasing one-list-two-names; why removing-while-looping skips; run-isn't-enough) (6) 6 3–5 0–2
Part 7 — AI-critique (names a specific thing checked/corrected by running — ideally the aliasing miss) (4) 4 2 0–1

Quality gate (self-checked): every model output above (['wake', 'read', 'rest'], 95/88.4, the table values 30, 40, [20, 30], [10, 20], [10, 20, 30, 40, 50], [10, 99, 20, 30, 40], 40/[10, 20, 30], True, [1, 2, 3], [1, 2], both bug fixes a = [1, 2, 3]/b = [1, 2, 3, 4] and [1, 2]) was produced by actually running the code in Pythonexecution gate: PASS. No output is hand-traced (Bug B's [1, 2, 0] is exactly the kind of result a hand-trace gets wrong). The lab grades the student's process (build → mutate → trace → debug → see-it-in-Python-Tutor → critique the AI), not a single fixed wording for the open-ended Part 3.

~ Prof. Okafor's edition · Fall 2026 · built with thecoursemaker.com