TheAlgorithms/Python · error · Exception

decode() accepts only 'A', 'B' and spaces

Error message

decode() accepts only 'A', 'B' and spaces

What it means

Raised by baconian_cipher decode() when the input contains characters outside {'A', 'B', ' '}. Decoding splits on spaces and consumes each word in 5-character chunks looked up in decode_dict, so any other character (lowercase 'a'/'b', digits, '!', etc.) breaks the chunking and is rejected with a bare Exception.

Source

Thrown at ciphers/baconian_cipher.py:76

            raise Exception("encode() accepts only letters of the alphabet and spaces")
    return encoded


def decode(coded: str) -> str:
    """
    Decodes from Baconian cipher

    >>> decode("AABBBAABAAABABAABABAABBAB BABAAABBABBAAAAABABAAAABB")
    'hello world'
    >>> decode("AABBBAABAAABABAABABAABBAB")
    'hello'
    >>> decode("AABBBAABAAABABAABABAABBAB BABAAABBABBAAAAABABAAAABB!")
    Traceback (most recent call last):
        ...
    Exception: decode() accepts only 'A', 'B' and spaces
    """
    if set(coded) - {"A", "B", " "} != set():
        raise Exception("decode() accepts only 'A', 'B' and spaces")
    decoded = ""
    for word in coded.split():
        while len(word) != 0:
            decoded += decode_dict[word[:5]]
            word = word[5:]
        decoded += " "
    return decoded.strip()


if __name__ == "__main__":
    from doctest import testmod

    testmod()

View on GitHub (pinned to f5988cc097)

Solutions

  1. Normalize input: coded.upper() (and strip invalid chars) before decode().
  2. Validate: set(coded) <= {'A','B',' '} in your caller before invoking.
  3. Ensure words are multiples of 5 characters; otherwise decode_dict[word[:5]] raises KeyError instead.

Example fix

# before
decode('aabbb')  # Exception: decode() accepts only 'A', 'B' and spaces

# after
decode('aabbb'.upper())  # 'h'
Defensive patterns

Strategy: validation

Validate before calling

coded = coded.upper()
if set(coded) - {'A', 'B', ' '}:
    raise ValueError('invalid Baconian input')
# also verify each word length % 5 == 0 to avoid KeyError

Type guard

def is_baconian_decodable(s: str) -> bool:
    s = s.upper()
    return set(s) <= {'A', 'B', ' '} and all(len(w) % 5 == 0 for w in s.split())

Try / catch

try:
    decode(coded)
except Exception as e:  # bare Exception
    if "accepts only" in str(e):
        decode(coded.upper().replace('a', 'A').replace('b', 'B'))
    else:
        raise

Prevention

When it happens

Trigger: Calling decode('AABBBAABAAABABAABABAABBAB BABAAABBABBAAAAABABAAAABB!') as in the doctest; also lowercase input ('aabb...') since the check is case-sensitive, or a word whose length is not a multiple of 5 (which instead fails with a KeyError on decode_dict lookup).

Common situations: Decoding text that was lowercased by a transport layer, copy-pasted with stray punctuation, or Baconian strings with wrong letter case from a different encoder convention.

Related errors


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