Week 3 — Lecture Outline · Input / Output & Strings
Course: Introduction to Computer Science — CS1 / Programming Fundamentals in Python (CSCI 1101) · Silver Oak University (fictional sample) · Prof. Okafor
Objective covered: Objective 2 — Use variables, data types, expressions, and input/output — read input with input(), build output with f-strings, and work with strings (indexing, slicing, len).
SLOs touched: A (write and run a correct interactive program) · B (trace slice/index output and predict it; find and fix an input()/IndexError defect)
Meeting pattern: 2 studio sessions × 75 min = 150 min. Segment minutes below total ~150; scale to your own pattern.
Every code output, traced value, and error type in this outline was produced by actually running the code in Python — not hand-traced. Run them live in class; the outputs are exact. (Slices especially — the room will guess wrong, and that's the lesson.)
Week at a Glance
| The week's big question | "How does a program take what a person types and turn it into a useful, personalized response?" |
| By the end of the week, students can… | (1) read input with input() and build output with an f-string; (2) explain why input() always returns a str and fix the bug with int(input()); (3) index and slice strings (s[0], s[-1], s[1:4], s[:3], s[2:], s[::2]) knowing the stop is exclusive; (4) use len(s) and recognize an IndexError. |
| Key vocabulary | input(), prompt, string (str), type conversion / cast, int(), concatenation (+), f-string, placeholder { }, index, indexing, zero-based, negative index, slice, slicing, start / stop / step, exclusive stop, len(), IndexError, TypeError |
| Materials | slides (Deck 3), the week's readings + reference links, a free online Python environment + Python Tutor (links in the readings), one approved chatbot (Gemini / Claude / ChatGPT) for the AI-critique moment and the tutorial |
| Timing note | 8 segments, ~150 min total. Session 1 = Segments 1–4 (~75). Session 2 = Segments 5–8 (~75). This is a studio: code along on the projector and have students type every example into the online environment with you. For input() examples, type a sample value when the program pauses and show the class exactly what was typed. |
Segment 1 — Hook & the Promise (8 min) · Session 1 opens
Hook. Pull up last week's program — something like print("Hello, Sam!") — and ask: "What's wrong with this as a greeting app?" Someone will say it: it only ever greets Sam. Right. It's a greeting that can't greet anyone but the name we baked in. Then type one line live:
name = input("What's your name? ")
print(f"Hello, {name}!")
Run it, and when it pauses, type a student's name. It greets them. The room feels the difference instantly: the program just talked to a person.
The promise (write it on the board): "By Friday your programs will ask a question, take what someone types, and build a personalized answer — and you'll have met the single most common beginner bug head-on: forgetting that input() hands you a string."
Why it matters line (memory hook): "input() always gives you a string — convert it with int() if you need to do math."
Segment 2 — input() and the "Always a String" Rule (22 min)
Plain language first. input() is a command that pauses the program, waits for the person to type a line and press Enter, and hands that line back to you as text. You usually give it a prompt — the message shown to the user — like input("Your name: "). Whatever they type, you capture in a variable.
Code-along #1 — capture and use it (everyone types it):
name = input("Your name: ")
print("Nice to meet you,", name)
Run it; type Sam. Output (run-verified, with Sam typed):
Nice to meet you, Sam
"input waited, took Sam, and stored it in name. Now we can use that variable anywhere."
The load-bearing rule — say it slowly. input() ALWAYS returns a string — even if the person types digits. Prove it:
x = input("Type a number: ")
print(type(x))
Run it; type 5. Output (run-verified):
<class 'str'>
"You typed 5, but Python stored the string '5', not the number 5. The type is str. This is true every single time input() runs."
The classic bug (do it live — let it crash). "Let's ask for an age and print next year's age."
age = input("Your age: ")
print("Next year you'll be", age + 1)
Run it; type 25. Python stops with (run-verified):
TypeError: can only concatenate str (not "int") to str
"We tried to add the number 1 to the string '25'. Python won't glue a number onto text. The error even tells us: 'can only concatenate str … to str.'"
The fix — convert it (cast to int):
age = int(input("Your age: "))
print("Next year you'll be", age + 1)
Run it; type 25. Output (run-verified):
Next year you'll be 26
"int(...) converts the string '25' into the number 25, and now the math works. Rule of thumb: need to do math? Wrap input() in int()."
Land the related trap ("5" + 3 vs "5" + "3"):
print("5" + "3")
Output (run-verified): 53 — two strings join, they don't add. And print("5" + 3) would crash with the same TypeError as above. "Quotes mean text; text joins. To add numerically, both sides must be numbers."
Segment 3 — Building Output: f-strings + Concatenation (the code-along) (22 min)
Set it up: "We can read a name. Now let's build a nice sentence around it. There are two ways to drop a value into text — and one is much cleaner."
Way 1 — concatenation with + (works, but clunky with non-strings):
name = "Ada"
print("Hello, " + name + "!")
Output (run-verified):
Hello, Ada!
"+ joins strings end to end. Notice the spaces and the ! are part of the strings — you have to place them yourself. And every piece must be a string, or you get that TypeError again."
Way 2 — the f-string (cleaner, this week's star):
name = "Ada"
print(f"Hello, {name}!")
Output (run-verified):
Hello, Ada!
"Put an f right before the opening quote, then drop a variable inside curly braces { }. Python replaces {name} with its value. Same output, far easier to read — and it handles numbers without a manual conversion."
f-strings shine with numbers (no manual str() needed):
score = 42
print(f"You scored {score} points.")
Output (run-verified):
You scored 42 points.
"With + you'd have had to convert 42 to a string first. The f-string just does it. From now on, f-strings are our default way to build output."
Tie it back to input (the whole week in three lines):
name = input("Your name: ")
print(f"Welcome, {name}!")
Run it; type Sam. Output (run-verified, with Sam typed):
Welcome, Sam!
Segment 4 — Trace This Code: Indexing & Slicing → What Does It Print? (24 min) · Session 1 closes (~75)
Set it up: "A string is a sequence of characters, and Python lets us reach in and grab pieces. Before we run anything, we'll predict — and slices are where everyone's gut is wrong, so this is exactly where we practice tracing."
Draw the index ruler on the board (use "PYTHON"):
+---+---+---+---+---+---+
| P | Y | T | H | O | N |
+---+---+---+---+---+---+
0 1 2 3 4 5
-6 -5 -4 -3 -2 -1
"Counting starts at 0 from the left, and at -1 from the right. len("PYTHON") is 6, so the valid indices are 0 through 5."
Worked trace #1 — single characters (predict, then run):
s = "PYTHON"
print(s[0])
print(s[-1])
print(s[2])
- Trace:
s[0]is the first characterP;s[-1]is the last characterN;s[2]isT(positions 0,1,2 → P,Y,T). - Output (run-verified):
P
N
T
Worked trace #2 — slicing, and the exclusive stop (the off-by-one):
s = "PYTHON"
print(s[1:4])
- Trace: a slice
s[start:stop]takes characters fromstartup to but NOT includingstop. Sos[1:4]is positions 1, 2, 3 →Y,T,H. Position 4 (O) is excluded. - Predicted by most students:
YTHO(they include 4). Run it. Actual output (run-verified):
YTH
"This is THE slice trap: the stop is exclusive. s[1:4] gives you 3 characters (4 − 1 = 3), ending just before index 4. When you're unsure, run it."
Worked trace #3 — defaults and step:
s = "PYTHON"
print(s[:3])
print(s[2:])
print(s[::2])
- Trace:
s[:3]— omit the start, it defaults to 0 → positions 0,1,2 →PYT.s[2:]— omit the stop, it defaults to the end → positions 2,3,4,5 →THON.s[::2]— start to end, step 2 → positions 0,2,4 →PTO. - Output (run-verified):
PYT
THON
PTO
Quick interaction (rapid-fire, ~5 min): put three on a slide; students predict solo (20 sec), then you run each. Suggested with run-verified outputs on s = "PYTHON": print(s[-2]) → O; print(s[1:3]) → YT; print(len(s)) → 6.
Segment 5 — Reading Errors: IndexError (and why len is your guardrail) (18 min) · Session 2 opens
Hook back in: "Last session you grabbed characters and slices. Today: what happens when you reach for a character that isn't there — and how len keeps you safe."
Plain language first. A string of length n has valid indices 0 through n − 1. Ask for one past the end and Python stops with an IndexError.
Live demo — an IndexError:
s = "cat"
print(s[5])
Run it. Python stops with (run-verified):
IndexError: string index out of range
"'cat' has length 3 — valid indices 0, 1, 2. There is no index 5, so: IndexError: string index out of range. Read the last line; it names exactly what went wrong."
The guardrail — len tells you the boundary:
s = "cat"
print(len(s))
print(s[len(s) - 1])
Output (run-verified):
3
t
"len(s) is 3, so the last valid index is len(s) - 1, which is 2 → t. Reaching for s[len(s)] would be one too far. This is the same off-by-one as the slice stop, wearing a different hat."
The kind reminder — slices forgive, indexing doesn't:
s = "cat"
print(s[1:99])
Output (run-verified):
at
"Curious detail: an out-of-range slice doesn't crash — Python just stops at the end and gives you at. An out-of-range index does crash. Slicing is forgiving; indexing is strict."
Misconception + cure:
- ❌ "len('cat') is 3, so s[3] is the last letter."
✅ Cure: len counts characters (3), but indices start at 0, so the last valid index is len(s) - 1 = 2. s[3] is one past the end → IndexError. Use s[-1] for the last character.
Segment 6 — Spot & Fix the Bug (the debugging demo) (18 min)
Set it up: "Here's a program that's supposed to greet someone and tell them their age next year — but it crashes. Let's debug it: find the bug, predict the fix, run to confirm."
The buggy program (put it on a slide exactly as is):
age = input("How old are you? ")
print("Next year you will be " + age + 1)
Debug it out loud:
1. Run it; type 30. Python says (run-verified): TypeError: can only concatenate str (not "int") to str.
2. Read the message: we're trying to glue the number 1 onto a string. Two problems hiding together: age is a string (because input() always returns a string), and we used + to mix text and a number.
3. The bug: age was never converted to a number, and + 1 tries to add a number to text.
4. The fix — convert the input to int, and build the sentence with an f-string so the number drops in cleanly. Then run to confirm:
age = int(input("How old are you? "))
print(f"Next year you will be {age + 1}")
Run it; type 30. Output (run-verified):
Next year you will be 31
"Two lessons in one bug: int(input()) when you need math, and f-strings make mixing text and numbers painless."
A second quick bug (let the room solve it): s = "PYTHON" then print(s[6]) → run-verified IndexError: string index out of range. The fix: the last index is 5 (or use s[-1]), because len("PYTHON") is 6 and indices start at 0.
Land the key idea: debugging is a loop, not a flash of genius. Run → read the error's last line → form a guess → make one change → run again. The two bugs you'll hit most this week are "I forgot input() is a string" and "I went one index too far."
Segment 7 — Misconceptions Round-Up + Quick Interaction (20 min)
Name the misconceptions out loud, then cure each:
- ❌ "
input()gives me a number if the user types a number."
✅ Cure: it always returns astr. Type-check it:type(input())is<class 'str'>. Wrap it inint()to do math. - ❌ "
s[1:4]includes index 4."
✅ Cure: the stop is exclusive.s[1:4]is positions 1, 2, 3 → for"PYTHON",YTH. Run it. - ❌ "The last character of
'cat'iss[3]."
✅ Cure: indices start at 0, so the last iss[2]— or justs[-1].s[3]is anIndexError. - ❌ "
"5" + "3"is 8."
✅ Cure: strings join →53. And"5" + 3crashes (TypeError). Quotes decide. - ❌ "f-strings and regular strings are the same."
✅ Cure: only an f-string (thefbefore the quote) replaces{name}with the variable's value; a plain string prints{name}literally.
Interaction — Predict-then-Run (rapid-fire, ~8 min): put four on a slide; students predict each output solo (30 sec), compare with a neighbor (1 min), then you run all four. Suggested with run-verified outputs (let s = "PYTHON", name = "Ada"): print(s[:2]) → PY; print(s[::2]) → PTO; print(f"Hi {name}") → Hi Ada; print(len("hello")) → 5. Tally the room — celebrate the slice misses as "this is why we run code."
Segment 8 — Technology Workflow + AI-Critique, Callback & Hand-off (18 min) · Session 2 closes (~75)
Technology workflow — the everyday loop, on demand:
1. Open the free online Python environment (link in the readings). Type your code.
2. Press Run. When the program pauses on input(), type a value in the console and press Enter.
3. If it's an error, read the last line first; it names the problem (TypeError, IndexError).
4. To watch a slice happen step by step, paste it into Python Tutor and step forward.
AI-critique moment (students verify, not consume):
Paste this to an approved chatbot: "What does this Python print?
s = "PYTHON"; print(s[1:4])— and alsoprint(s[::2])andprint(s[-2]). Give the exact output of each."
Then check its work by running all three yourself. Chatbots routinely mis-trace slices — they slip on the exclusive stop (claimings[1:4]isYTHOorYTinstead ofYTH) and miscount steps and negative indices, stating it all with total confidence. Your job all semester: the tool drafts, you run it and judge. This is exactly how the weekly Lecture Tutorial and Coding Lab work — you catch the model, not trust it.
Callback + tease:
- Callback: "Today: reading input, the 'always a string' rule and int(input()), building output with f-strings, indexing and slicing with an exclusive stop, len, and the IndexError. Everything that talks to a user builds on this."
- Tease next week: "Right now our programs ask and answer, but they can't yet decide. Next week we give them judgment — Booleans and conditionals — comparison operators (==, <, >), truth tables, and if / elif / else, so a program can validate that input and react differently to it. (That's also exactly what this week's discussion is decomposing.)"
Hand-off (the week's graded work):
- Lecture Tutorial 3 (AI tutor, share-link submission) — input(), the string rule, indexing, slicing, f-strings.
- Quiz 3 and Discussion 3 ("Decompose a Validator") and Assignment 3 ("Input, Slice & Fix").
- Coding Lab 3 — "Ask, Slice, Fix" — write an interactive f-string program, trace a slice table, and fix an input() bug in the online environment.
Instructor FAQ — Common Stumbles
| Student says / does | Quick cure |
|---|---|
"My program crashed with a TypeError when I added 1 to the input." |
input() returns a string; "25" + 1 mixes text and number. Wrap it: int(input()). |
"It printed {name} literally instead of the name." |
They forgot the f before the quote. Only an f-string substitutes {name}. |
Thinks s[1:4] includes index 4. |
The stop is exclusive — s[1:4] is indices 1,2,3 → YTH for "PYTHON". Run it. |
Reaches for s[len(s)] as the last character. |
That's one past the end → IndexError. Last index is len(s) - 1; or just use s[-1]. |
Surprised "5" + "3" is 53, not 8. |
Strings join; + on text concatenates. Convert with int() to add numerically. |
"input() should know I typed a number." |
It never does — it always returns str. Convert on purpose with int() (or float()). |
| Out-of-range slice "should" crash but didn't. | Slices are forgiving (s[1:99] → at); only out-of-range indexing raises IndexError. |
| "I'll just trust the chatbot's slice answer." | Chatbots miscount the exclusive stop constantly. The loop is edit → run → read → fix. Always run. |
Scope flag
This outline stays within Objective 2 (variables, data types, expressions, and input/output, with strings: indexing, slicing, f-strings, len). We use only this-week and prior-week constructs — print, variables and arithmetic (Week 2), input(), int(), string literals, indexing/slicing, len, f-strings — plus the two errors that arise naturally here (TypeError from mixing text and numbers, IndexError from over-indexing). Booleans and conditionals (if/elif/else, comparison operators) are Week 4 and only teased; loops, functions, and string methods (.upper(), .split(), etc.) come later (string methods in depth are Week 11). Python and its error names (TypeError, IndexError) are referenced factually; the instructor and institution remain fictional. Every output shown was produced by running the code.
~ Prof. Okafor's edition · Fall 2026 · built with thecoursemaker.com