TheAlgorithms/Python · error · ValueError

gon_side must be in the range [3, 5]

Error message

gon_side must be in the range [3, 5]

What it means

Raised by solution() in project_euler/problem_068/sol1.py when gon_side is outside [3, 5]. The magic gon ring generator only handles 3-gon, 4-gon, and 5-gon rings because the digit-concatenation scheme and permutation search are sized for those; gon_side 6 or more would need numbers with two digits on the inner ring and explodes combinatorially.

Source

Thrown at project_euler/problem_068/sol1.py:64

def solution(gon_side: int = 5) -> int:
    """
    Find the maximum number for a "magic" gon_side-gon ring

    The gon_side parameter should be in the range [3, 5],
    other side numbers aren't tested

    >>> solution(3)
    432621513
    >>> solution(4)
    426561813732
    >>> solution()
    6531031914842725
    >>> solution(6)
    Traceback (most recent call last):
    ValueError: gon_side must be in the range [3, 5]
    """
    if gon_side < 3 or gon_side > 5:
        raise ValueError("gon_side must be in the range [3, 5]")

    # Since it's 16, we know 10 is on the outer ring
    # Put the big numbers at the end so that they are never the first number
    small_numbers = list(range(gon_side + 1, 0, -1))
    big_numbers = list(range(gon_side + 2, gon_side * 2 + 1))

    for perm in permutations(small_numbers + big_numbers):
        numbers = generate_gon_ring(gon_side, list(perm))
        if is_magic_gon(numbers):
            return int("".join(str(n) for n in numbers))

    msg = f"Magic {gon_side}-gon ring is impossible"
    raise ValueError(msg)


def generate_gon_ring(gon_side: int, perm: list[int]) -> list[int]:
    """
    Generate a gon_side-gon ring from a permutation state

View on GitHub (pinned to f5988cc097)

Solutions

  1. Call only with 3, 4, or 5 (or no argument for the default 5).
  2. Clamp or reject user input first: if not 3 <= gon_side <= 5: raise/reject in your wrapper.
  3. If you need larger rings, write a dedicated generator; do not widen this guard.

Example fix

# before
for gon_side in range(2, 8):
    print(solution(gon_side))  # ValueError at 2 and again at 6

# after
for gon_side in (3, 4, 5):
    print(solution(gon_side))
Defensive patterns

Strategy: validation

Validate before calling

if not (isinstance(gon_side, int) and 3 <= gon_side <= 5):
    raise ValueError(f"gon_side must be in [3, 5], got {gon_side!r}")
solution(gon_side)

Type guard

def is_supported_gon_side(value) -> bool:
    return isinstance(value, int) and 3 <= value <= 5

Try / catch

try:
    result = solution(gon_side)
except ValueError as e:
    if "range [3, 5]" in str(e):
        logger.error("unsupported gon_side %s; use 3-5", gon_side)
    else:
        raise

Prevention

When it happens

Trigger: solution(2), solution(6), solution(10). Any loop over range(1, 11) that calls solution(gon_side) will raise for gon_side in {1, 2, 6, 7, 8, 9, 10}.

Common situations: Generalizing a parameter sweep beyond the supported domain; user-facing wrappers that expose gon_side without a range check; copying the pattern to 'support' 6-gon rings without rewriting the generator.

Related errors


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