TheAlgorithms/Python · error · ValueError

Second rotor position is not within range of 1..26 ({rotorpo

Error message

Second rotor position is not within range of 1..26 ({rotorpos2}

What it means

Raised by the Enigma machine validator when the SECOND rotor position is outside 1..26. Same 1-based rule as the other rotors; the message f-string also misses its closing parenthesis (cosmetic bug).

Source

Thrown at ciphers/enigma_machine2.py:103

    :param rotpos: rotor_positon
    :param rotsel: rotor_selection
    :param pb: plugb -> validated and transformed
    :return: (`rotpos`, `rotsel`, `pb`)
    """
    # Checks if there are 3 unique rotors

    if (unique_rotsel := len(set(rotsel))) < 3:
        msg = f"Please use 3 unique rotors (not {unique_rotsel})"
        raise Exception(msg)

    # Checks if rotor positions are valid
    rotorpos1, rotorpos2, rotorpos3 = rotpos
    if not 0 < rotorpos1 <= len(abc):
        msg = f"First rotor position is not within range of 1..26 ({rotorpos1}"
        raise ValueError(msg)
    if not 0 < rotorpos2 <= len(abc):
        msg = f"Second rotor position is not within range of 1..26 ({rotorpos2})"
        raise ValueError(msg)
    if not 0 < rotorpos3 <= len(abc):
        msg = f"Third rotor position is not within range of 1..26 ({rotorpos3})"
        raise ValueError(msg)

    # Validates string and returns dict
    pbdict = _plugboard(pb)

    return rotpos, rotsel, pbdict


def _plugboard(pbstring: str) -> dict[str, str]:
    """
    https://en.wikipedia.org/wiki/Enigma_machine#Plugboard

    >>> _plugboard('PICTURES')
    {'P': 'I', 'I': 'P', 'C': 'T', 'T': 'C', 'U': 'R', 'R': 'U', 'E': 'S', 'S': 'E'}
    >>> _plugboard('POLAND')
    {'P': 'O', 'O': 'P', 'L': 'A', 'A': 'L', 'N': 'D', 'D': 'N'}

View on GitHub (pinned to f5988cc097)

Solutions

  1. Set the second position within 1..26, e.g. rotpos=(1, 13, 26)
  2. Range-check the whole tuple up front: assert all(0 < p <= 26 for p in rotpos)
  3. Parse and clamp user-supplied settings before passing them in

Example fix

# before
rotpos = (1, 0, 1)

# after
rotpos = (1, 1, 1)
Defensive patterns

Strategy: validation

Validate before calling

assert all(0 < p <= 26 for p in rotpos), "positions must be in 1..26"

Type guard

def valid_rotor_positions(rotpos) -> bool:
    return len(rotpos) == 3 and all(0 < p <= 26 for p in rotpos)

Try / catch

try:
    settings = validate_and_transform(rotpos, rotsel, pb)
except ValueError as exc:
    if "rotor position" in str(exc):
        raise ConfigError("rotor settings out of range 1..26") from exc
    raise

Prevention

When it happens

Trigger: rotpos=(1, 0, 1), (5, 27, 5), or any tuple whose second element is < 1 or > 26.

Common situations: Building rotor settings from user input where the middle value was mistyped; arrays indexed from 0; settings files copied from an implementation with 0-based positions.

Related errors


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