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

  1. Convert to int at the call site: perfect(int(number)) when the value is known to be integral.
  2. Parse user input explicitly (int(input().strip()) inside try/except ValueError) instead of passing raw strings.
  3. 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

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


AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14). Data as JSON: /api/errors/8c376aa5181fee12. Report an issue: GitHub.