Wrap from end to beginning. 27 to 1, 28 to 2 etc - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: Wrap from end to beginning. 27 to 1, 28 to 2 etc (/thread-11126.html) |
Wrap from end to beginning. 27 to 1, 28 to 2 etc - DreamingInsanity - Jun-23-2018 As a simple project I wanted to make a Caeser cipher encoder and decoder using my own knowledge. I got the encoding done but am stuck on the wrap around if you go above 26. At the title said 27 goes back to 1 or -1 goes back to 26. I have tried lots but cant get it to work. It works when you input a shift of about 0 - 4 or have no characters in it like a 'z'. But otherwise, I get a 'KeyErrror' ranging from about 27 - 30. Here is my code. Please note: this may be just generally bad code / bad way of doing the conversion, but I would appreciate it if you did not improve it since I wanted to use as much of my own knowledge as possible and not have to use forums. Also there may be variable in there that don't do anything, they were just used for previous testing or conversion methods. from __future__ import print_function import time import string import operator num = 0 convto = {"a" : 1, "b" : 2, "c" : 3, "d" : 4, "e" : 5, "f" : 6, "g" : 7, "h" : 8, "i" : 9, "j" : 10, "k" : 11, "l" : 12, "m" : 13 , "n": 14, "o" : 15, "p": 16, "q" : 17, "r" : 18, "s" : 19, "t" : 20, "u" : 21, "v" : 22, "w" : 23, "x" : 24, "y" : 25, "z" : 26} #a = 0, b = 1 ect. convfrom = {"1" : "a", "2" : "b", "3" : "c", "4" : "d", "5" : "e", "6" : "f", "7" : "g", "8" : "h", "9" : "i", "10" : "j", "11" : "k", "12" : "l", "13" : "m" , "14" : "n", "15" : "o", "16" : "p", "17" : "q", "18" : "r", "19" : "s", "20" : "t", "21" : "u", "22" : "v", "23" : "w", "24" : "x", "25" : "y", "26" : "z"} usercipher = [] caeserints = [] def main(): global cipher global shift print("This will decrypt/encrypt Caeser Ciphers automatically!") time.sleep(0.5) print("----------------------------------------------------") time.sleep(1) cipher = input("Input cipher: ") cipher = cipher.replace(" ", "") cipher = cipher.lower() shift = int(input("Input the shift: ")) encrypt() def encrypt(): global encrypt global num usercipher = list(cipher) for letter in usercipher: numlist = convto[letter] + shift numlist = str(numlist) caeserints.append(numlist) for i in range(0,len(caeserints)): if oversize >= str(27): num = 0 num += 1 charsout = convfrom[caeserints[num]] #print(charsout) if __name__ == '__main__': main()Thanks in advance, Dream. RE: Wrap from end to beginning. 27 to 1, 28 to 2 etc - j.crater - Jun-23-2018 Modulo operator (%) is what you are looking for to solve for shifting over 26. It returns the remainder of integer division. >>> 26 % 26 0 >>> 27 % 26 1 >>> 28 % 26 2 >>> 3 % 26 3 RE: Wrap from end to beginning. 27 to 1, 28 to 2 etc - DreamingInsanity - Jun-23-2018 Thanks for the reply! I will try it out as soon as possible. Dream. RE: Wrap from end to beginning. 27 to 1, 28 to 2 etc - DreamingInsanity - Jun-24-2018 It works perfectly for postive numbers but for any negative number (-5 % 1) gives me 0. Is there another option for negative numbers? Thanks, Dream. I have tried this code: over_limit = num if int(over_limit) > max_limit: left_over = over_limit % 26 caeserint.append(left_over)But I am still getting a KeyError. Any help? RE: Wrap from end to beginning. 27 to 1, 28 to 2 etc - DreamingInsanity - Jun-24-2018 YAY! I got it to work: if int(caeserints[num]) > max_limit: left_over = over_limit % 26 caeserints[num] = str(left_over) RE: Wrap from end to beginning. 27 to 1, 28 to 2 etc - ljmetzger - Jun-24-2018 Good job. Take a look at the following code, and write finish the decryption algorithm: NOTES and suggestions: a. Make variables local if possible - i.e. avoid globals b. Pass items to functions as parameters c. Make variable names more meaningful d. I hard coded the inputs for easier debugging e. The key to success is to be able to identify 'test cases' when debugging (e.g. adding punctuation, positive and negative shifts [large and small], test string with all letters of the alphabet [caps and lower case]) from __future__ import print_function import time import string import operator num = 0 convto = {"a" : 1, "b" : 2, "c" : 3, "d" : 4, "e" : 5, "f" : 6, "g" : 7, "h" : 8, "i" : 9, "j" : 10, "k" : 11, "l" : 12, "m" : 13 , "n": 14, "o" : 15, "p": 16, "q" : 17, "r" : 18, "s" : 19, "t" : 20, "u" : 21, "v" : 22, "w" : 23, "x" : 24, "y" : 25, "z" : 26} #a = 0, b = 1 ect. convfromlist = {"1" : "a", "2" : "b", "3" : "c", "4" : "d", "5" : "e", "6" : "f", "7" : "g", "8" : "h", "9" : "i", "10" : "j", "11" : "k", "12" : "l", "13" : "m" , "14" : "n", "15" : "o", "16" : "p", "17" : "q", "18" : "r", "19" : "s", "20" : "t", "21" : "u", "22" : "v", "23" : "w", "24" : "x", "25" : "y", "26" : "z"} def remove_punctuation_and_numbers(s): _s = "" for _c in s: if _c.isalpha(): _s = _s + _c return _s def main(): print("This will decrypt/encrypt Caeser Ciphers automatically!") time.sleep(0.5) print("----------------------------------------------------") time.sleep(1) # cipher = input("Input cipher: ") cipher = "Hello World, am I a Zebra?" # cipher = "abCDEFghijklmnopqrstuvwxyz+-)(1234567890" cipher = remove_punctuation_and_numbers(cipher) cipher = cipher.lower() print("After remove punctuation cipher is '{}'".format(cipher)) # shift = int(input("Input the shift: ")) shift = -1 encrypted_string = encrypt(cipher, shift) print("The encrypted string is '{}'".format(encrypted_string)) decrypted_string = decrypt(encrypted_string, shift) print("The decrypted string is '{}'".format(decrypted_string)) def encrypt(cipher, shift): caeserints = [] for letter in cipher: # print(letter) numlist = (convto[letter] + shift) % 26 if numlist == 0: numlist = 26 numlist = str(numlist) caeserints.append(numlist) # print(caeserints) # print(len(caeserints)) encrypted_string = "" for num in caeserints: # print(num, type(num)) charout = convfromlist[num] # print(num, charout) encrypted_string += charout return encrypted_string def decrypt(encrypted_string, shift): decrypted_string = "" # To be completed return decrypted_string if __name__ == '__main__': main()Lewis |