Python Forum
Wrap from end to beginning. 27 to 1, 28 to 2 etc
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Wrap from end to beginning. 27 to 1, 28 to 2 etc
#1
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.
Reply
#2
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
Reply
#3
Thanks for the reply! I will try it out as soon as possible.
Dream.
Reply
#4
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?
Reply
#5
YAY! I got it to work:
if int(caeserints[num]) > max_limit:
            left_over = over_limit % 26
            caeserints[num] = str(left_over)
Reply
#6
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
To paraphrase: 'Throw out your dead' code. https://www.youtube.com/watch?v=grbSQ6O6kbs Forward to 1:00
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Just beginning dalekeel 2 233 Apr-15-2024, 11:49 AM
Last Post: Pedroski55
  Program doesnt return beginning bilisim19 2 940 Feb-15-2023, 06:23 PM
Last Post: Larz60+
  List of dataframe values beginning with x,y or z glidecode 3 1,949 Nov-08-2021, 10:16 PM
Last Post: glidecode
  How to start the program from the beginning. iamaghost 5 2,955 Feb-23-2021, 03:40 AM
Last Post: deanhystad
  Python Dev suggestion: Combining line-wrap with comments inside functions NikoNiels 2 1,738 Sep-26-2020, 07:45 PM
Last Post: bowlofred
  want to change the beginning of the result Rudinirudini 5 3,602 Nov-15-2018, 11:28 AM
Last Post: Rudinirudini
  Beginning of Beginner Help: Should I start with Python? appdevelnewb 2 3,060 Jul-23-2018, 11:17 PM
Last Post: appdevelnewb
  How to Loop CSV File Beginning at Specific Row? bmccollum 5 40,381 Nov-05-2017, 11:04 PM
Last Post: bmccollum
  Need help for beginning coding sylas 13 8,310 Mar-28-2017, 06:36 AM
Last Post: sylas

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020