TheAlgorithms/Python · error · ValueError
number must be an integer
Error message
number must be an integer
What it means
perfect() in maths/perfect_number.py decides whether a number equals the sum of its proper divisors (sum(i for i in range(1, number // 2 + 1) ...) == number). It guards its input with isinstance(number, int) and raises ValueError when the argument is not a Python int, because the divisor-sum loop and number % i comparisons assume exact integer arithmetic. Note the exception type is ValueError, not TypeError, even though it is a type problem — matching the doctest contract of the module.
Source
Thrown at maths/perfect_number.py:69
>>> perfect(33550337) # Just above a large perfect number
False
>>> perfect(1) # Edge case: 1 is not a perfect number
False
>>> perfect("123") # String representation of a number
Traceback (most recent call last):
...
ValueError: number must be an integer
>>> perfect(12.34)
Traceback (most recent call last):
...
ValueError: number must be an integer
>>> perfect("Hello")
Traceback (most recent call last):
...
ValueError: number must be an integer
"""
if not isinstance(number, int):
raise ValueError("number must be an integer")
if number <= 0:
return False
return sum(i for i in range(1, number // 2 + 1) if number % i == 0) == number
if __name__ == "__main__":
from doctest import testmod
testmod()
print("Program to check whether a number is a Perfect number or not...")
try:
number = int(input("Enter a positive integer: ").strip())
except ValueError:
msg = "number must be an integer"
raise ValueError(msg)
print(f"{number} is {'' if perfect(number) else 'not '}a Perfect Number.")
View on GitHub (pinned to f5988cc097)
Solutions
- Convert to int at the call site: perfect(int(number)) when the value is known to be integral.
- Parse user input explicitly (int(input().strip()) inside try/except ValueError) instead of passing raw strings.
- If you wrap calls in error handling, catch ValueError (not TypeError) — that is what this function raises.
Example fix
# before perfect(user_value) # ValueError if user_value is 6.0 or '6' # after perfect(int(user_value))
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(number, int):
number = int(number) # only after confirming it is numeric
result = perfect(number) Type guard
def is_int_like(v) -> bool:
return isinstance(v, int) or (isinstance(v, str) and v.lstrip('-').isdigit()) Try / catch
try:
perfect(n)
except ValueError as exc:
if 'integer' in str(exc):
n = int(float(n)) # or reject
else:
raise Prevention
- Catch ValueError, not TypeError — this module raises ValueError for type problems.
- Centralize int() conversion where data enters your program.
- Check the function's doctest block for the exact error contract.
When it happens
Trigger: Calling perfect(12.34), perfect('Hello'), perfect(6.0), or passing an unconverted value from input()/file parsing directly to perfect().
Common situations: Reading a number from a config file or API payload and passing it through without int() conversion; wrapping the function in generic code that catches TypeError but not ValueError, so the guard slips through.
Related errors
- multiplicative_persistence() only accepts integral values
- multiplicative_persistence() does not accept negative values
- additive_persistence() only accepts integral values
- additive_persistence() does not accept negative values
- is_prime() only accepts positive integers
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/8c376aa5181fee12.
Report an issue: GitHub.