pjdavis
pjdavis

Reputation: 345

Using a dictionary with string replace method

def decoder(message):
    key = {'a':'n', 'b':'o', 'c':'p', 'd':'q', 'e':'r', 'f':'s', 'g':'t', 'h':'u', 
   'i':'v', 'j':'w', 'k':'x', 'l':'y', 'm':'z', 'n':'a', 'o':'b', 'p':'c', 
   'q':'d', 'r':'e', 's':'f', 't':'g', 'u':'h', 'v':'i', 'w':'j', 'x':'k',
   'y':'l', 'z':'m', 'A':'N', 'B':'O', 'C':'P', 'D':'Q', 'E':'R', 'F':'S', 
   'G':'T', 'H':'U', 'I':'V', 'J':'W', 'K':'X', 'L':'Y', 'M':'Z', 'N':'A', 
   'O':'B', 'P':'C', 'Q':'D', 'R':'E', 'S':'F', 'T':'G', 'U':'H', 'V':'I', 
   'W':'J', 'X':'K', 'Y':'L', 'Z':'M'} 
    for i in message:
        for x,y in key.items():
            if i == y:
                message = message.replace(y,x)
   return message

>>>decoder('Pnrfne pvcure? V zhpu cersre Pnrfne fnynq!')
'Carsar piphrr? I mhph prrsrr Carsar salad!'

Only some of the letters get translated and I cannot work out why. Can anyone spot why this is?

Upvotes: 0

Views: 90

Answers (2)

Jean-François Fabre
Jean-François Fabre

Reputation: 140196

Better change (or rebuild) the dictionary to fit str.translate method (which needs ascii code of the letter as key), done just for that:

key = {'a':'n', 'b':'o', 'c':'p', 'd':'q', 'e':'r', 'f':'s', 'g':'t', 'h':'u',
   'i':'v', 'j':'w', 'k':'x', 'l':'y', 'm':'z', 'n':'a', 'o':'b', 'p':'c',
   'q':'d', 'r':'e', 's':'f', 't':'g', 'u':'h', 'v':'i', 'w':'j', 'x':'k',
   'y':'l', 'z':'m', 'A':'N', 'B':'O', 'C':'P', 'D':'Q', 'E':'R', 'F':'S',
   'G':'T', 'H':'U', 'I':'V', 'J':'W', 'K':'X', 'L':'Y', 'M':'Z', 'N':'A',
   'O':'B', 'P':'C', 'Q':'D', 'R':'E', 'S':'F', 'T':'G', 'U':'H', 'V':'I',
   'W':'J', 'X':'K', 'Y':'L', 'Z':'M'}

# we can rebuild it like that
newkey = {ord(k):v for k,v in key.items()}

def decoder(s):
    return s.translate(newkey)

print( decoder('Pnrfne pvcure? V zhpu cersre Pnrfne fnynq!') )

result:

Caesar cipher? I much prefer Caesar salad!

all characters not in dictionary are left as-is.

next simplest thing without that would be: "".join([key.get(i,i) for i in s])

(using dict.get with default as input if not found)

In that particular case, there's an even simpler solution using codecs and rot13 encoding:

import codecs
def decoder(s):
    return codecs.encode(s,"rot13")

Upvotes: 1

Max Shepherd
Max Shepherd

Reputation: 61

You're replacing things multiple times. I think:

def decoder(message):
    key = {'a': 'n', 'b': 'o', 'c': 'p', 'd': 'q', 'e': 'r', 'f': 's', 'g': 't', 'h': 'u',
       'i': 'v', 'j': 'w', 'k': 'x', 'l': 'y', 'm': 'z', 'n': 'a', 'o': 'b', 'p': 'c',
       'q': 'd', 'r': 'e', 's': 'f', 't': 'g', 'u': 'h', 'v': 'i', 'w': 'j', 'x': 'k',
       'y': 'l', 'z': 'm', 'A': 'N', 'B': 'O', 'C': 'P', 'D': 'Q', 'E': 'R', 'F': 'S',
       'G': 'T', 'H': 'U', 'I': 'V', 'J': 'W', 'K': 'X', 'L': 'Y', 'M': 'Z', 'N': 'A',
       'O': 'B', 'P': 'C', 'Q': 'D', 'R': 'E', 'S': 'F', 'T': 'G', 'U': 'H', 'V': 'I',
       'W': 'J', 'X': 'K', 'Y': 'L', 'Z': 'M'}
    return ''.join(key[s] if s in key else s for s in message)

print(decoder('Pnrfne pvcure? V zhpu cersre Pnrfne fnynq!'))

is probably what you wanted (prints Caesar cipher? I much prefer Caesar salad!).

Upvotes: 1

Related Questions