Replace letters in a secret text
I want to change e开发者_开发百科very 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)
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
.
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 '
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.
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)
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())
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)
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
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])
精彩评论