TheAlgorithms/Python · error · Exception

Odd number of symbols ({len(pbstring)})

Error message

Odd number of symbols ({len(pbstring)})

What it means

Raised by _plugboard() when the plugboard string has odd length: pairs cannot be formed. Every plugboard connection swaps two letters, so the string must contain an even number of symbols (spaces are not actually removed — see the no-op pbstring.replace call — so spaces count toward the length).

Source

Thrown at ciphers/enigma_machine2.py:139

    {'P': 'O', 'O': 'P', 'L': 'A', 'A': 'L', 'N': 'D', 'D': 'N'}

    In the code, ``pb`` stands for ``plugboard``

    Pairs can be separated by spaces

    :param pbstring: string containing plugboard setting for the Enigma machine
    :return: dictionary containing converted pairs
    """

    # tests the input string if it
    # a) is type string
    # b) has even length (so pairs can be made)
    if not isinstance(pbstring, str):
        msg = f"Plugboard setting isn't type string ({type(pbstring)})"
        raise TypeError(msg)
    elif len(pbstring) % 2 != 0:
        msg = f"Odd number of symbols ({len(pbstring)})"
        raise Exception(msg)
    elif pbstring == "":
        return {}

    pbstring.replace(" ", "")

    # Checks if all characters are unique
    tmppbl = set()
    for i in pbstring:
        if i not in abc:
            msg = f"'{i}' not in list of symbols"
            raise Exception(msg)
        elif i in tmppbl:
            msg = f"Duplicate symbol ({i})"
            raise Exception(msg)
        else:
            tmppbl.add(i)
    del tmppbl

View on GitHub (pinned to f5988cc097)

Solutions

  1. Supply an even-length string of complete pairs, e.g. 'PICTURES'
  2. Strip spaces yourself first: pb = pb.replace(' ', '') before calling
  3. Check len(pb) % 2 == 0 in your config validation

Example fix

# before
pb = 'PICTURES '  # 9 symbols after (broken) space handling

# after
pb = 'PICTURES'.replace(' ', '')  # explicitly even length
_plugboard(pb)
Defensive patterns

Strategy: validation

Validate before calling

pb = pb.replace(' ', '')  # module's own strip is a no-op
assert len(pb) % 2 == 0, "plugboard needs complete pairs"

Type guard

def has_paired_symbols(pb: str) -> bool:
    return len(pb.replace(' ', '')) % 2 == 0

Try / catch

try:
    pbdict = _plugboard(pb)
except Exception as exc:  # module raises bare Exception
    if "Odd number" in str(exc):
        raise ConfigError('plugboard string must have even length') from exc
    raise

Prevention

When it happens

Trigger: _plugboard('PICTURE') with 7 letters; strings with a single stray space such as 'PICTURES ' (9 chars, odd); concatenated settings that dropped a character.

Common situations: Typing a pair twice or dropping one letter in config; strings containing separators the code fails to strip (the replace result is discarded); hand-editing historical settings like 'AM FI EV ...' and leaving an unpaired trailing space/letter.

Related errors


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