kame
kame

Reputation: 21990

Replace letters in a secret text

I want to change every letter in a text to after next following letter. But this program doesnt work. Does anyone know why. Thanks in advance. There is also a minor problem with y and z.

import string

letters = string.ascii_lowercase
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(1,24):
    text.replace(letters[x],letters[x+2])
print(text)

Upvotes: 3

Views: 10709

Answers (8)

blacktea
blacktea

Reputation: 11

I finished it by a common way. Here is my code. I didn't use string.translate and I have tried @mangobug's code. I don't know why, but it doesn't work.

import string
def puzzle(x):
    y=" "
    for i in x:
        if ord("a")<= ord(i)<=ord("x"):
            n=ord(i)+2
        elif ord(i)==ord("y"):
            n=ord("a")
        elif ord(i)==ord("z"):
            n=ord("b")
        else:
            n=ord(i)
        y=y+chr(n)
    return y

x="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."
y=puzzle(x)
print y

Upvotes: 1

Zain Khan
Zain Khan

Reputation: 3793

import string    

s = "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. "    
trans = string.maketrans('abcdefghijklmnopqrstuvwxyz', 'cdefghijklmnopqrstuvwxyzab')
string.translate(s, trans)

Upvotes: 2

sastanin
sastanin

Reputation: 41541

This should do what you want:

>>> rot = lambda xs: (xs + [xs[0]])[1:]
>>> apply = lambda n,f,x: (n == 0) and x or f(apply(n-1,f,x))
>>> abc = map(chr,range(ord('a'),ord('z')+1))
>>> d = dict(zip(list(abc),apply(2,rot,(list(abc)))))
>>> s = "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. "
>>> reduce(lambda a,b:a+b,map(lambda c: d.get(c,' '),list(s)),"")
'i hope you didnt translate it by hand  thats what computers are for  doing it in by hand is inefficient and that s why this text is so long  using string maketrans   is recommended  now apply on the url  '

Upvotes: 4

Antony Hatchkins
Antony Hatchkins

Reputation: 34014

Solution closest to yours is:

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())

Upvotes: 2

Hamish Grubijan
Hamish Grubijan

Reputation: 10830

Ok, I incorporated the suggestions, but this is still not quite there yet ...

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. "
convert = lambda t: chr(ord('a') + (ord(t) - ord('a')) % 26)
txt_mod = ''.join(convert(chr(ord(t) + 2) if 'a' <= t <= 'z' else t) for t in text)

Upvotes: 2

Andrew Jaffe
Andrew Jaffe

Reputation: 27107

Strings are immutable in python.

So text.replace returns a string, but doesn't change its original string.

Given that, you shouldn't actually use text.replace, since you would have to change the string 24 (or probably 26; see below) times. Rather, you can actually create a translation table to do all the changes at once, and use string.translate.

To do that, you should first use string.maketrans to convert from the letters to the second letter following (and what do you want to do with 'y' and 'z'? I expect they should probably become 'a' and 'b'). That will give you a translation table over all possible characters for translate.

Upvotes: 8

Ritwik Bose
Ritwik Bose

Reputation: 6069

aren't you forgetting forgetting base cases?

problems that I see are: 1)

for x in range(1,24):

-- shouldn't that be your string length?

2)

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

what happens when x == 23? I suggest using ((x+2) % len(letters)) or something like that.

also, are you sure that text is being updated? I know python treats strings as arrays, but does that mean that the letters are updated everytime you do replace?

try:

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

Upvotes: 0

Mark Byers
Mark Byers

Reputation: 838944

Your first error is that strings are immutable so your replace isn't doing anything. To replace characters in a string you have to reassign:

text = text.replace(a, b)

But this is a very inefficient way to do it anyway as you are creating many temporary strings which will just be discarded again shortly afterwards. You should try to iterate over the string handling one character at a time and the join the result.

I won't give away the full solution so that you can have another go.

Upvotes: 3

Related Questions