Reputation:
I have this code that I used for a python challenge, now it use to work perfectly, but now the only result I get as an output is 'i'.
I'm not sure but I'm assuming that my code isn't storing all the values I'm giving ascii_list for some reason.
a = """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."""
def ascii_list(a):
for i in a: return chr(ord(i)+2)
alist = ascii_list(a)
print ("".join(alist))
Now my question is, why is it doing this and where have I gone wrong? I'm using Python 3.3.
(Go easy on me I've tried to do this right)
Upvotes: 0
Views: 98
Reputation: 365717
The problem is here:
def ascii_list(a):
for i in a: return chr(ord(i)+2)
The first time through the loop, you return
. That ends the function, and the loop, on the first value.
You could change this into a generator function:
def ascii_list(a):
for i in a: yield chr(ord(i)+2)
Intuitively, this is pretty simple. You can yield
as many times as you want, instead of return
ing one value. When someone tries to loop over the result of your function, or pass it to a function like list
or join
, it will get all the yield
ed results.
But if this is too confusing, and you're not ready to learn about generators yet, you could also build up a list explicitly:
def ascii_list(a):
return [chr(ord(i)+2) for i in a]
… or:
def ascii_list(a):
result = []
for i in a: result.append(chr(ord(i)+2))
return result
As Jon Clements pointed out in a comment, this isn't quite the right algorithm for what you're trying to do. First, you need to "roll over" past the end of the alphabet—otherwise, you get {
instead of a
and |
instead of b
. If you understand the %
(modulus/remainder) operator, you can do this in a single step; if not, you can use an if
/else
. Second, you don't want to translate non-letters like space or .
at all; for this, you probably want and if
/else
. Writing this out verbosely:
def ascii_list(a):
for i in a:
if not i.isalpha():
rot = 0
else if i.lower() > 'x':
rot = 2 - 26
else:
rot = 2
yield chr(ord(i) + rot)
Upvotes: 3
Reputation: 174624
In addition to a list comprehension, you can also use a map
with your method:
def get_code(i):
return chr(ord(i)+2)
''.join(map(get_code, a))
Or a more compact version, with a lambda:
''.join(map(lambda i: chr(ord(i)+2), a))
Upvotes: 0
Reputation: 6190
You start iterating the string, get to character 'g', then return chr(ord('g') + 2). That returns 'i' and terminates the loop.
Upvotes: 0
Reputation: 308206
That's because you're returning in the first pass of the loop. You really want a list comprehension:
return [chr(ord(i)+2) for i in a]
Upvotes: 1