{"record":{"id":"0222ea1cc01dda96","repo":"TheAlgorithms/Python","slug":"invalid-input-option","errorCode":null,"errorMessage":"invalid input option","messagePattern":"invalid input option","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"ciphers/simple_keyword_cypher.py","lineNumber":89,"sourceCode":"    \"\"\"\n    # Reverse our cipher mappings\n    rev_cipher_map = {v: k for k, v in cipher_map.items()}\n    return \"\".join(rev_cipher_map.get(ch, ch) for ch in message.upper())\n\n\ndef main() -> None:\n    \"\"\"\n    Handles I/O\n\n    :return: void\n    \"\"\"\n    message = input(\"Enter message to encode or decode: \").strip()\n    key = input(\"Enter keyword: \").strip()\n    option = input(\"Encipher or decipher? E/D:\").strip()[0].lower()\n    try:\n        func = {\"e\": encipher, \"d\": decipher}[option]\n    except KeyError:\n        raise KeyError(\"invalid input option\")\n    cipher_map = create_cipher_map(key)\n    print(func(message, cipher_map))\n\n\nif __name__ == \"__main__\":\n    import doctest\n\n    doctest.testmod()\n    main()\n","sourceCodeStart":71,"sourceCodeEnd":99,"githubUrl":"https://github.com/TheAlgorithms/Python/blob/f5988cc09713315817df6a7e327e258013a94440/ciphers/simple_keyword_cypher.py#L71-L99","documentation":"Raised by main() in ciphers/simple_keyword_cypher.py when the option prompt answer's first character is not 'e' or 'd'. The lookup dict {'e': encipher, 'd': decipher} raises KeyError, which is re-raised with the message 'invalid input option'. Note: input(...)[0] will IndexError first on an empty line.","triggerScenarios":"Answering 'x', 'encode', 'E ' is fine but 'encode' works ('e' taken); answering 'q' or 'help'; pressing Enter on an empty line (raises IndexError before the KeyError); answering uppercase is fine due to .lower().","commonSituations":"Interactive CLI users typing full words is OK ('encode' -> 'e') but invalid choices like 'both' or 'n' fail; piping empty input into the script; non-interactive automation calling the script without a TTY.","solutions":["Answer with a string starting with 'e' (encipher) or 'd' (decipher), e.g. 'encipher'","Re-prompt on bad input instead of crashing: loop until option[0] in {'e', 'd'}","For automation, call encipher/decipher directly instead of driving the interactive main()"],"exampleFix":"# before (main loop)\noption = input(\"Encipher or decipher? E/D:\").strip()[0].lower()\ntry:\n    func = {\"e\": encipher, \"d\": decipher}[option]\nexcept KeyError:\n    raise KeyError(\"invalid input option\")\n\n# after\nwhile True:\n    option = input(\"Encipher or decipher? E/D:\").strip().lower()\n    if option and option[0] in {\"e\", \"d\"}:\n        func = {\"e\": encipher, \"d\": decipher}[option[0]]\n        break\n    print(\"Please answer 'e' or 'd'.\")","handlingStrategy":"validation","validationCode":"option = input('Encipher or decipher? E/D:').strip().lower()\nwhile not option or option[0] not in {'e', 'd'}:\n    option = input(\"Please answer 'e' or 'd':\").strip().lower()\nfunc = {'e': encipher, 'd': decipher}[option[0]]","typeGuard":"def valid_option(answer: str) -> bool:\n    return bool(answer) and answer.strip().lower()[0] in {'e', 'd'}","tryCatchPattern":"try:\n    func = {'e': encipher, 'd': decipher}[option]\nexcept KeyError:\n    print(\"invalid input option; please answer 'e' or 'd'\")\n    option = input('Encipher or decipher? E/D:').strip().lower()[0]\n    func = {'e': encipher, 'd': decipher}[option]","preventionTips":["Loop the prompt until the first character is 'e' or 'd'","Handle empty input before indexing [0] to avoid IndexError","For automation, import encipher/decipher directly instead of running main()"],"tags":["cli","user-input","keyword-cipher","validation"],"backgroundTag":null,"analyzedSha":"f5988cc09713315817df6a7e327e258013a94440","analyzedAt":"2026-08-14T17:30:07.041Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}