b4sh
b4sh

Reputation: 55

Caesar Cipher validation

I'm making a Caesar cipher and everything is exactly how I wanted it but when it comes to validation if I enter '123' it outputs 'Your translated text is: 123' when I want it to return back to getMessage() and tell the user that the input was invalid. Help would be greatly appreciated because I have been struggling with this for days.

Thanks in advance.

            def getMode():
                 while True:
                     mode = input('Do you wish to encrypt(e) or decrypt(d) a message: ').lower()
                     if mode in 'encrypt e decrypt d'.split():
                         return mode
                     else:
                         print('Enter either "encrypt" or "e" or "decrypt" or "d".')

            def getMessage():
                 message = input('Enter your message: ')
                 return message

            def getKey():
                 key = 0
                 while True:
                     key = 5
                     return key

            def getTranslatedMessage(mode, message, key):
                 if mode[0] == 'd':
                     key = -key
                 translated = ''

                 for symbol in message:
                     if symbol.isalpha():
                         num = ord(symbol)
                         num += key

                         if symbol.isupper():
                             if num > ord('Z'):
                                 num -= 26
                             elif num < ord('A'):
                                 num += 26
                         elif symbol.islower():
                             if num > ord('z'):
                                 num -= 26
                             elif num < ord('a'):
                                 num += 26

                         translated += chr(num)
                     else:
                         translated += symbol
                 return translated



            mode = getMode()
            message = getMessage()
            key = getKey()

            print('Your translated text is: ', getTranslatedMessage(mode, message, key))

Upvotes: 2

Views: 507

Answers (2)

Padraic Cunningham
Padraic Cunningham

Reputation: 180481

If you just want to allow alpha characters:

def getMessage():
    while True:
        message = input('Enter your message: ')
        if message.isalpha():
            return message
        print("Invalid input, text must contain alphabetic characters only.")

To allow spaces and letters:

 if all(ch.isalpha() or ch.isspace() for ch in message):
            return message

A dict and using modulo is going to be a much more concise approach:

def get_mode():
    while True:
        mode = input('Do you wish to encrypt(e) or decrypt(d) a message: ').lower()
        if mode.lower() in {"e","d"}:
            return mode
        print('Enter either "encrypt" or "e" or "decrypt" or "d".')

def get_message():
    while True:
        message = input('Enter your message: ')
        if all(ch.isalpha() or ch.isspace() for ch in message):
            return message
        print("Invalid input, text must contain alphabetic characters only.")

def get_key():
    return 5

from string import ascii_letters

d = {k: i for i, k in enumerate(ascii_letters)}

enc = ascii_letters

def get_translated_message(mode, message, key):
    if mode == "e":
        return "".join([enc[(d[ch] + key) % 52] if not ch.isspace() else ch for ch in message])
    return "".join([enc[(d[ch] - key) % 52] if not ch.isspace() else ch for ch in message])

Just run it the same way:

mode = get_mode()
message = get_message()
key = get_key()

print('Your translated text is: ', get_translated_message(mode, message, key))

Upvotes: 3

idjaw
idjaw

Reputation: 26590

You mentioned you want to return an error if the user enters something like '123'. Based off of that requirement, the problem in your code is right here:

You are doing this check:

if symbol.isalpha():

Which will check if something is of alpha: A-Z

Therefore, in your else, you want to return your error when the alpha check fails:

So when you do this:

else:
    translated += symbol

You want this:

else:
    return "input invalid"

However, again, focusing on your code, this brings up another problem. You need to change how you are handling the return of your method, so the output makes more sense. You might want to consider something like this:

mode = getMode()
message = getMessage()
key = getKey()

result = getTranslatedMessage(mode, message, key)
if not result:
    print("invalid")
else:
    print('Your translated text is: ', result)

Based on recent updates, you are looking to preserve whitespace. Therefore, you should consider changing your code to also handle whitespace by simply adding an elif condition for checking for whitespace and adding ' ' to your translated variable. So, the code in your for loop would then look like this:

 for symbol in message:
         if symbol.isalpha():
             num = ord(symbol)
             num += key

             if symbol.isupper():
                 if num > ord('Z'):
                     num -= 26
                 elif num < ord('A'):
                     num += 26
             elif symbol.islower():
                 if num > ord('z'):
                     num -= 26
                 elif num < ord('a'):
                     num += 26

             translated += chr(num)
         elif symbol.isspace():
             translated += ' '
         else:
            return False

But Padraic's approach is really good and is definitely worth a look to consider refactoring.

Upvotes: 2

Related Questions