Week 1 of 16

Numbers & formatter_v2

Add math and runtime calculations to the formatter — and learn the #1 beginner trap along the way

Day 3 60 minutes Build + Practice

Day 3 of 80

What You'll Build Today

Today's Format

Each concept comes with a "predict the output" exercise before you run anything. Write your prediction first. This single habit will develop your Python intuition faster than anything else.

Part 1: Numbers

Python has two kinds of numbers: integers (whole numbers) and floats (decimals). You don't declare which type — Python infers it from whether there's a decimal point.

numbers.pyPython
clip_count  = 12        # int  — whole number
fps         = 24        # int
duration    = 3.5       # float — has a decimal
score       = 8.7       # float

print(type(clip_count))   # <class 'int'>
print(type(duration))     # <class 'float'>

type() reveals what kind of data a variable holds. Use it when debugging — if a calculation produces a wrong result, check the types involved.

Math Operators

OperatorWhat it doesExampleResult
+Addition10 + 313
-Subtraction10 - 37
*Multiplication10 * 330
/Division — always gives a float10 / 33.333...
//Floor division — rounds down to int10 // 33
%Remainder (modulo)10 % 31
**Exponent2 ** 38
Predict First, Then Verify

Write down what you think each of these will print. Then open Python interactive mode (python in your terminal) and type each one to check:

>>> 17 / 5
>>> 17 // 5
>>> 17 % 5
>>> 2 ** 8
>>> 15 / 3
>>> 15 // 3

The last two will surprise most beginners — think about why before running them.

Write This Calculation

Open a new file called calc.py. Write code that calculates and prints: total clip time for a sequence of 8 clips at 3.5 seconds each, with 0.5-second transitions between clips. Use variables — don't hard-code the final number. The output should be 31.5 seconds.

Write it yourself before checking below.

calc.py — solutionPython
clip_count    = 8
avg_duration  = 3.5
transition    = 0.5

clip_time       = clip_count * avg_duration
transition_time = (clip_count - 1) * transition
total           = clip_time + transition_time

print(f"Total runtime: {total} seconds")
print(f"That's {total / 60:.1f} minutes")

:.1f inside an f-string formats a float to 1 decimal place. :.2f would give 2. You don't need to memorize these — just know they exist and that f means "float format".

(clip_count - 1) — there are one fewer transitions than clips. 8 clips = 7 gaps between them.

Part 2: The #1 Beginner Trap — Type Conversion

This trips up everyone. Here's the trap in plain language: input() always returns a string, even if the user types a number. You can't do math with a string.

See the Crash Yourself

Create trap.py and run it. Read the error message carefully — what is Python telling you?

clips = input("How many clips? ")
total_time = clips * 3.5
print(total_time)
Why It Crashes

You typed 8, but Python stored the text "8". Multiplying text by a float makes no sense — hence TypeError: can't multiply sequence by non-int of type 'float'. Python isn't being difficult — it's being precise.

The fix: wrap input() in int() or float(). Read it inside-out: first input() gets the text, then the conversion function turns it into a number.

trap_fixed.pyPython
# int() for whole numbers, float() for decimals
clips    = int(input("How many clips? "))
duration = float(input("Average clip length (seconds): "))

total_time = clips * duration
print(f"Total clip time: {total_time} seconds")

Use int() when you need a whole number (counts, IDs, scene numbers). Use float() when decimals are possible (durations, prices, percentages). F-strings handle str() conversion automatically — that's why f"Total: {total_time}" works even when total_time is a float.

Predict These Outputs

Without running, write what each line will print. Then verify in the Python REPL.

>>> int("7") + int("3")
>>> "7" + "3"
>>> str(42) + " shots"
>>> float("3.5") * 4

The first two are the key contrast. If you got them both right without running, you understand the type system.

Part 3: Build — formatter_v2.py

Now evolve the formatter. formatter_v2.py adds one question per shot: how long is this clip? With that, it can calculate and display the total sequence runtime.

Try the Faded Version First

The blanks show exactly where today's new concepts go. Fill them in using what you just learned about float(), int(), and arithmetic.

formatter_v2.py — fill in the blanksPython
# Shot 1 — add a duration input after the existing two inputs
print("--- Shot 1 ---")
desc1 = input("Description: ")
plat1 = input("Platform: ")
dur1  = ____(____(____))    # float of input — clip duration in seconds
scene1 = 1

# ... same pattern for Shot 2 and Shot 3 ...
dur2 = ____(____(____))
dur3 = ____(____(____))

# After all inputs — calculate total runtime
total_seconds = ____ + ____ + ____
total_minutes = ____ / ____

# In the output — add a runtime line before the closing divider
print(f"  Runtime: {____:.1f}s  ({____:.1f} min)")
print(f"{'=' * 44}")
Now Build the Full Version

Open formatter_v1.py and save it as formatter_v2.py. Add these changes:

  1. After each shot's input, add: dur1 = float(input("Clip duration (seconds): "))
  2. After all three shots are collected, calculate: total_runtime = dur1 + dur2 + dur3
  3. Add a runtime line to the output: Total runtime: X.X seconds (X.X min)

Give it 10 minutes. It's just applying what you just learned to code you already wrote.

formatter_v2.py — key additionsPython
# In the data collection section, add a duration for each shot:
print("--- Shot 1 ---")
desc1 = input("Description: ")
plat1 = input("Platform: ")
dur1  = float(input("Clip duration (seconds): "))
scene1 = 1

# ... same for Shot 2 and Shot 3 ...

# Calculate total runtime after collecting all shots:
total_seconds = dur1 + dur2 + dur3
total_minutes = total_seconds / 60

# In the output section, add runtime to the footer:
print()
print(f"  Runtime: {total_seconds:.1f}s  ({total_minutes:.1f} min)")
print(f"{'=' * 44}")

Notice where the calculation happens: after all the inputs, before the output. Input, process, output — the same three-part structure you'll see in every script.

Also notice dur1 = float() not int() — clip durations have decimals (3.5s, 4.2s). Always choose the right type for the data.

Run It With Real Numbers

Run formatter_v2.py and enter three real shots with realistic durations. The output should now show formatted shots and a calculated runtime. If the runtime looks wrong, check whether you used float() not int() for the durations.

How This Connects to Your Work

Quality scores are numbers. Everything analytically interesting you could extract from your evaluation history — average score per model, score variance across sessions, how Kling compares to Runway on motion accuracy — requires exactly the math you learned today. Right now that analysis lives in your head. Python gives it a place to live.

The type conversion lesson is also directly relevant to evaluation work: any time you read scores from a CSV, a form response, or a log file, they arrive as strings. int() is always step one. Every data pipeline at every AI lab starts with this exact conversion.

Try This at Work

session_stats.py — Upgrade xai_eval_v1.py so the score is now a real number. Ask for three separate quality scores from a session (e.g. coherence, prompt adherence, safety), convert them all with int(), calculate the average, and display a summary.

model      = input("Model: ")
score_coh  = int(input("Coherence score (1-5): "))
score_adh  = int(input("Prompt adherence (1-5): "))
score_safe = int(input("Safety score (1-5): "))

average = (score_coh + score_adh + score_safe) / 3

print(f"\n{model.title()} — Session Summary")
print(f"  Coherence:   {score_coh}/5")
print(f"  Adherence:   {score_adh}/5")
print(f"  Safety:      {score_safe}/5")
print(f"  Average:     {average:.1f}/5")

Run this with scores from a real session. Notice what it can't do yet: it can't tell you what percentage of your sessions scored below 3, or which model averages highest. That requires loops and lists — Week 2. But you'll feel exactly why you need them, which is the whole point.

When You Hit an Error Today
  1. Read the last line of the error message — that's the diagnosis
  2. Find the line number Python mentions
  3. Say out loud what Python expected to see there
  4. Make one small change and run again
  5. Only after all four steps — ask Claude or search

Did You Make It?

Floor — Minimum Pass

The day counts.

  • Ran trap.py, saw the crash, fixed it in trap_fixed.py
  • Ran formatter_v2.py at least once with real inputs
Goal — Today's Target

The real pass.

  • Predicted all four REPL outputs before running them
  • Wrote calc.py from scratch with variables — not hard-coded math
  • Built formatter_v2.py — runtime calculates correctly
  • Can explain: why does "7" + "3" give "73"?
Honors — Great Day

Only if Goal is fully done.

  • Filled in the faded formatter_v2.py blanks before building it
  • Added M:SS runtime format using // and %
  • Ran session_stats.py with real evaluation scores
Tomorrow: The Finished Tool

Day 4 is the biggest build of the week. You'll add a project header, a timestamp, and file-saving — so formatter_v3.py writes a formatted .txt file you could actually hand to a client. Everything you need, you already know.

Optional Reference: Numbers in Python

If you want to go deeper on Python number types, arithmetic, and formatting, Real Python's guide is the best free resource. Read the "Basic Numeric Types" and "Arithmetic Operators and Expressions" sections.

Numbers in Python — Real Python

Free reference guide. Covers integers, floats, arithmetic, and math functions in depth.