Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Caesar's code - problems in implementation in Python

Tags:

python

ascii

Hello and thanks in advance for the answers, I was trying to do first task for PythonChallenge: http://www.pythonchallenge.com/pc/def/map.html and I have a comuple of questions regarding the code. I know that this code works:

import string
letters = string.ascii_lowercase
uletters = string.ascii_uppercase
text = ("g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.")
for x in range(0, 26):
    text = text.replace(letters[x-2], uletters[x])
    print(text.lower())

I was playing with the code a little bit and here are my observations in regard to which I have questions: 1. When I run:

text = text.replace(letters[x], uletters[x+2])

errors occur such as "trynslyte" instead of "translate". Why does this shift make such a change? 2. When I changed: uletters = string.ascii_uppercase to

uletters = string.ascii_lowercase

a bunch of "z"s and "y"s appeared. Again, what is the matter?

Many thanks

like image 357
user2579288 Avatar asked Jan 28 '26 20:01

user2579288


2 Answers

When you evaluate letters[x-2] and x is either 0 or 1, you end up with letters[-1] or letters[-2], which in Python accesses the last and the penultimate elements, respectively. This is why this step works. However, indices that are greater than the index of the last element does not have the same effect, so letters[x+2] won't work when x is too big.

What you need to do is something like this:

letters[(x+2)%len(letters)]

To force this wrap-around.

like image 80
Gustav Larsson Avatar answered Jan 31 '26 08:01

Gustav Larsson


A better way to do this is with str.translate().

from string import ascii_lowercase as lc

text = ("g fmnc wms bgblr rpylqjyrc gr zw fylb. rfyrq ufyr amknsrcpq ypc dmp. "
        "bmgle gr gl zw fylb gq glcddgagclr ylb rfyr'q ufw rfgq rcvr gq qm jmle. "
        "sqgle qrpgle.kyicrpylq() gq pcamkkclbcb. lmu ynnjw ml rfc spj.")

print (text.translate(str.maketrans(lc, lc[2:] + lc[:2])))

To write an encoder, just swap the arguments to maketrans() around:

print (text.translate(str.maketrans(lc[2:] + lc[:2], lc)))
like image 32
kindall Avatar answered Jan 31 '26 09:01

kindall