Worked examples — Input with `input()` — always returns string, conversion needed
The scenario matrix
Before any code, let's list every distinct situation the same line int(input(...)) or float(input(...)) can land in. Think of this as the full map — each worked example below fills exactly one cell.
| Cell | User types | Converter | What happens |
|---|---|---|---|
| A — clean whole number | 42 |
int() |
works → 42 |
| B — clean decimal | 3.14 |
float() |
works → 3.14 |
| C — negative sign | -7 |
int() |
works → -7 (sign kept) |
| D — surrounding spaces | 9 |
int() |
works → 9 (spaces trimmed) |
| E — zero / degenerate | 0 or empty |
int() |
0 works; empty crashes |
F — decimal into int() |
3.5 |
int() |
crashes (ValueError) |
| G — letters (garbage) | twenty |
int() |
crashes (ValueError) |
| H — forgot to convert | 3 then 4 |
none | + joins → "34" (wrong) |
| I — word problem | mixed | float/int |
real calculation |
| J — exam twist | tricky mix | you decide | reason it out |
The three big axes here are: (1) which converter matches the meaning (whole vs decimal), (2) sign and whitespace (does the text survive cleaning?), and (3) does the text even look like a number at all (or does it crash?). The picture below shows those three axes as a decision funnel.

Now let's fill every cell.
Case A — the clean whole number
Case B — the clean decimal
Case C — the negative sign survives
Case D — spaces around the number
Case E — zero and the degenerate empty input
This cell has two sub-cases because "nothing typed" is the true edge of the map.
count = int(input("Count: ")) # user just types 0
print(count + 1)Forecast: is 0 special? Crash or 1?
Steps:
input()→"0".int("0")→0. Zero is an ordinary integer; nothing degenerate about it toint().0 + 1 = 1.
Verify: . Prints 1. ✓
x = int(input("Number: ")) # user presses Enter without typingForecast: what does int("") do?
Steps:
input()→""— the empty string, zero characters.int("")→ crashes withValueError: invalid literal for int() with base 10: ''. Why:int()needs at least one digit to read. An empty string spells no number at all — this is the degenerate limit where there's nothing to convert.
Verify (conceptually): empty is not 0; empty is absence of a number. Guard it with Exceptions and try-except:
try:
x = int(input("Number: "))
except ValueError:
print("Please type a whole number.")Case F — a decimal fed to int()
x = int(input("Enter: ")) # user types 3.5Forecast: 3, 4, or crash?
Steps:
input()→"3.5".int("3.5")→ crashesValueError. Why (subtle!):int()does not round or truncate a string — it demands the text spell a whole number."3.5"contains a., which is not part of a whole-number spelling, so it refuses. Contrast:int(3.5)(on a float, not a string) →3(truncates). Butint("3.5")(on a string) crashes. The.in text is the killer.
Verify: the correct tool here is float: float("3.5") → 3.5. If you truly want the integer part, do int(float("3.5")) → 3.
Look at the picture below — it shows the two-hop route str → float → int that survives a decimal, versus the direct str → int road that hits a wall.

Case G — letters and garbage
n = int(input("How many? ")) # user types "twenty"Forecast: does Python understand English number words?
Steps:
input()→"twenty".int("twenty")→ crashesValueError: invalid literal for int() with base 10: 'twenty'. Why:int()reads digit characters (0–9) plus an optional sign — not English words."twenty"is letters; no digit to be found.
Verify (guarded version):
raw = input("How many? ")
try:
n = int(raw)
print("Got", n)
except ValueError:
print(raw, "is not a whole number.")For "twenty" this prints twenty is not a whole number. — no crash. This is the production-safe pattern; see Exceptions and try-except.
Case H — forgetting to convert (the flagship bug)
+ joins instead of adding
a = input("First: ") # user types 3
b = input("Second: ") # user types 4
print(a + b)Forecast: 7 or something else?
Steps:
a = "3",b = "4"— both strings, no conversion happened.a + b="3" + "4". Why this joins: for two strings,+means concatenate — glue them end to end. The characters'3'and'4'sit next to each other.
Verify: "3" + "4" = "34". Prints 34, not 7. To fix: print(int(a) + int(b)) → 7.
This is the single most common beginner trap — you now know why the type, not the digits, decides what + does.
Case I — the word problem (real-world mix)
Statement: A shop asks for the item price (may have cents), the quantity (whole items), and a discount percent (may be fractional, like 12.5). Compute the final amount paid.
price = float(input("Price per item: ")) # 19.99
qty = int(input("Quantity: ")) # 3
discount = float(input("Discount %: ")) # 10
subtotal = price * qty
final = subtotal * (1 - discount / 100)
print("Pay:", round(final, 2))Forecast: with 19.99, 3, 10 — what's the final amount?
Steps:
price = float("19.99")→19.99. Why float? money has cents — a fractional part.intwould crash on the..qty = int("3")→3. Why int? you can't buy half an item; quantity is a whole count.discount = float("10")→10.0. Why float? discounts can be12.5\%; usingfloatkeeps it flexible even when the user types a whole10.subtotal = 19.99 * 3 = 59.97.final = 59.97 * (1 - 10/100) = 59.97 * 0.9. Why divide by 100?10\%means "10 per hundred" =0.10.1 - 0.10 = 0.90keeps 90% of the price.
Verify (units too): dollars × count = dollars; dollars × (unitless fraction) = dollars ✓.
. Prints Pay: 53.97. ✓
Case J — the exam-style twist
Statement: Predict the exact output. The user types 5 then 2.
x = input("a: ") # 5
y = int(input("b: ")) # 2
print(x * y)Forecast: 10, 52, 55, or crash? This one is nasty — think about the type of each operand.
Steps:
x = "5"— a string (no conversion on line 1).y = 2— an int (converted on line 2).x * y="5" * 2. Why this is legal and NOT a crash:string * intis defined in Python — it repeats the stringinttimes!"5" * 2="55". (This is different from"ab" * "3"in the parent note, which crashes because that'sstr * str.)
Verify: "5" * 2 = "55". Prints 55. Not 10 (that would need both to be numbers), not 52. The lesson: str * int = repeat, int * int = multiply. Type decides the operation. See Operators in Python.
Master recall
int(" -7 ")→ ? :::-7(sign kept, spaces trimmed) — Cells C+Dint("3.5")→ ? ::: crash,ValueError(dot in string) — Cell Fint("")→ ? ::: crash,ValueError(empty) — Cell E2"5" * 2→ ? :::"55"(string repeat) — Cell J"3" + "4"→ ? :::"34"(concatenate) — Cell H- How to safely read a number from untrusted input? ::: wrap
int(input())intry/except ValueError— Cells E2/G
"Match the meaning, then convert." Whole count → int. Has a dot → float. Untrusted → try. Forgot → + bites you.
Connections
- Parent topic — the golden rule this page stress-tests.
- Type Conversion (Casting) — the
str → float → inttwo-hop of Case F. - String Concatenation vs Arithmetic — why Case H prints
34. - Exceptions and try-except — guarding Cases E2 and G.
- Operators in Python — why Case J's
str * intrepeats. - Variables and Data Types — the
str/int/floattriad behind every cell. - print() Function — the output side of all examples.