program to encode and decode baconian or bacon s cipher wikipedia reference https en wikipedia orgwikibacon27scipher encodes to baconian cipher encodehello aabbbaabaaababaababaabbab encodehello world aabbbaabaaababaababaabbab babaaabbabbaaaaababaaaabb encodehello world traceback most recent call last exception encode accepts only letters of the alphabet and spaces decodes from baconian cipher decodeaabbbaabaaababaababaabbab babaaabbabbaaaaababaaaabb hello world decodeaabbbaabaaababaababaabbab hello decodeaabbbaabaaababaababaabbab babaaabbabbaaaaababaaaabb traceback most recent call last exception decode accepts only a b and spaces encodes to baconian cipher encode hello aabbbaabaaababaababaabbab encode hello world aabbbaabaaababaababaabbab babaaabbabbaaaaababaaaabb encode hello world traceback most recent call last exception encode accepts only letters of the alphabet and spaces 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
encode_dict = {
    "a": "AAAAA",
    "b": "AAAAB",
    "c": "AAABA",
    "d": "AAABB",
    "e": "AABAA",
    "f": "AABAB",
    "g": "AABBA",
    "h": "AABBB",
    "i": "ABAAA",
    "j": "BBBAA",
    "k": "ABAAB",
    "l": "ABABA",
    "m": "ABABB",
    "n": "ABBAA",
    "o": "ABBAB",
    "p": "ABBBA",
    "q": "ABBBB",
    "r": "BAAAA",
    "s": "BAAAB",
    "t": "BAABA",
    "u": "BAABB",
    "v": "BBBAB",
    "w": "BABAA",
    "x": "BABAB",
    "y": "BABBA",
    "z": "BABBB",
    " ": " ",
}


decode_dict = {value: key for key, value in encode_dict.items()}


def encode(word: str) -> str:
    
    encoded = ""
    for letter in word.lower():
        if letter.isalpha() or letter == " ":
            encoded += encode_dict[letter]
        else:
            raise Exception("encode() accepts only letters of the alphabet and spaces")
    return encoded


def decode(coded: str) -> str:
    
    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()