Python Type Conversion: Why "5" + 5 Fails and How to Fix It
Python refuses to guess whether "5" + 5 means 55 or 10. Convert with int(), float() and str() where values come in, handle text that won't convert, and avoid the bool("False") trap.
"5" + 5 fails because Python refuses to guess. One side is text, the other is a number, and Python won't decide for you whether you meant "55" or 10. That's not Python being difficult. It's Python protecting you from a wrong answer that looks right.
Skip ahead: If you only need the fix, it's int("5") + 5 for numbers and "5" + str(5) for text. Read "When conversion fails" before you use int() on anything a person typed.
The error
age = "5"
print(age + 5)
Traceback (most recent call last):
File "/home/you/project/fail.py", line 2, in <module>
print(age + 5)
~~~~^~~
TypeError: can only concatenate str (not "int") to str
Read the last line. can only concatenate str (not "int") to str means: the left side is text, so + means "join text", and you gave it a number. Python could turn the 5 into "5" and give you "55". It could turn "5" into 5 and give you 10. Both are possible, so it does neither.
Some languages do guess. JavaScript gives you "55". I think Python's choice is better. A crash on line 2 is easier to fix than a wrong total discovered next month.
Where the text comes from
You rarely write "5" yourself. Text that looks like a number comes from:
input(), which always returns text, even when the person types digits- files, including CSV files, where every value is text
- command-line arguments in
sys.argv - web forms and many APIs
So the real rule is: anything that came from outside your program is text until you convert it.
The conversion functions
print(int("42") + 1)
print(float("3.5") * 2)
print(str(42) + " items")
print(int(7.9))
print(round(7.9))
print(int(" 42\n"))
43
7.0
42 items
7
8
42
Three things to notice:
- **
int()andfloat()turn text into numbers.**str()turns anything into text. - **
int(7.9)is 7, not 8.**int()cuts off the decimal part. It doesn't round. If you want rounding, useround(). - Spaces and a newline at the ends are fine.
int()strips them, which helps with values read from files, where each line ends with\n.
💡 Tip: If you only want to print text and a number together, don't convert at all. Use an f-string: print(f"You are {age} years old"). It handles any type.
When conversion fails
int() only accepts text that really is a whole number:
for text in ["42", "4.5", "4,500", "", "five"]:
try:
print(repr(text), "->", int(text))
except ValueError as error:
print(repr(text), "-> ValueError:", error)
'42' -> 42
'4.5' -> ValueError: invalid literal for int() with base 10: '4.5'
'4,500' -> ValueError: invalid literal for int() with base 10: '4,500'
'' -> ValueError: invalid literal for int() with base 10: ''
'five' -> ValueError: invalid literal for int() with base 10: 'five'
"4.5" fails because it's not a whole number. If decimals are allowed, use float(). "4,500" fails because of the comma. Remove it first with .replace(",", ""). And "" fails, which is exactly what you get when someone presses Enter without typing anything.
âš Warning: Never call int(input(...)) on input from a real person without a plan for the ValueError. One empty Enter crashes the whole program. Catch it with try/except ValueError and ask again. The while loop tutorial shows how.
The other trap: bool("False")
This one gives no error at all, which makes it worse:
print(bool("False"))
print(bool(""))
print(bool(0))
True
False
False
bool() doesn't read the word. Any non-empty text is True, including "False" and "0". If you read yes/no or True/False from a file or a person, compare the text instead:
answer = "False"
is_active = answer.strip().lower() in ("true", "yes", "1")
print(is_active)
False
Checking the type when you're not sure
If a value behaves strangely, ask Python what it is:
price = "95.00"
print(type(price))
print(type(float(price)))
<class 'str'>
<class 'float'>
type() is the quickest way to stop guessing. If it says str and you expected a number, you found the bug.
Common mistakes
- Converting too late. Convert once, right where the value comes in. Not in five different places later.
- **Using
int()to round.** It cuts. Useround(). - **Using
float()for money and expecting exact cents.** It's fine for practice. For real money totals, look up thedecimalmodule. - **Trusting
bool()on text.** Compare the text instead.
What happens if you skip it
If you're lucky, you get the TypeError and fix it in a minute. If you're unlucky, the text never gets added to a number. It gets compared or sorted instead, and "10" < "9" is True because text sorts letter by letter. No crash. Just a wrong order nobody notices.
If a CSV file gives you "10", "9" and "100", and you sort them without converting, which one comes first?
About
Why text and numbers don't mix, how int(), float() and str() behave, what to do when conversion fails, and why bool("False") is True. After this, you can convert input safely instead of hoping it's a number.
- Responsible
- John G
- Last Update
- 09/22/2026
- Reading Time
- 5 min
Reviews
Sign in to write a reviewComments (0)
Sign in to commentNo comments yet.