TheAlgorithms/Python · error · ValueError
multiplicative_persistence() only accepts integral values
Error message
multiplicative_persistence() only accepts integral values
What it means
multiplicative_persistence() in maths/persistence.py counts how many times you must multiply a number's digits together until one digit remains. It first requires the argument to be a Python int (isinstance(num, int)); anything else — strings, floats — raises ValueError('multiplicative_persistence() only accepts integral values'). The check runs before the negativity check, so a non-int negative-looking input hits this error first. The string-based digit loop (str(num), int(i)) is why non-integral types are rejected.
Source
Thrown at maths/persistence.py:20
"""
Return the persistence of a given number.
https://en.wikipedia.org/wiki/Persistence_of_a_number
>>> multiplicative_persistence(217)
2
>>> multiplicative_persistence(-1)
Traceback (most recent call last):
...
ValueError: multiplicative_persistence() does not accept negative values
>>> multiplicative_persistence("long number")
Traceback (most recent call last):
...
ValueError: multiplicative_persistence() only accepts integral values
"""
if not isinstance(num, int):
raise ValueError("multiplicative_persistence() only accepts integral values")
if num < 0:
raise ValueError("multiplicative_persistence() does not accept negative values")
steps = 0
num_string = str(num)
while len(num_string) != 1:
numbers = [int(i) for i in num_string]
total = 1
for i in range(len(numbers)):
total *= numbers[i]
num_string = str(total)
steps += 1
return steps
View on GitHub (pinned to f5988cc097)
Solutions
- Convert the argument with int() before calling: multiplicative_persistence(int(num)).
- Validate/parse external data at the system boundary rather than relying on the function's guard.
- Remember it raises ValueError (not TypeError) — catch accordingly.
Example fix
# before multiplicative_persistence(user_input) # ValueError for '7788' # after multiplicative_persistence(int(user_input))
Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(num, int):
raise ValueError(f'persistence needs int, got {type(num).__name__}')
multiplicative_persistence(num) Type guard
def is_persistence_input(v) -> bool:
return isinstance(v, int) and not isinstance(v, bool) Try / catch
try:
multiplicative_persistence(num)
except ValueError as exc:
if 'integral values' in str(exc):
num = int(num)
else:
raise Prevention
- Apply int() immediately after input()/deserialization.
- Keep persistence math on ints end-to-end; avoid / division upstream.
- Note the type guard fires before the negativity guard — order matters.
When it happens
Trigger: Calling multiplicative_persistence('long number'), multiplicative_persistence(77.0), or passing an unparsed value from input()/JSON. Note the type check precedes the sign check, so multiplicative_persistence(-0.5) raises this, not the negative-values error.
Common situations: Chaining the function directly after input() or a web-form field without int() conversion; tests written with string literals ('39') copied from documentation examples.
Related errors
- number must be an integer
- 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/0b93392053ac17c7.
Report an issue: GitHub.