WasiLearn Code
Python · Getting started

Types, and converting between them

Python knows the difference between the number 5 and the text "5". They look identical printed on a screen and they behave nothing alike, and almost every confusing early error comes from one being where the other was expected.

print(5 + 5)
print("5" + "5")
output
10
55

Same operator, same-looking values, two completely different jobs. Between numbers + adds; between strings it joins.

The four types you start with

print(type(7))
print(type(7.5))
print(type("seven"))
print(type(True))
output
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>

int is a whole number. float is a number with a decimal point. str is text. bool is True or False — capitalised, unlike most languages, and a common source of typos.

type() is the tool for finding out what you actually have, and it is the first thing to reach for when a value is not behaving.

int and float are not interchangeable

print(7 / 2)
print(7 // 2)
print(7 % 2)
print(type(6 / 2))
output
3.5
3
1
<class 'float'>

/ always produces a float, even when the answer is whole — 6 / 2 gives 3.0, not 3. // is floor division, which divides and throws away the remainder. % gives that remainder.

That last line catches people. If a program needs a whole number — a row index, a count of pages — / will hand it a float and something downstream will object. // or int() is what you want.

Converting on purpose

Each type name doubles as a conversion function.

print(int("42"))
print(float("42"))
print(str(42))
print(int(7.9))
print(float(7))
output
42
42.0
42
7
7.0

int(7.9) gives 7, not 8. It truncates — chops the decimal off — rather than rounding. When you want rounding, say so with round():

print(int(7.9))
print(round(7.9))
print(round(7.4))
print(round(2.5))
print(round(3.5))
output
7
8
7
2
4

Those last two are not a mistake. Python uses banker's rounding: an exact half goes to the nearest even number. It exists so that rounding a long column of figures does not drift upwards, and it surprises everyone once.

Conversion that fails, loudly

print(int("42"))
print(int("forty two"))

Nothing is printed for the second line, because the program stops:

ValueError: invalid literal for int() with base 10: 'forty two'

This is Python being helpful. JavaScript would hand back a quiet NaN that poisons every later calculation; Python refuses at the point of the mistake and tells you the exact string it could not read. A crash on line 2 is much cheaper to fix than nonsense on a receipt.

int("42.5") fails too, for the same reason — "42.5" is not a whole number. Convert to float first if that is what you meant.

input() always gives you a string

This is the one that catches every beginner, and it catches them the same way.

age = "16"
print(type(age))
print(age + 1)

That last line stops the program:

TypeError: can only concatenate str (not "int") to str

input() returns a string. Always. Even when the person typed digits and nothing else. So this — which looks completely reasonable — does not work:

age = input("Your age: ")
next_year = age + 1        # TypeError

The fix is to convert as the value arrives, not later:

age = int(input("Your age: "))
next_year = age + 1        # fine

Doing it on the same line means every use afterwards is already a number. Getting input in a browser works a little differently on this site, which the input lesson covers.

Notice also that Python raised a TypeError rather than guessing. That is the deliberate difference from JavaScript, where "16" + 1 silently produces "161".

Truthiness

Any value can be used where Python expects a condition. The values that count as false are few:

print(bool(0))
print(bool(""))
print(bool([]))
print(bool(None))
print(bool("0"))
print(bool(-1))
print(bool(" "))
output
False
False
False
False
True
True
True

Zero, the empty string, the empty list and None are falsy. Everything else is truthy, including the string "0" and a string containing only a space.

The practical warning is the same one every language has: if count: asks whether count is truthy, not whether it exists. A genuine count of zero takes the else branch, which is almost never what you meant. Use if count is not None: when zero is real data.

None is not zero and not empty

nothing = None

print(nothing)
print(type(nothing))
print(nothing is None)
output
None
<class 'NoneType'>
True

None means "no value here". It is Python's single answer to the question JavaScript splits between null and undefined.

Compare it with is, not ==. is None is the idiom, it reads well, and it cannot be fooled by a class that has redefined equality.

Mixing types

Python allows arithmetic between int and float, quietly widening to float:

print(3 + 0.5)
print(type(3 + 0.5))
print(True + 1)
output
3.5
<class 'float'>
2

That last line is real: bool is a subclass of int, with True equal to 1. It means sum([True, False, True]) counts how many are true, which is occasionally useful and mostly a curiosity.

What Python will not do is mix strings with numbers:

print("Total: " + str(450))
output
Total: 450

The str() is required. Leave it out and you get a TypeError — which is why f-strings, which convert automatically, are the better habit:

total = 450
print(f"Total: {total}")
output
Total: 450

The rule worth carrying

Convert at the boundary. The moment a value arrives from outside your program — from input(), from a file, from a web form — turn it into the type you actually mean, on that line. Everything after it then works with real numbers and real text, and type() is there for the times it still does not.

Next: comments and readable code.

Prefer learning with a teacher?

WasiLearn Academy runs small-group classes covering this material, online and in Karachi.

See the classes