Slow down, test your assumptions, and find the gaps — this is where it actually sticks
Day 7 of 40
These two chapters cover the same ground Mosh covered yesterday — but in text, with more precise explanations. Skim what already feels solid, slow down on anything that was fuzzy after the video.
| Chapter | What to focus on |
|---|---|
| Chapter 2 — Flow Control | if/elif/else, comparison operators, and/or/not, for loops, while loops, break/continue |
| Chapter 4 — Lists | Creating lists, indexes, slicing, methods (.append, .remove, .sort), the in operator |
Don't just read — type the examples yourself. The book is free and online. Keep Cursor open next to it. If the book explains something and you're not sure it'll work the way it says, run it in the terminal immediately. Verify everything.
Jupyter Notebook is a different way to run Python. Instead of writing a script and running the whole thing, you run one small block of code at a time and see the result immediately. It's your scratch pad this week.
Open Cursor's terminal and install Jupyter if you haven't already:
$ pip install notebook
$ jupyter notebook
Your browser will open with the Jupyter interface. Navigate to your Python Training folder and create a new notebook called week-2-practice.ipynb. You'll use this for everything below.
Scripts (.py files) are for building finished things. Notebooks are for experimenting. You're learning new concepts this week — Jupyter lets you test one idea at a time and see what happens without running a full program. From Week 5 onward you'll be back to scripts full-time.
Copy each cell below into your notebook and run it. Before you run each cell, predict what the output will be. Getting it wrong is fine — being surprised is how you learn something new.
# What counts as True and what counts as False?
# Predict each result before you run it.
print(bool("hello")) # non-empty string
print(bool("")) # empty string
print(bool(42)) # non-zero number
print(bool(0)) # zero
print(bool([1, 2, 3])) # non-empty list
print(bool([])) # empty list
if shots: instead of if len(shots) > 0: — shorter and more idiomatic. This works because an empty list is False and a non-empty list is True. Knowing this prevents a whole class of subtle bugs.
# Python is lazy — 'or' returns the first truthy value it finds.
# 'and' returns the first falsy value it finds.
# This is called short-circuit evaluation.
print("Kling" or "Runway") # → ?
print("" or "Runway") # → ?
print("" or "" or "Veo") # → ?
print("Kling" and "Runway") # → ?
print("" and "Runway") # → ?
platform = user_input or "Kling" — if user_input is empty (falsy), fall back to "Kling". One line instead of three.
platforms = ["Kling", "Runway", "Veo", "Pika", "Sora"]
# [0] [1] [2] [3] [4]
print(platforms[0]) # first item
print(platforms[-1]) # last item — always
print(platforms[1:3]) # items at index 1 and 2 (not 3!)
print(platforms[:2]) # first two items
print(platforms[2:]) # everything from index 2 to the end
print(platforms[1:4:2]) # every other item from index 1 to 3
[start:stop:step]. Stop is exclusive — [1:3] gives you indexes 1 and 2, not 3. Negative indexes always count from the end: -1 is always the last item, -2 is second-to-last, and so on.
# This is a famous Python trap. Run it, then read the explanation.
rows = [[]] * 3
print(rows) # looks fine: [[], [], []]
rows[0].append("surprise")
print(rows) # wait — why did all three change?
# The fix: use a list comprehension to create independent lists
rows_fixed = [[] for _ in range(3)]
rows_fixed[0].append("only here")
print(rows_fixed) # only the first one changed
[[]] * 3 doesn't create three separate empty lists — it creates three references to the same list. Change one, you change all three. The list comprehension [[] for _ in range(3)] creates genuinely independent lists. You may never hit this in Week 2, but it will bite you eventually — now you know why.
shot_types = ["wide", "medium", "close-up", "aerial"]
# Loop through and print each shot
for shot in shot_types:
print(shot)
# Loop with index using enumerate()
for i, shot in enumerate(shot_types):
print(f"{i + 1}. {shot}")
# Build a new list from an old one using a list comprehension
upper_shots = [shot.upper() for shot in shot_types]
print(upper_shots)
enumerate() gives you both the index and the value in one loop — you don't have to manually track a counter. List comprehensions ([x for x in list]) are the Pythonic way to transform lists. You'll use both of these constantly.
week-2-practice.ipynb notebook is openYou switch from experimenting to building. Tomorrow's project — the Shot List Filter — combines everything you've seen this week into a real script that does something useful. It introduces one new concept: dictionaries (a sneak preview of Week 3). It's the most interesting thing you'll build so far.