Week 2 of 8

Build: Shot List Filter

Lists, loops, and conditionals together — your first real data-processing script

Day 8 60 minutes Build Day

Day 8 of 40

What You'll Accomplish Today

The Project: Shot List Filter

You're building a script an AI filmmaker would actually use. You have a list of shots — each one has a scene number, a description, and a platform (Kling, Runway, or Veo). The user types a platform name and the script shows only the matching shots, then displays a count.

This is the first script you'll build that processes structured data. It's small, but the pattern — store data, filter it, display results — is how real tools work.

Create a new file in your Python Training folder called shot_filter.py.

The Full Script — Line by Line

Here's the complete script. Read through the whole thing first, then we'll break it apart section by section.

shot_filter.py Python
shots = [
    {"scene": 1, "description": "Wide establishing, golf course sunrise", "platform": "Kling"},
    {"scene": 2, "description": "Close-up hands gripping club", "platform": "Runway"},
    {"scene": 3, "description": "Aerial drone pull-back reveal", "platform": "Veo"},
    {"scene": 4, "description": "Slow motion ball flight", "platform": "Kling"},
    {"scene": 5, "description": "Crowd reaction, shallow depth of field", "platform": "Runway"},
]

choice = input("Show shots for which platform? (Kling / Runway / Veo / all): ")

count = 0

for shot in shots:
    if shot["platform"].lower() == choice.lower() or choice.lower() == "all":
        print(f"  Scene {shot['scene']} [{shot['platform']}]: {shot['description']}")
        count += 1

print(f"\nShowing {count} of {len(shots)} shots.")

if count == 0:
    print("No shots found for that platform. Try: Kling, Runway, Veo, or all.")
Type this out completely. Don't copy-paste — your fingers need to learn the indentation and the syntax. Run it after typing to verify it works before moving on to the explanations below.

Breaking It Down: Section by Section

Section 1 — The Data Structure

shot_filter.py — lines 1–7 Python
shots = [
    {"scene": 1, "description": "Wide establishing, golf course sunrise", "platform": "Kling"},
    {"scene": 2, "description": "Close-up hands gripping club", "platform": "Runway"},
    # ... more items ...
]

This is a list of dictionaries. The outer [] makes it a list. Each item inside — wrapped in {} — is a dictionary.

A dictionary is a collection of key:value pairs. Instead of accessing data by position (shots[0] = the first shot), you access it by name (shot["platform"] = the platform field). Think of it as a labeled form — each field has a name and a value.

This is a preview of Week 3. You don't need to master dictionaries today — just recognize the pattern and understand why shot["platform"] works.

Dictionary vs. List: The Core Difference

A list is ordered. You access items by position: shots[0], shots[1]. You have to remember (or count) which slot holds which data.

A dictionary is labeled. You access items by name: shot["platform"], shot["description"]. The key tells you exactly what data you're getting. When your data has structure — like a shot with multiple fields — a dictionary is almost always cleaner.

Section 2 — User Input and the Counter

shot_filter.py — lines 9–11 Python
choice = input("Show shots for which platform? (Kling / Runway / Veo / all): ")

count = 0

choice stores whatever the user types. It could be "Kling", "kling", "KLING" — we'll handle the case difference in the loop.

count = 0 creates a counter variable, initialized to zero. Every time the filter finds a matching shot, we'll add 1 to this. Setting it to zero before the loop is critical — Python doesn't assume it starts at zero, you have to tell it.

Section 3 — The Filter Loop

shot_filter.py — lines 13–16 Python
for shot in shots:
    if shot["platform"].lower() == choice.lower() or choice.lower() == "all":
        print(f"  Scene {shot['scene']} [{shot['platform']}]: {shot['description']}")
        count += 1

for shot in shots: — Python loops through the list one item at a time. Each time through the loop, shot is one dictionary (one row of your shot list). The variable name shot is your choice — it could be s or item, but descriptive names make code readable.

shot["platform"] — accesses the "platform" field of the current dictionary. This is how you read a value from a dictionary: the name in square brackets.

.lower() — converts a string to all lowercase. "Kling".lower() returns "kling". Applying it to both sides of the == makes the comparison case-insensitive. Whether the user types "kling", "KLING", or "Kling", it will match.

or choice.lower() == "all" — if the user typed "all", show every shot regardless of platform. The or means the condition is true if either side is true.

count += 1 — shorthand for count = count + 1. Every time a shot passes the filter, the counter goes up by 1.

Key Concept: count += 1

The += operator adds a value to a variable and stores the result back in the same variable. These three lines all do the same thing:

count = count + 1    # explicit, verbose
count += 1           # shorthand — what most Python code uses

You'll also see -=, *=, and /= for the same pattern with subtraction, multiplication, and division.

Section 4 — Summary Output

shot_filter.py — lines 18–21 Python
print(f"\nShowing {count} of {len(shots)} shots.")

if count == 0:
    print("No shots found for that platform. Try: Kling, Runway, Veo, or all.")

The \n in the f-string is a newline character — it prints a blank line before the summary, which makes the output easier to read.

len(shots) returns the total number of items in the shots list — the total count before any filter is applied.

The final if count == 0 block only prints the help message if nothing matched — a friendly error state that guides the user to try again with a valid input.

Run It

In your terminal, run the script and test several inputs:

Terminal
$ python shot_filter.py
Show shots for which platform? (Kling / Runway / Veo / all): Kling

  Scene 1 [Kling]: Wide establishing, golf course sunrise
  Scene 4 [Kling]: Slow motion ball flight

Showing 2 of 5 shots.

$ python shot_filter.py
Show shots for which platform? (Kling / Runway / Veo / all): all

  Scene 1 [Kling]: Wide establishing, golf course sunrise
  Scene 2 [Runway]: Close-up hands gripping club
  Scene 3 [Veo]: Aerial drone pull-back reveal
  Scene 4 [Kling]: Slow motion ball flight
  Scene 5 [Runway]: Crowd reaction, shallow depth of field

Showing 5 of 5 shots.
Test the Edge Cases

Try typing "kling" (lowercase), "RUNWAY" (all caps), and "sora" (a platform that isn't in the list). The first two should work because of .lower(). The third should show the "No shots found" message. If both behaviors work, your script is handling input correctly.

Exercises

Exercise 1 — Add More Shots

Add two more shots to the shots list at the top of the script. Make sure each has all three keys: "scene", "description", and "platform". Use real shot descriptions from a project you'd actually film. Run the script and verify the count updates correctly.

Exercise 2 — Filter by Scene Number

Change the filter logic so that instead of filtering by platform, it shows all shots where the scene number is greater than 2. The condition should look like: if shot["scene"] > 2:. Remove the input() line for this exercise — hardcode the filter. This tests that you understand how to access a numeric field from a dictionary and compare it.

Exercise 3 — Platform Summary (Stretch)

After the filtered output, add a new section that counts how many shots exist per platform in the full list (not filtered). The output should look like:

--- All Platforms ---
Kling: 2 shots
Runway: 2 shots
Veo: 1 shot

Hint: You'll need a variable for each platform counter, or — if you want to look ahead — a dictionary to hold all counts at once.

End of Day Checklist

Tomorrow

You'll start building your most ambitious script yet: Scene Planner. It uses a while True loop that keeps running until the user types "done", and it builds up a list of shot dictionaries from user input one at a time. Day 9 sets up the input loop; Day 10 adds the output and summary. It's a two-day build.