2

How can I make each letter in the message to be encoded by replacing it with the letter k positions further in the alphabet?. For example, if k=3, “a” is replaced by “d”, “b” is replaced by “e”, and so on. The alphabet wraps around. “w” is replaced by “z”, “x” by “a”, “y” by “b”, and “z” by “c”. You can assume the message to be encoded is not empty and only contains lower case letters and spaces. A space is encoded as a space. this is what I tried but it doesn't work like it needs to. I need to be able to enter an amount of letters to skip.

def encode(string,keyletter):
  alpha="abcdefghijklmnopqrstuvwxyz"
  secret = ""
  for letter in string:
    index = alpha.find(letter)
    secret = secret+keyletter[index]
  print secret
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
mayna
  • 75
  • 1
  • 1
  • 4

2 Answers2

0

You could make use of Python's maketrans feature to produce a suitable character mapping as follows:

import string

def encode(text, rotate_by):
    s_from = string.ascii_lowercase
    s_to = string.ascii_lowercase[rotate_by:] + \
           string.ascii_lowercase[:rotate_by]
    cypher_table = string.maketrans(s_from, s_to)
    return text.translate(cypher_table)

text = raw_input("Enter the text to encode: ").lower()
rotate_by = int(raw_input("Rotate by: "))
print encode(text, rotate_by)

This would display:

Enter the text to encode: hello world
Rotate by: 3
khoor zruog
Martin Evans
  • 45,791
  • 17
  • 81
  • 97
  • What problem do you get? I have changed it to only work with lowercase letters. – Martin Evans Oct 03 '15 at 08:10
  • it won't run when i enter the rotate number is comes up as an error. – mayna Oct 03 '15 at 13:06
  • I need each line to be under 80 characters and when I try to split the line it doesn't work – mayna Oct 03 '15 at 13:16
  • import string def encode(text,rotate_by): s_from = string.ascii_lowercase + string.ascii_uppercase s_to = "string.ascii_lowercase[rotate_by:]" + "string.ascii_lowercase[:rotate_by]" + "string.ascii_uppercase[rotate_by:]" + "string.ascii_uppercase[:rotate_by]" cypher_table = string.maketrans(s_from, s_to) cypher_table = string.maketrans(s_from, s_to) return text.translate(cypher_table) text = raw_input("Enter the text to encode: ") rotate_by = int(raw_input("Rotate by: ")) print encode(text, rotate_by) – mayna Oct 03 '15 at 13:20
  • I have split the long line into two using a backslash as a line continuation character. That should help. – Martin Evans Oct 03 '15 at 17:19
0

Here is simple version that doesn't require rearranging the alpha string. Note this doesn't account for user input that is wrong such as entering a word instead of a number for the rotation.

while 1:
    rot = int(raw_input("Enter Rotation: "))
    cipher = raw_input("Enter String: ")
    secret,alpha = '', 'abcdefghijklmnopqrstuvwxyz'

    for i in cipher.lower():   #Loop through the original string 
        if i not in alpha:     #If the character in the original string is not in the alphabet just add it to the secret word
            secret += i
        else:
            x = alpha.index(i)   #Get index of letter in alphabet
            x = (x+rot)%26  #Find the index of the rotated letter
            secret += alpha[x]   #Add the new letter to the secret word
    print f

you can condense everything in the for loop to one line but it's not as pretty to read like so

f += i if i not in s else s[(s.index(i)+rot)%26]

If you want to get fancy with your Caesar Cipher then look up a keyed Caesar Cipher and add that option in also. That will require manipulating your alpha string though.

SirParselot
  • 2,640
  • 2
  • 20
  • 31