RizTech Academy logo
RizTech Academy
Variables and Data TypesLesson 5 of 515 min

Type conversion and why input() always gives you a string

You now know the basic types. This lesson is about moving between them, and about the mistake that almost every Python beginner makes exactly once — usually while writing their first program that asks a question.

Converting on purpose

Each type has a function named after it:

print(int("42"))        # 42     — string to int
print(float("3.14"))    # 3.14   — string to float
print(str(42))          # "42"   — int to string
print(bool(1))          # True

Converting between numbers works as you would expect, with one detail:

print(int(3.9))     # 3
print(int(-3.9))    # -3

int() truncates — it chops the decimal part off rather than rounding. int(3.9) is 3, not 4. When you want rounding, say round().

Note that this differs from //, which floors:

print(int(-3.9))    # -3   — towards zero
print(-3.9 // 1)    # -4.0 — towards negative infinity

Both are correct; they answer different questions.

input() always gives you a string

Here is the one.

input() shows a prompt and returns what the user typed. Always as a string. Always. Even when they typed digits and nothing else.

age = input("How old are you? ")
print(age + 10)
How old are you? 25
TypeError: can only concatenate str (not "int") to str

The user typed 25, but age is the string "25", and you cannot add a number to a string.

The fix is to convert as you read:

age = int(input("How old are you? "))
print(age + 10)
How old are you? 25
35

Read the inner brackets first: input(...) runs, returns "25", and int(...) turns it into 25.

A subtler version of the same trap, where nothing crashes at all:

a = input("First number: ")
b = input("Second number: ")
print(a + b)
First number: 2
Second number: 3
23

No error. Just a wrong answer — because + on two strings joins them. This kind of bug is worse than a crash, since nothing tells you anything is wrong. Whenever a number comes out strange, check the types first:

print(type(a))

When conversion fails

int("hello")
ValueError: invalid literal for int() with base 10: 'hello'

ValueError means the type was right — a string is what int() expects — but the value inside it was not usable. Compare with TypeError, which means the type itself was wrong. Reading that distinction correctly saves real time when debugging.

These all fail too, and the third is the one people do not expect:

int("")         # ValueError — empty string
int("12.5")     # ValueError — int() will not accept a decimal point
int(None)       # TypeError  — wrong type entirely

int("12.5") fails because int() parses whole numbers only. Go via float:

print(int(float("12.5")))    # 12

Two things that do work, and are worth knowing:

print(int("  42  "))    # 42   — surrounding whitespace is ignored
print(int("-42"))       # -42  — a leading sign is fine

That first one is quietly helpful, since text from users and files often arrives padded.

Checking before you convert

Rather than converting and hoping, you can ask first:

value = input("Enter a number: ")

if value.isdigit():
    number = int(value)
    print(number * 2)
else:
    print("That was not a whole number.")

isdigit() has limits worth knowing: it returns False for "-5" and for "3.14", because neither is made only of digits. For anything beyond simple positive integers, the honest approach is to try the conversion and handle the failure — which is try/except, and the subject of module 6.

For now, isdigit() is enough.

Converting to string

str() works on anything:

print(str(42))           # "42"
print(str(3.14))         # "3.14"
print(str(True))         # "True"
print(str(None))         # "None"
print(str([1, 2, 3]))    # "[1, 2, 3]"

In practice you rarely call it, because f-strings convert for you:

age = 25
print(f"I am {age} years old")    # no str() needed

That is one more reason to prefer f-strings over +.

Truthiness, converted

bool() follows the rules from the last lesson:

print(bool("False"))    # True  — a non-empty string
print(bool("0"))        # True  — also non-empty
print(bool(0))          # False
print(bool([]))         # False

bool("False") being True catches people reading configuration files, where everything arrives as text. "False" is nine characters of non-empty string, so it is truthy. Converting text to a boolean needs an explicit comparison:

setting = "False"
enabled = setting.lower() == "true"
print(enabled)    # False

A complete small program

Everything from this module, working together:

name = input("Your name: ").strip()
price = float(input("Item price: "))
quantity = int(input("How many? "))

TAX_RATE = 0.18

subtotal = price * quantity
tax = subtotal * TAX_RATE
total = subtotal + tax

print(f"\nThank you, {name.title()}")
print(f"Subtotal: {subtotal:>10,.2f}")
print(f"Tax (18%): {tax:>9,.2f}")
print(f"Total:     {total:>9,.2f}")
Your name:  priya
Item price: 249.50
How many? 3

Thank you, Priya
Subtotal:     748.50
Tax (18%):    134.73
Total:        883.23

Worth noticing: .strip() on the name because users type spaces, .title() to tidy the capitalisation, TAX_RATE in capitals to signal a constant, float for price and int for quantity, and f-string alignment so the numbers line up.

It also has a flaw you now know about: it uses floats for money. For a shop receipt that is acceptable; for an accounting system it is not.

And it crashes if the user types "abc" for the price. Handling that properly needs try/except — module 6.

Practice

  1. Write a program asking for two numbers and printing their sum. Get it wrong first — without int() — and see 23 instead of 5. Then fix it.
  2. Ask the user for their birth year and print their approximate age.
  3. Predict, then check: int("7"), int(7.9), int("7.9"), float("7"), str(7) + "7", int("") . Two of those raise errors — know which before you run them.
  4. Write a converter: ask for a temperature in Celsius, print it in Fahrenheit to one decimal place using an f-string. The formula is f = c * 9 / 5 + 32.
  5. Extend the receipt program above to ask for a discount percentage and apply it before tax.
  6. Using isdigit(), make the quantity input refuse anything that is not a whole number, printing a clear message instead of crashing.

That is module two. You can now store values, do arithmetic without being caught by floats, format text properly, and move between types deliberately rather than by accident.

Next module: control flow — making the program decide and repeat, which is where it stops being a calculator and starts being a program.

Stuck on this lesson?

Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.

About the internship