You wrote a short program that asks for your birth year and works out your age. You type 2002, press Enter, and Python stops with this:
Traceback (most recent call last):
File "main.py", line 3, in <module>
age = 2026 - year
~~~~~^~~~~~
TypeError: unsupported operand type(s) for -: 'int' and 'str'This is one of the most common errors in a first Python program. The fix is one word, but it's worth understanding why it happens, because the same idea comes back again and again.
Here is the program:
name = input("Your name? ")
year = input("Born in? ")
age = 2026 - year
print("Hi", name, "- you are", age)What the error means
Read the last line of the error from the left:
TypeError: the problem is the type of a value, not its spelling.unsupported operand type(s) for -: the minus sign got values it can't work with.'int' and 'str': the value on the left is anint(a whole number,2026) and the value on the right is astr(a string, which means text).
Python can subtract a number from a number. It can't subtract text from a number, and it doesn't guess that the text "2002" was meant as a number.
The lines above the last one tell you where it happened: line 3 of main.py. The ^ mark points at the minus sign. (Python 3.11 and newer draw that mark; older versions only show the line.)
Why year is text
input() always gives back a string, even when you type only digits. You can check it yourself with type():
year = input("Born in? ")
print(type(year))Born in? 2002
<class 'str'>So year holds the text "2002", not the number 2002. To Python those are as different as the word "five" and the number 5.
The fix: turn the text into a number
Wrap the input() in int():
name = input("Your name? ")
year = int(input("Born in? "))
age = 2026 - year
print("Hi", name, "- you are", age)Your name? Lena
Born in? 2002
Hi Lena - you are 24Read the new line from the inside out: input() asks the question and gives back text, then int() turns that text into a whole number. Now both sides of the minus sign are numbers.
For numbers with a decimal point, like a height of 1.75, use float() instead of int().
The same error with other operators, and the other order
The two types in the message are in the same order as in your code: the value left of the operator first, then the value right of it. So if the text is on the left, the message turns round:
year = "2002"
next_birthday = year - 1TypeError: unsupported operand type(s) for -: 'str' and 'int'The symbol after for tells you which operator failed. With text on the left, you'll see the same message for division and floor division, and a slightly longer one for powers:
TypeError: unsupported operand type(s) for /: 'str' and 'int'
TypeError: unsupported operand type(s) for //: 'str' and 'int'
TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'int'And with a number on the left of a +, like 2026 + year, it's for +: 'int' and 'str'. You get the same message from sum() on a list of strings, such as sum(["72", "85"]), because sum adds the items up one by one, starting from the number 0.
The fix is the same every time: convert the text to a number before you calculate, with int() or float().
Three operators behave differently, so watch out for them:
year + 1with text on the left givescan only concatenate str (not "int") to str(see below).year % 2gives the puzzlingTypeError: not all arguments converted during string formatting, because%after a string means "fill in this text", not "remainder".year * 2gives no error at all: it prints20022002. Multiplying text by a whole number repeats the text. (Two strings, like"5" * "3", do fail:can't multiply sequence by non-int of type 'str'.)
If the message says 'NoneType' instead of 'str', the value isn't text but nothing: often a function that prints its result instead of returning it.
Two errors you may meet next
can only concatenate str (not "int") to str
This is the same problem the other way round. + between two strings joins them, but here one side is a number:
print("Born in " + 2002)TypeError: can only concatenate str (not "int") to strEither let print() put the pieces together with commas, print("Born in", 2002), or turn the number into text first with str(2002).
ValueError: invalid literal for int() with base 10
int() only works when the text really is a whole number. If someone types a word, the conversion fails:
Your name? Lena
Born in? nineteen
Traceback (most recent call last):
File "main.py", line 2, in <module>
year = int(input("Born in? "))
^^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 10: 'nineteen'This one isn't a mistake in your code: it's input your program didn't expect. Handling it with try and except is the topic of Error Handling in Python Course 3.
How to read any TypeError
- Find the line number in the traceback, and the
^mark under the line. - Look at the operator or function it points to:
-,+,len()and so on. - Read the two types the message names. If you're not sure which value is which, print
type()of each. - Convert one side so the types match:
int(),float()orstr().
