Home > front end >  Using a dictionary to create Caesar Cipher, outputting only one item
Using a dictionary to create Caesar Cipher, outputting only one item

Time:10-13

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
  • Related