TheAlgorithms/Python · error · ValueError
Number should not be negative.
Error message
Number should not be negative.
What it means
Raised by factorial(num) when num < 0. Factorial is undefined for negative integers, and this recursive implementation (num * factorial(num - 1)) would recurse forever downward without the guard. The ValueError is the first thing checked on every recursive call.
Source
Thrown at dynamic_programming/factorial.py:19
# Factorial of a number using memoization
from functools import lru_cache
@lru_cache
def factorial(num: int) -> int:
"""
>>> factorial(7)
5040
>>> factorial(-1)
Traceback (most recent call last):
...
ValueError: Number should not be negative.
>>> [factorial(i) for i in range(10)]
[1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880]
"""
if num < 0:
raise ValueError("Number should not be negative.")
return 1 if num in (0, 1) else num * factorial(num - 1)
if __name__ == "__main__":
import doctest
doctest.testmod()
View on GitHub (pinned to f5988cc097)
Solutions
- Validate the argument at the boundary: if num < 0: raise/handle before calling factorial.
- Fix the caller's arithmetic (e.g. clamp k to 0 <= k <= n before computing factorials of differences).
- For large n, note this recursive version hits Python's recursion limit near n ~ 1000 — prefer math.factorial in production.
Example fix
# before result = factorial(n - k) # negative when k > n # after k = min(k, n) result = factorial(n - k)
Defensive patterns
Strategy: validation
Validate before calling
if not isinstance(num, int) or num < 0:
raise ValueError('num must be a non-negative integer')
result = factorial(num) Type guard
def is_non_negative_int(value: object) -> bool:
return isinstance(value, int) and not isinstance(value, bool) and value >= 0 Try / catch
try:
result = factorial(num)
except ValueError:
raise ValueError(f'factorial undefined for {num!r}; check upstream arithmetic') from None Prevention
- Validate sign at input boundaries rather than relying on deep library checks.
- In combinatorics code, clamp subtraction results (n - k) before taking factorials.
- Prefer math.factorial in production; this recursive version also risks recursion limits.
When it happens
Trigger: factorial(-1), factorial(-100), or any call chain where a computed argument becomes negative (e.g. factorial(n) with n from unvalidated input, or downstream arithmetic like factorial(x - y) with y > x).
Common situations: User input or file-parsed integers not validated for sign; combinatorics formulas that subtract in the wrong order (k > n in n-choose-k); passing a float like -3.0 also triggers it.
Related errors
- Both arguments MUST be non-negative!
- Limit for the Catalan sequence must be ≥ 0
- Negative arguments are not supported
- the value of input must be a natural number
- surface_area_cube() only accepts non-negative values
AI-assisted analysis of TheAlgorithms/Python@f5988cc097 (2026-08-14).
Data as JSON: /api/errors/23bde96292a6405b.
Report an issue: GitHub.