Exercises — Input with `input()` — always returns string, conversion needed
One term appears again and again in the solutions below, so let's pin it down once, here on this page:
Before we start, one picture of the whole journey — every exercise is a step somewhere on this pipeline:

Level 1 — Recognition
Goal: can you name the type of a value without running the code?
Recall Solution 1.1
What we're asked: the type of x, not its value.
The one fact: input() always returns a str. It does not matter that the characters look like a number — the microphone recorded text.
Answer: <class 'str'>
The little <class '...'> wrapper is just how Python prints a type object. The important word inside is str.
Recall Solution 1.2
- (i)
a→str. Rawinput()is always text:"5". - (ii)
b→int.int("5")reads the digit-text and builds the number5. - (iii)
c→float.float("5")builds5.0. - (iv)
d→ error (ValueError). Here's the subtle one:int()on the string"5.0"fails, because"5.0"is not a whole-number spelling — it contains a dot.int()only accepts strings that look like plain integers. (float("5.0")would work; so wouldint(float("5.0")).)
Level 2 — Application
Goal: convert correctly so real operations work.
Recall Solution 2.1
- (i)
aandbare both strings, so+joins them:"3" + "4"→"34". Printed:34. - (ii)
int(a)is3,int(b)is4, so+now adds numbers:3 + 4→7. Printed:7.
Same +, two behaviours — decided entirely by the types of what sits either side. (See String Concatenation vs Arithmetic.)
Recall Solution 2.2
price = float(input("Price: ")) # "19.99" -> 19.99
qty = int(input("Quantity: ")) # "3" -> 3
print("Total:", price * qty) # Total: 59.97Why float for price, int for quantity? The meaning of the data chooses the converter. Money can have cents (a fractional part) → float. You can't buy 3.5 items in this model → int. Output: Total: 59.97.
Recall Solution 2.3
n = int(input("How many? ")) # "3" -> 3
print("go" * n) # gogogoOutput: gogogo.
Forgetting the conversion: "go" * "3" raises TypeError: can't multiply sequence by non-int of type 'str'. String-times-string is meaningless; string-times-int means "repeat". You must hand * an actual int.
Level 3 — Analysis
Goal: predict why code succeeds, fails, or crashes.
Recall Solution 3.1
- (i)
42— clean integer text. - (ii)
42—int()strips surrounding whitespace before parsing, so leading/trailing spaces are fine. - (iii)
ValueError— the dot makes it non-integer text;int()refuses. - (iv)
ValueError— letters are not a number spelling. - (v)
ValueError— the empty string has nothing to parse (this is the "user just pressed Enter" case — always possible!). - (vi)
3.5—float()accepts decimals. - (vii)
1000.0—float()understands scientific notation. Here1e3means "1 followed by 3 zeros", i.e. one thousand.
Pattern: int() is the strictest gate (whole-number spelling only). float() is more forgiving (dots, e-notation). Neither accepts letters. (See Type Conversion (Casting).)
Recall Solution 3.2
What happens: the user typed 20.5, so input() returns "20.5", and int("20.5") raises ValueError — the program crashes before print ever runs.
Why: int() cannot represent the fractional .5; it does not silently round or truncate a string, it rejects it.
Fix: use the converter that matches the data's meaning — decimals need float:
age = float(input("Age: ")) # "20.5" -> 20.5
print(age + 1) # 21.5Output: 21.5.
Level 4 — Synthesis
Goal: combine input, conversion, and guarding into a working routine.
Recall Solution 4.1
a = int(input("a: ")) # "12" -> 12
b = int(input("b: ")) # "4" -> 4
print("sum:", a + b) # sum: 16
print("diff:", a - b) # diff: 8
print("prod:", a * b) # prod: 48
print("quot:", a // b) # quot: 3Why convert once at the top? We convert each input immediately into a named int, then reuse a and b everywhere. Convert-early means every later line can assume it is working with real numbers — no repeated int(...), no line accidentally left as text. Outputs: 16, 8, 48, 3 (// is integer division: 12 shared into 4 gives exactly 3).
Recall Solution 4.2
try:
age = int(input("Age: "))
print("Next year you are", age + 1)
except ValueError:
print("Not a whole number!")- Input
twenty:int("twenty")raisesValueError; control jumps to theexceptblock → printsNot a whole number!. No crash. - Input
19:int("19")succeeds →19, then printsNext year you are 20.
Why try/except here? Bad input is not a programming mistake — it is a runtime event you can expect. You catch exactly the error int() throws (ValueError, defined at the top of this page) and respond gracefully. (See Exceptions and try-except.)
Level 5 — Mastery
Goal: design robustly for every case, including the degenerate ones.
Recall Solution 5.1
while True:
raw = input("Positive whole number: ")
try:
n = int(raw)
except ValueError:
print("That's not a whole number, try again.")
continue
if n <= 0:
print("Must be positive, try again.")
continue
break # only reached when n is a valid positive int
print("Thanks! You gave", n)Trace:
hi→int("hi")raisesValueError→ prints "not a whole number" →continue→ loop again.3.5→int("3.5")raisesValueError(the dot!) → same message → loop again.-4→int("-4")succeeds (negative integers are valid integer text) → butn <= 0isTrue→ prints "Must be positive" → loop again.7→int("7")=7, and7 <= 0isFalse, so we reachbreak. Final print:Thanks! You gave 7.
Why two separate guards? try/except catches malformed text (cases a, b). The if n <= 0 catches well-formed but unwanted values (case c). These are different kinds of failure and each needs its own defence. Notice case (b) is caught by the same net as (a), because int() rejects "3.5" as a string.
Recall Solution 5.2
Pressing Enter with no typing makes input() return the empty string "".
Then int("") raises ValueError — there is no text to parse.
This is caught by our except ValueError block → prints "not a whole number, try again" → loops. So yes, it is handled, for free, by the same guard that catches hi. This is exactly why we must think about the degenerate empty input: it is the single most common thing a distracted user does, and a robust routine survives it without special-casing.
Connections
- Parent topic — the core rule these exercises drill.
- Variables and Data Types —
strvsintvsfloat. - Type Conversion (Casting) —
int(),float()behaviour in depth. - String Concatenation vs Arithmetic — why
+gives"34". - Operators in Python — overloaded
+and*. - Exceptions and try-except — catching
ValueError. - print() Function — displaying the results.