Lists, loops, and conditionals together — your first real data-processing script
Day 8 of 40
shot_filter.py — a real script that processes a list of shot datafor loops and conditionals together in a meaningful context.lower() to make user input case-insensitivecount += 1) to track resultsYou'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.
Here's the complete script. Read through the whole thing first, then we'll break it apart section by section.
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.")
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.
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.
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.
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.
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.
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.
In your terminal, run the script and test several inputs:
$ 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.
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.
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.
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.
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.
shot_filter.py runs without errorsshot["platform"] does.lower() does and why it's used on both sidesYou'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.