TheAlgorithms/Python · error · ValueError

the value of input must be a natural number

Error message

the value of input must be a natural number

What it means

Raised by minimum_squares_to_represent_a_number(number) when number != int(number), i.e. the value has a fractional part. The algorithm allocates an answers array indexed 0..number and iterates with integer indices, so non-integral inputs are rejected before anything runs. Note the type is not checked — 12.0 passes because 12.0 == int(12.0); this check happens before the negativity check.

Source

Thrown at dynamic_programming/minimum_squares_to_represent_a_number.py:29

    >>> minimum_squares_to_represent_a_number(37)
    2
    >>> minimum_squares_to_represent_a_number(21)
    3
    >>> minimum_squares_to_represent_a_number(58)
    2
    >>> minimum_squares_to_represent_a_number(-1)
    Traceback (most recent call last):
        ...
    ValueError: the value of input must not be a negative number
    >>> minimum_squares_to_represent_a_number(0)
    1
    >>> minimum_squares_to_represent_a_number(12.34)
    Traceback (most recent call last):
        ...
    ValueError: the value of input must be a natural number
    """
    if number != int(number):
        raise ValueError("the value of input must be a natural number")
    if number < 0:
        raise ValueError("the value of input must not be a negative number")
    if number == 0:
        return 1
    answers = [-1] * (number + 1)
    answers[0] = 0
    for i in range(1, number + 1):
        answer = sys.maxsize
        root = int(math.sqrt(i))
        for j in range(1, root + 1):
            current_answer = 1 + answers[i - (j**2)]
            answer = min(answer, current_answer)
        answers[i] = answer
    return answers[number]


if __name__ == "__main__":
    import doctest

View on GitHub (pinned to f5988cc097)

Solutions

  1. Round or validate first: minimum_squares_to_represent_a_number(int(number)) if truncation is intended, or reject non-integral values upstream.
  2. Use round(number) when the value should be integral but accumulated float error.
  3. Validate at input boundaries with number.is_integer() for floats.

Example fix

# before
count = minimum_squares_to_represent_a_number(value)  # value = 12.34 -> ValueError

# after
if not float(value).is_integer():
    raise ValueError(f'expected integer, got {value}')
count = minimum_squares_to_represent_a_number(int(value))
Defensive patterns

Strategy: validation

Validate before calling

if float(number).is_integer():
    count = minimum_squares_to_represent_a_number(int(number))
else:
    raise ValueError(f'{number!r} is not a natural number')

Type guard

def is_natural_number(value: object) -> bool:
    return isinstance(value, (int, float)) and not isinstance(value, bool) and float(value).is_integer() and value >= 0

Try / catch

try:
    count = minimum_squares_to_represent_a_number(number)
except ValueError as exc:
    if 'natural number' in str(exc):
        raise ValueError(f'round or reject {number!r} before calling') from exc
    raise

Prevention

When it happens

Trigger: minimum_squares_to_represent_a_number(12.34) as in the doctest; any float with a fractional part; Decimal or Fraction values whose numeric comparison with int(number) fails. NaN also raises here since nan != int(nan) comparison is False.

Common situations: Math results (averages, sqrt outputs) passed without rounding; user input parsed as float from CLI or web forms; currency/measurements with decimal precision.

Related errors


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