Reputation: 21990
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
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
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
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
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
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
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
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
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