Reputation: 33
Assume a message is entered and you want to encrypt it by moving each letter in the word "up the alphabet" with a x number of spaces. eg "cat" moved one space becomes "dbu":
I am trying to build a dictionary with the alphabet in upper and lower case as the keys, and a duplicate alphabet (moved on "shift" number of letters) as the values. eg shift=1 d={a:b, b:c...A:B, B:C}. This alphabet changes every time "shift" changes. Please let me know where I am going wrong. Please see: def build_shift_dict(self, shift) below. Thanks in advance!:
class Message(object):
### DO NOT MODIFY THIS METHOD ###
def __init__(self, text):
'''
Initializes a Message object
text (string): the message's text
a Message object has two attributes:
self.message_text (string, determined by input text)
self.valid_words (list, determined using helper function load_words
'''
self.message_text = text
self.valid_words = load_words(WORDLIST_FILENAME)
### DO NOT MODIFY THIS METHOD ###
def get_message_text(self):
'''
Used to safely access self.message_text outside of the class
Returns: self.message_text
'''
return self.message_text
### DO NOT MODIFY THIS METHOD ###
def get_valid_words(self):
'''
Used to safely access a copy of self.valid_words outside of the class
Returns: a COPY of self.valid_words
'''
return self.valid_words[:]
import string
def build_shift_dict(self, shift):
'''
Creates a dictionary that can be used to apply a cipher to a letter.
The dictionary maps every uppercase and lowercase letter to a
character shifted down the alphabet by the input shift. The dictionary
should have 52 keys of all the uppercase letters and all the lowercase
letters only.
shift (integer): the amount by which to shift every letter of the
alphabet. 0 <= shift < 26
Returns: a dictionary mapping a letter (string) to
another letter (string).
'''
stringLower = string.ascii_lowercase
stringUpper = string.ascii_uppercase
Alphabet = list(stringLower + stringUpper)
dictionary = {}
string2Lower = list(string.ascii_lowercase[shift:] + string.ascii_lowercase[0:shift])
string2Upper = list(string.ascii_uppercase[shift:] + string.ascii_uppercase[0:shift])
combinedList = string2Lower.append(string2Upper)
for key in Alphabet:
for value in combinedList:
dictionary[key] = value
combinedList.remove(value)
return dictionary
def apply_shift(self, shift):
'''
Applies the Caesar Cipher to self.message_text with the input shift.
Creates a new string that is self.message_text shifted down the
alphabet by some number of characters determined by the input shift
shift (integer): the shift with which to encrypt the message.
0 <= shift < 26
Returns: the message text (string) in which every character is shifted
down the alphabet by the input shift
'''
result=''
dictionary = self.build_shift_dict(shift)
messageString = str(Message)
for letter in messageString:
if letter in dictionary.keys:
result += dictionary[i]
return result
Upvotes: 0
Views: 2741
Reputation: 6712
You can cut a lot of the class based stuff out, as it isn't doing much apart from adding boilerplate code and complicating things. You can put it back in after, but Here I've written the core functionality out for you in a more pythonic way:
import string
def build_shift_dict(shift):
alphabet = string.ascii_lowercase + string.ascii_uppercase
shifted_lower = string.ascii_lowercase[shift:] + string.ascii_lowercase[0:shift]
shifted_upper = string.ascii_uppercase[shift:] + string.ascii_uppercase[0:shift]
shifted_alphabet = shifted_lower + shifted_upper
return {key: value for key, value in zip(alphabet, shifted_alphabet)}
Once you've got shifted_alphabet
, you can zip
it with the original alphabet, and then use a Dictionary Comprehension to create the dictionary. That's a much more pythonic way of making a dict, instead of a for loop
Then to apply the shift, we can use a list comprehension to lookup the dictionary for each letter in the message, and create a list, which is then join
-ed back together into a string, and returned.
def apply_shift(shift, message):
dictionary = build_shift_dict(shift)
return ''.join(dictionary[letter] for letter in message)
Then to use:
>>> print(apply_shift(2, "Hello"))
Jgnnq
Available here -> https://repl.it/@LukeStorry/63042493
Update: You can avoid creating and using a dict by using ord
and chr
instead:
def apply_shift_v2(shift, message):
return ''.join(chr(ord(letter) + shift) for letter in message)
This has the added bonus of working for any character, not just being limited to the alphanumeric ones you set up the dict with.
Upvotes: 2
Reputation: 174
my suggestion is instead of creating dictionary this will be lot simpler
def apply_shift(shift, letter):
asci = ord(letter)
new_ascii = 97 + (asci + shift -97) % 26
return chr(new_ascii)
print(apply_shift(1, 'z') )
output:
a
Upvotes: 0