-1

I have a code and I'm having trouble making it interactive. Here's the problem:

"""Write a function called rot13 that uses the Caesar cipher to encrypt a message. The Caesar cipher works like a substitution cipher but each character is replaced by the character 13 characters to “its right” in the alphabet. So for example the letter “a” becomes the letter “n”. If a letter is past the middle of the alphabet then the counting wraps around to the letter “a” again, so “n” becomes “a”, “o” becomes “b” and so on. Hint: Whenever you talk about things wrapping around its a good idea to think of modulo arithmetic (using the remainder operator)."""

Here's the code to this problem:

def rot13(mess):
    alphabet = 'abcdefghijklmnopqrstuvwxyz'
    encrypted = ''
    for char in mess:
        if char == ' ':
            encrypted = encrypted + ' '
        else:
            rotated_index = alphabet.index(char) + 13
            if rotated_index < 26:
                encrypted = encrypted + alphabet[rotated_index]
            else:
                encrypted = encrypted + alphabet[rotated_index % 26]
    return encrypted

def main():
    print(rot13('abcde'))
    print(rot13('nopqr'))
    print(rot13(rot13('since rot thirteen is symmetric you should see this message')))

if __name__ == "__main__":
    main()

I want to make it interactive where you can input any message and you can rotate the letters however many times as you want. Here is my attempt. I understand you'd need two parameters to pass, but I'm clueless as to how to replace a few items.

Here's my attempt:

def rot13(mess, char):
    alphabet = 'abcdefghijklmnopqrstuvwxyz'
    encrypted = ''
    for char in mess:
        if char == ' ':
            encrypted = encrypted + ' '
        else:
            rotated_index = alphabet.index(char) + mess
            if rotated_index < 26:
                encrypted = encrypted + alphabet[rotated_index]
            else:
                encrypted = encrypted + alphabet[rotated_index % 26]
    return encrypted

def main():
    messy_shit = input("Rotate by: ")
    the_message = input("Type a message")
    print(rot13(the_message, messy_shit))


if __name__ == "__main__":
    main()

I don't know where my input should be taking place in the function. I have a feeling it could be encrypted?

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • `rot13(mess, char)`... `for char in mess`... You're overriding the char parameter... Which isn't even a character, it's `messy_shit`, which seems like you want to use as a number but input always returns a string – OneCricketeer Aug 27 '17 at 02:30
  • `rotated_index = alphabet.index(char) + mess` is probably incorrect. – Cuber Aug 27 '17 at 02:32
  • I understand this might be homework, but python already provides rot13. https://stackoverflow.com/questions/3269686/short-rot13-function-python – OneCricketeer Aug 27 '17 at 02:34

2 Answers2

0

This is probably what you're looking for. It rotates the message by the messy_shit input.

def rot13(mess, rotate_by):
        alphabet = 'abcdefghijklmnopqrstuvwxyz'
        encrypted = ''
        for char in mess:
            if char == ' ':
                encrypted = encrypted + ' '
            else:
                rotated_index = alphabet.index(char) + int(rotate_by)
                if rotated_index < 26:
                    encrypted = encrypted + alphabet[rotated_index]
                else:
                    encrypted = encrypted + alphabet[rotated_index % 26]
        return encrypted

    def main():
        messy_shit = input("Rotate by: ")
        the_message = input("Type a message")
        print(rot13(the_message, messy_shit))
Cuber
  • 713
  • 4
  • 17
  • I tried it out and it worked! Except for one thing. It worked when I removed the main function and had loose lines of code, but when I had the main function and called on it, it only gives me the first letter and not the phrase. I tried to throw in a len there but idk where. – Christian Martinez Aug 27 '17 at 03:13
  • sorry, it worked a second ago but regardless of the main function or no main function it only receives the first letter – Christian Martinez Aug 27 '17 at 03:23
0
def rot(message, rotate_by):
    '''
    Creates a string as the result of rotating the given string 
    by the given number of characters to rotate by

    Args:
        message: a string to be rotated by rotate_by characters
        rotate_by: a non-negative integer that represents the number
            of characters to rotate message by

    Returns:
        A string representing the given string (message) rotated by
        (rotate_by) characters. For example:

        rot('hello', 13) returns 'uryyb'
    '''
    assert isinstance(rotate_by, int) == True
    assert (rotate_by >= 0) == True

    alphabet = 'abcdefghijklmnopqrstuvwxyz'
    rotated_message = []
    for char in message:
        if char == ' ':
            rotated_message.append(char)
        else:
            rotated_index = alphabet.index(char) + rotate_by
            if rotated_index < 26:
                rotated_message.append(alphabet[rotated_index])
            else:
                rotated_message.append(alphabet[rotated_index % 26])

    return ''.join(rotated_message)

if __name__ == '__main__':
    while True:
        # Get user input necessary for executing the rot function
        message = input("Enter message here: ")
        rotate_by = input("Enter your rotation number: ")

        # Ensure the user's input is valid
        if not rotate_by.isdigit():
            print("Invalid! Expected a non-negative integer to rotate by")
            continue

        rotated_message = rot(message, int(rotate_by))
        print("rot-ified message:", rotated_message)

        # Allow the user to decide if they want to continue
        run_again = input("Continue? [y/n]: ").lower()
        while run_again != 'y' and run_again != 'n':
            print("Invalid! Expected 'y' or 'n'")
            run_again = input("Continue? [y/n]: ")

        if run_again == 'n':
            break

Note: It's more efficient to create a list of characters then join them to produce a string instead of using string = string + char. See Method 6 here and the Python docs here. Also, be aware that our rot function only works for lowercase letters of the alphabet. It'll break if you try to rot a message with uppercase characters or any character that isn't in alphabet.

Onel Harrison
  • 1,244
  • 12
  • 14