How to Fix: TypeError: unsupported operand type(s) for -: ‘str’ and ‘int’

3D illustration of a minus sign failing to subtract a number from an apple, representing the string minus integer error TypeError unsupported operand.

This TypeError is the cousin of TypeError: unsupported operand type(s) for +. It means: “You tried to use a math operator (like -, *, /) on data types that don’t support it.”

You cannot subtract a number from a word.

โšก Quick Fix: TypeError: unsupported operand type(s) for -: ‘str’ and ‘int’ โ€” Python int() and float() Conversion Fix for input() Math with -, *, /, and ** Operators

You applied a math operator between a string and a number โ€” -, *, /, and ** have no defined behaviour between these types and Python stops immediately.

# WRONG โ€” input() returns "10" as a string, subtraction needs an integer
total_score = 100
penalty = input("Enter penalty: ")   # user types 10 โ€” penalty is "10"
final = total_score - penalty        # TypeError: unsupported operand type(s) for -: 'int' and 'str'

# WRONG โ€” same error fires on *, /, ** between mismatched types
price = "25.99"
discount = 5
sale_price = price - discount        # TypeError: unsupported operand type(s) for -: 'str' and 'int'

# RIGHT โ€” convert at the point of assignment, before math runs
penalty = int(input("Enter penalty: "))
final = total_score - penalty        # works โ€” both are integers

# RIGHT โ€” float() for decimal strings
price = float("25.99")
sale_price = price - discount        # works โ€” both are numbers

# RIGHT โ€” production pattern: wrap conversion in try/except
try:
    penalty = int(input("Enter penalty: "))
    final = total_score - penalty
    print(f"Final score: {final}")
except ValueError:
    print("Enter a whole number.")

The two causes below cover the input() source and the string-from-data-source pattern โ€” the exact points where the type mismatch enters your code.

The Cause

The most common cause is, again, input(). The input() function always gives you a string. Problem Code:

total_score = 100
penalty_str = input("Enter penalty points: ") # User types '10'

# 'total_score' is an INT (100)
# 'penalty_str' is a STR ("10")
final_score = total_score - penalty_str 
# CRASH! TypeError: unsupported operand type(s) for -: 'int' and 'str'

The Fix: Convert Your Types

You must make sure all your variables are the same, numeric type before you do math. Use int() or float() to convert the string.

total_score = 100
penalty_str = input("Enter penalty points: ")

try:
    # THE FIX: Convert the string "10" to the number 10
    penalty_int = int(penalty_str)
    
    final_score = total_score - penalty_int
    print(f"Final score: {final_score}")

except ValueError:
    print("That was not a valid number!")

This applies to all math operators: * (multiplication), / (division), and ** (exponent).


TypeError: unsupported operand type(s) for -: ‘str’ and ‘int’ โ€” The Type Contract Every Math Operator Enforces

TypeError: unsupported operand type(s) for -: ‘str’ and ‘int’ fires on -, *, /, //, %, and ** equally. Every math operator in Python requires both operands to be numeric. No operator silently converts a string โ€” Python never guesses your intent.

The + operator is the one exception that confuses this issue. “10” + 5 fires TypeError because + between str and int is ambiguous. But “10” + “5” produces “105” because string + string does concatenation. This asymmetry is why type-checking at the assignment point matters more than checking at the operator.

Two sources deliver strings where math expects numbers.

input() โ€” unconditionally. Wrap every input() that feeds math with int() or float() at the exact line where the value enters your code. Never let a raw input() result reach a -, *, /, or ** operator.

External data. CSV files, JSON APIs, database results, and environment variables all return strings by default. A column named “price” with value “25.99” is the string “25.99” until you call float(). Convert at the load step โ€” not at the calculation step three functions later when the crash is harder to trace.

The one pattern that handles both sources and both int and float inputs cleanly:

def to_number(value: str) -> float:
try:
return float(value)
except (ValueError, TypeError):
return 0.0 # or raise, or return None โ€” choose based on your pipeline

Apply to_number() to any value coming from input(), a CSV cell, or a JSON field before it touches a math operator. One function, every source covered, no TypeError at runtime.

Similar Posts

Leave a Reply