Looping for every character in a string in Python decoder ring
Solution 1
How about:
s = 'ifmmp'
new_s = ''
for c in s:
n = ord(c)
n = n - 1
if n < ord('a'):
# 'a' -> 'z'
n = ord('z')
new_s += chr(n)
# print('new_s = %r' % new_s) -> new_s = 'hello'
Of course, this is only handling small letters, not capital.
Solution 2
Forget loops, whenever possible use the features built in to Python:
from string import maketrans, translate, ascii_lowercase
import functools
translation = maketrans(ascii_lowercase, ascii_lowercase[-1]+ascii_lowercase[:-1])
decipher = functools.partial(string.translate, table=translation)
print(decipher("ifmmp")) # 'hello'
Solution 3
from string import maketrans
table = maketrans('abcdefghijklmnopqrstuvwxyz/','zabcdefghijklmnopqrstuvwxy ')
for x in ('pdfbo','qipophsbqi','cmvf/nppo/jo/b/sfe/tlz'):
print x,' -> ',x.translate(table)
result
pdfbo -> ocean
qipophsbqi -> phonograph
cmvf/nppo/jo/b/sfe/tlz -> blue moon in a red sky
.
Edit
I rewrote the algorithm of Joachim (function better()) and I wrote my own solution not using maketrans() ( yop() ) :
s = '{ifmmp}\t\tcmvf-nppo \n SUNNY ~ ajhabh 14568'
def bof(s):
new_s = ''
for c in s:
n = ord(c)
n = n - 1
if n < ord('a'):
# 'a' -> 'z'
n = ord('z')
new_s += chr(n)
return new_s
def better(s):
li = []
for c in s:
n = ord(c)-1
if n == 96:
li.append('z')
elif 96<n<122:
li.append(chr(n))
else:
li.append(c)
return ''.join(li)
def yop(s):
gen = ((c,ord(c)-1) for c in s)
return ''.join('z' if y==96 else chr(y) if 96<y<122 else x for x,y in gen)
def better_yop(s):
def gen(h):
for c in h:
n = ord(c)-1
if n == 96:
yield 'z'
elif 96<n<122:
yield chr(n)
else:
yield c
return ''.join(gen(s))
for truc in (s,bof(s),better(s),yop(s),better_yop(s)):
print '%r\n%s\n' % (truc,truc)
result
'{ifmmp}\t\tcmvf-nppo \n SUNNY ~ ajhabh 14568'
{ifmmp} cmvf-nppo
SUNNY ~ ajhabh 14568
'zhello|zzbluezmoonzzzzzzzzz}zzigzagzzzzzz'
zhello|zzbluezmoonzzzzzzzzz}zzigzagzzzzzz
'{hello}\t\tblue-moon \n SUNNY ~ zigzag 14568'
{hello} blue-moon
SUNNY ~ zigzag 14568
'{hello}\t\tblue-moon \n SUNNY ~ zigzag 14568'
{hello} blue-moon
SUNNY ~ zigzag 14568
'{hello}\t\tblue-moon \n SUNNY ~ zigzag 14568'
{hello} blue-moon
SUNNY ~ zigzag 14568
However , my function yop() is slower than the function better()
.
Edit
Now the function better_yop() has a speed equivalent to the speed of better()
However, better() seems to be slightly faster than better_yop(). Since it is also simpler, better() is the best
Solution 4
I would recommend making the decoder ring a dictionary. Then open the input file for reading, read the file, loop through a character at a time and use the dictionary to translate to an output string. Finally write that string to a file.
user1063543
Updated on June 08, 2020Comments
-
user1063543 about 4 years
I'm trying to make a simple decoder ring in Python.
Example:
a=b, `b=c, c=d, etc.
I want the script to take an encoded message and output the decoded message.
For instance, I would input"ifmmp"
and it would output"hello"
.I've been thinking I need to split all the characters up and loop through them and change their
chr()
orord()
values.There doesn't seem to be any documentation for this in python.
-
eyquem over 12 yearsSorry, but this solution has some deficiencies. A minor one is that the function must obtain ord('a') for each character c in s: replacing with number 97 would be better. A bigger one is that
new_s += chr(n)
creates a new string for each character of s. If the text is 10000 long, you see the useless work... A major deficiency is that capital letters are treated indeed, as all the characters having an ord() < 97 that is to say digits, capital letters, characters !"#$%'()*+,-./:;<=>?@[]^_` and \t \r \n and others... More in the edit of my answer -
user1063543 over 12 yearsYes, I ended up using the maketrans solution, but made a translation table for all 26 orders it could be in, then had the program check for outputted english words, and had the english words written to a file.
-
Wtower about 9 yearsFor the record,
maketrans
is a static function ofbytes
andbytearrays
in Python 3 stackoverflow.com/questions/3031045/… -
Some programmer dude over 7 years@eyquem Magic numbers are never a solution I would recommend.