TheAlgorithms/Python · error · ValueError

num_people or step_size is not a positive integer.

Error message

num_people or step_size is not a positive integer.

What it means

Raised by josephus_recursive in maths/josephus_problem.py when num_people or step_size is not an int, or either is <= 0. The Josephus recurrence (winner of n people = (winner of n-1 + step) % n) requires at least one person and a positive step; the combined guard rejects floats, strings, zero, and negatives with ValueError before recursion starts.

Source

Thrown at maths/josephus_problem.py:72

        Traceback (most recent call last):
            ...
        ValueError: num_people or step_size is not a positive integer.
        >>> josephus_recursive(1_000, 0.01)
        Traceback (most recent call last):
            ...
        ValueError: num_people or step_size is not a positive integer.
        >>> josephus_recursive("cat", "dog")
        Traceback (most recent call last):
            ...
        ValueError: num_people or step_size is not a positive integer.
    """
    if (
        not isinstance(num_people, int)
        or not isinstance(step_size, int)
        or num_people <= 0
        or step_size <= 0
    ):
        raise ValueError("num_people or step_size is not a positive integer.")

    if num_people == 1:
        return 0

    return (josephus_recursive(num_people - 1, step_size) + step_size) % num_people


def find_winner(num_people: int, step_size: int) -> int:
    """
    Find the winner of the Josephus problem for num_people and a step_size.

    Args:
        num_people (int): Number of people.
        step_size (int): Step size for elimination.

    Returns:
        int: The position of the last person remaining (1-based index).

View on GitHub (pinned to f5988cc097)

Solutions

  1. Validate both parameters as positive ints before calling: int(n) >= 1 and int(k) >= 1.
  2. Guard against empty groups: if not people: skip instead of calling with 0.
  3. Coerce numeric config values (e.g. int(step_cfg)) at load time so the hot path always sees ints.

Example fix

// before
winner = josephus_recursive(num_people, step_size)  # raw config values

// after
num_people, step_size = int(num_people), int(step_size)
if num_people < 1 or step_size < 1:
    raise ValueError(f"need positive ints, got {num_people=}, {step_size=}")
winner = josephus_recursive(num_people, step_size)
Defensive patterns

Strategy: validation

Validate before calling

num_people, step_size = int(num_people), int(step_size)
if num_people < 1 or step_size < 1:
    raise ValueError("num_people and step_size must be positive integers")
w = josephus_recursive(num_people, step_size)

Type guard

def valid_josephus_args(n, k) -> bool:
    return (
        isinstance(n, int) and isinstance(k, int)
        and not isinstance(n, bool) and not isinstance(k, bool)
        and n > 0 and k > 0
    )

Try / catch

try:
    w = josephus_recursive(n, k)
except ValueError:
    n, k = int(n), int(k)
    w = josephus_recursive(n, k)

Prevention

When it happens

Trigger: Calling josephus_recursive(0, 3), josephus_recursive(5, 0), josephus_recursive(-2, 3), josephus_recursive(5.0, 2), or josephus_recursive('cat', 'dog'). Any one invalid argument triggers the raise.

Common situations: Simulation parameters read as strings from config/CLI; step_size defaulting to 0 or None; counts computed as floats from averaging logic; passing num_people from len() of an empty collection (0).

Related errors


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