For class I am creating a function that converts each letter in the alphabet into its corresponding letter after a given shift, in a way that a caesar cipher would shift each letter. So far I have:
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
# Problem 1.
def build_cipher(shift):
'''
Description: takes in shift (an integer representing the amount the letter key in the dictionary is shifted from its corresponding letter) and returns a dictionary containing all letters and their corresponding letters after the shift. This is acheived through subtracting the shift from the number corresponding to the letter, and using modulo 26.
>>> build_cipher(3)
'''
for i in range(0, 26):
letter = alphabet[i]
shiftedletter = alphabet[(i - shift) % 26]
return {letter : shiftedletter}
This is mostly correct, but it only outputs:
{'a': 'x'}
How can I get it to output for each letter? I want my output to be:
{‘a’: ‘x’,
‘b’: ‘y’,
‘c’: ‘z’,
‘d’: ‘a’,
‘e’: ‘b’,
‘f’: ‘c’,
‘g’: ‘d’,
‘h’: ‘e’,
‘i’: ‘f’,
‘j’: ‘g’,
‘k’: ‘h’,
‘l’: ‘i’,
‘m’: ‘j’,
‘n’: ‘k’,
‘o’: ‘l’,
‘p’: ‘m’,
‘q’: ‘n’,
‘r’: ‘o’,
‘s’: ‘p’,
‘t’: ‘q’,
‘u’: ‘r’,
‘v’: ‘s’,
‘w’: ‘t’,
‘x’: ‘u’,
‘y’: ‘v’,
‘z’: ‘w’}
I think the problem is that it isn't looping for each letter in the alphabet, but I am not exactly sure how to fix that. Any help is appreciated, thank you!
CodePudding user response:
You want to build the dictionary first. When you're done, return the dictionary you just built.
def build_cipher(shift):
cipher = dict()
for i in range(0, 26):
letter = alphabet[i]
shiftedletter = alphabet[(i - shift) % 26]
cipher[letter] = shiftedletter
return cipher
Or, as a comprehension:
def build_cipher(shift):
return {alphabet[i]: alphabet[(i - shift) % 26] for i in range(0, 26)}
CodePudding user response:
As an alternative, you can use str.maketrans()
to make the translation table t
, and then str.translate(t)
to translate a string:
In [1]: alpha = "abcdefghijklmnopqrstuvwxyz"
In [2]: shift = 13
In [3]: t = str.maketrans(alpha, alpha[shift:] alpha[:shift])
In [4]: "hello world".translate(t)
Out[4]: 'uryyb jbeyq'
In [5]: "hello world".translate(t).translate(t)
Out[5]: 'hello world'
Note that str.translate(t).translate(t)
only works for a shift of 13.
CodePudding user response:
This is one way to solve it.
alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
# Problem 1.
def build_cipher(shift):
result = {}
for i in range(0, 26):
letter = alphabet[i]
shiftedletter = alphabet[(i - shift) % 26]
result.update({letter : shiftedletter})
return result
CodePudding user response:
A simple solution.
def build_cipher(shift):
'''
Description: takes in shift (an integer representing the amount the letter
key in the dictionary is shifted from its corresponding letter) and returns
a dictionary containing all letters and their corresponding letters after
the shift. This is acheived through subtracting the shift from the number
corresponding to the letter, and using modulo 26.
>>> build_cipher(3)
'''
alphabet = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
]
cipher = {}
for i in range(0, 26):
cipher[alphabet[i]] = alphabet[(i - shift) % 26]
return cipher
cipher = build_cipher(3)
for k,v in cipher.items():
print("{}: {}".format(k, v))
Output:
a: x
b: y
c: z
d: a
e: b
f: c
g: d
h: e
i: f
j: g
k: h
l: i
m: j
n: k
o: l
p: m
q: n
r: o
s: p
t: q
u: r
v: s
w: t
x: u
y: v
z: w
CodePudding user response:
The moment you first call return
it will jump out of the function.
You could either change the return statement into a print-statement, or you could have a return string, that you partially put together in the loop. Something like this:
ret = ""
for i in range(0, 26):
letter = alphabet[i]
shiftedletter = alphabet[(i - shift) % 26]
ret = "{" letter " : " shiftedletter "}\n"
return ret