Week 1 of 16

Input & Strings

Make the formatter ask questions — and master every string operation you'll actually use

Day 2 60 minutes Build + Practice

Day 2 of 80

What You'll Build Today

The Rule for Today

Every concept gets a "Do This Now" immediately after it's introduced. Don't read ahead before running the code. Doing is the learning — reading about it is just preparation for doing.

Part 1: Getting Input from the User

Yesterday your formatter had hard-coded data. That means you have to edit the source file every time the project changes. Real tools ask for the data instead.

input() shows a message, waits for the user to type something, and stores whatever they typed in a variable.

input_demo.pyPython
# input() waits for the user to type something and press Enter.
# Whatever they type is stored as a string in the variable.
name = input("What's your name? ")

print(f"Hey {name}, let's build something.")

Notice the space after the ? inside the string. Without it, the cursor blinks right against the question mark: What's your name?_. The space makes it readable: What's your name? _.

input() always returns a string — even if the user types a number. You'll deal with that on Day 3.

Do This Now

Create input_demo.py, type the code above, run it. Then add a second input() that asks for their favourite platform, and print a second line that uses both variables in an f-string.

Part 2: String Methods

Strings have built-in abilities called methods, called with a dot. These are the ones you'll reach for constantly.

strings.pyPython
title = "Golf Course Commercial"

print(title.upper())          # GOLF COURSE COMMERCIAL
print(title.lower())          # golf course commercial
print(title.title())          # Golf Course Commercial (capitalize each word)

print(title.replace("Golf", "Surf"))  # Surf Course Commercial

print(len(title))              # 22 (count of characters including spaces)

print(title.startswith("Golf"))  # True
print(title.endswith("al"))      # True

messy = "  extra spaces  "
print(messy.strip())           # "extra spaces" — removes leading/trailing whitespace

# Chaining methods — each one returns a new string you can call the next on
filename = title.lower().replace(" ", "_")
print(filename)               # golf_course_commercial

Methods don't change the original string. title.upper() returns a new string. title is still "Golf Course Commercial" unless you reassign: title = title.upper().

Chaining works because every method returns a new string — so you can call another method on the result immediately. title.lower().replace(" ", "_") first lowercases, then replaces spaces with underscores.

Predict, Then Verify

Before running the code, write down what you think each print() will output. Then create strings.py, type the code, and run it. Check how many you got right. Prediction first is how you develop intuition — you can't get it by just reading.

Fix This Broken Code

The following code has three bugs. Find and fix all of them without running it first — read carefully and reason through each line. Then run to check.

project = "DVP Promo Film
print(project.Upper())
print(f"Project: {project.title()
print(len project)

Part 3: Multi-Line Strings

When your string spans multiple lines — like an AI prompt — use triple quotes. Everything between them is part of the string, including line breaks and indentation.

multiline.pyPython
platform = "Kling"
scene = 1

prompt = f"""
Scene {scene} — Platform: {platform}

Cinematic wide establishing shot of a golf course at golden hour.
Camera slowly pushes in from behind the tee box.
Shallow depth of field, filmic grain, 4K resolution.
Color grade: warm tones, lifted shadows.
"""

print(prompt)

Triple quotes work with f-strings too — just put the f before the first """. Every variable in curly braces still gets substituted. You'll write AI prompts like this constantly.

Do This Now

Create multiline.py. Write a triple-quoted f-string for a real shot from a DVP project — platform, scene, and a full cinematic prompt description. Run it and check the formatting.

Part 4: Build — formatter_v1.py

Now you have everything needed to upgrade the formatter. formatter_v1.py is identical to formatter_v0.py — except the project name, client, and three shots come from input() instead of being hard-coded.

Try the Faded Version First

Fill in the blanks. The output section at the bottom is identical to formatter_v0.py — only the data collection at the top changes. Use the 5-pattern table from Day 1 if you need it.

formatter_v1.py — fill in the blanksPython
print("=== DVP Shot Formatter ===")
print()

project = ____("Project name: ")
client  = ____("Client: ")

print()
print("--- Shot 1 ---")
desc1 = ____("Description: ")
plat1 = ____("Platform (Kling / Runway / Veo): ")
scene1 = ____       # still a number — no input() needed

print("--- Shot 2 ---")
desc2 = ____("____")
plat2 = ____("____")
scene2 = ____

print("--- Shot 3 ---")
desc3 = ____("____")
plat3 = ____("____")
scene3 = ____

# Output section — identical to formatter_v0, nothing changes here
print()
print(f"{'=' * 44}")
print(f"  {____.____()}")
print(f"  Client: {____}")
# ... continue the output from formatter_v0
Now Build the Full Version

Open formatter_v0.py and save it as formatter_v1.py. Replace every hard-coded string variable with an input() call. Don't change the formatting logic at the bottom — only the data collection at the top.

When you're done, running the script should ask:

Spend 10 minutes on this before looking at the solution below.

formatter_v1.py — data collectionPython
print("=== DVP Shot Formatter ===")
print()

# Project info
project = input("Project name: ")
client  = input("Client: ")

print()

# Shot 1
print("--- Shot 1 ---")
desc1 = input("Description: ")
plat1 = input("Platform (Kling / Runway / Veo): ")
scene1 = 1   # still hard-coded — we'll fix this tomorrow

print()

# Shot 2
print("--- Shot 2 ---")
desc2 = input("Description: ")
plat2 = input("Platform (Kling / Runway / Veo): ")
scene2 = 2

print()

# Shot 3
print("--- Shot 3 ---")
desc3 = input("Description: ")
plat3 = input("Platform (Kling / Runway / Veo): ")
scene3 = 3

# ── Output (same as v0 — nothing changes here) ──────────────────
print()
print(f"{'=' * 44}")
print(f"  {project.upper()}")
print(f"  Client: {client}")
print(f"{'=' * 44}")
print()
print(f"  Scene {scene1}  [{plat1}]")
print(f"  {desc1}")
print()
print(f"  Scene {scene2}  [{plat2}]")
print(f"  {desc2}")
print()
print(f"  Scene {scene3}  [{plat3}]")
print(f"  {desc3}")
print()
print(f"{'=' * 44}")

The output section is identical to v0. Only the top changed. This is a fundamental principle: separate where data comes from and what you do with it. You'll see this pattern in every real program.

Run It With Real Data

Run formatter_v1.py and enter a real DVP project. Look at the output. This is now a tool someone could actually use — they run the script, answer the questions, get a formatted shot list. Tomorrow you'll add numbers and runtime calculations.

How This Connects to Your Work

input() is the difference between a script that works on your data and one that works on anyone's data. Right now your evaluation notes probably live in xAI's web form — filled out by hand, one session at a time. A script that uses input() to collect them lets you capture that data in your own format, on your own terms, before it disappears into a system you don't control.

String methods are directly relevant too. Model names come in inconsistently: "grok aurora", "Grok", "GROK-AURORA-V1". .lower().replace() normalises them so your records are consistent and searchable. That normalisation habit is the difference between messy data and useful data — and useful data is what makes your evaluations referenceable later.

Try This at Work

xai_eval_v1.py — Upgrade yesterday's eval record so it asks you for the data instead of having it hard-coded. After a real xAI session, you should be able to run this and capture a clean record in under a minute.

Ask for:

model       = input("Model name: ")
prompt      = input("Prompt evaluated: ")
score       = input("Quality score (1-5): ")
notes       = input("Failure notes (or 'none'): ")

Then print a formatted eval record using f-strings. Use .title() to normalise the model name regardless of how you type it. The score stays as a string for now — Day 3 fixes that. Try running this immediately after your next real eval session and see how it feels to capture your own data.

Did You Make It?

Floor — Minimum Pass

The day counts.

  • Ran input_demo.py — it asked your name and used it
  • Ran formatter_v1.py — it accepted input for at least one shot
Goal — Today's Target

The real pass.

  • Predicted strings.py output before running it
  • Fixed all three bugs in the broken code challenge
  • Built formatter_v1.py — all inputs working, output formatted
  • Can explain why title.upper() doesn't change title
Honors — Great Day

Only if Goal is fully done.

  • Filled in the faded formatter_v1.py blanks before building the real version
  • Wrote multiline.py with a real DVP prompt in triple-quote f-string
  • Ran xai_eval_v1.py after a real session
Tomorrow: Numbers and a Completed Tool

You'll add numbers, math, and type conversion to the formatter — so it can also ask for clip counts, durations, and calculate total runtime. By end of Day 3, the formatter does real production math.

Optional: Reference

If you want to go deeper on string methods, Real Python has a comprehensive guide covering every method with clear examples. Dip into specific sections — don't read it front to back.

Strings and Character Data in Python — Real Python

Free reference guide. Read the sections that cover methods you used today.