Somebody had uploaded a video of him or her waltzing through the entire level in a little bit more than thirty seconds. In other words, because this particular player had skills and was familiar with the area, he or she was able to achieve something that a "pair" of less experienced people had not been able to do in sixty times the amount of effort! I guess, sometimes "knowing your stuff" really makes a difference.
I was recently reminded of this at work when I was chatting with somebody else about my progress in learning python. I am mostly a Java guy, I said, so there were a couple of things getting used to. I was doing ok nowadays, but there were still things I wished the language had. A ternary operator, for example.
"Yeah, I've heard of this before," my colleague responded. "A friend once told me about a workaround. Did you know that you can just combine or and and to do the same in python? Take a look at the following:"
>>> True and 1 or 2
1
>>> False and 1 or 2
2
At first, I was amazed -- why had I not thought of this option myself? The idom of "condition and true-value or false-value" seemed to fit perfectly. If the condition was true, the logical and would evaluate the "true-value"; if it was false, it would skip the second argument and directly proceed to the "false-value". Euphoria set in, but it was only short-lived: the idom is actually flawed! Take a look at the following snippet:
def part2(s):
return s.startswith('part1=') and s[6:].strip() or 'part2'
This snippet defines a very simple parser that is supposed to interpret a string in the format of "part1=somevalue" and return the right-hand-side of the equation. If the string does not match the pattern, it should return part2 as a default.
If we fire up a python shell and test out the method, we expect the following to happen:
>>> part2('part1=3')
'3'
>>> part2('x')
'part2'
>>> part2('part1= ')
''
Unfortunately, the third input returns part2 instead. What went wrong? The problem is that a construct of logical operators is not equal to the ternary operator! A ternary operator "condition?trueValue:falseValue" is expected to behave as following:
- Evaluate condition
- If condition is true, return trueValue
- If condition is false, return falseValue
Using the idiom condition and trueValue or falseValue however behaves more like this:
- If condition, compute condition and trueValue
- If condition and trueValue is true, return condition and trueValue
- If condition and trueValue is false, return falseValue
In other words, the content of trueValue influences the overall result. If trueValue happens to be evaluated as false (which is the case for None-values and, as in this case, the empty string), our idiom will return the wrong value!
By this point in the post, you might be wondering why this whole episode made me think of Mario 64, but I'm getting to it right now: my buddy and I were both reasonably smart people, and were puzzled at how we could spend so much time thinking about this problem and running into a wall. Somebody else must have had the same issue before! We did a quick google search and this is what we came up with:
On 9/29/2005, Guido decided to add conditional expressions in the
form of "X if C else Y". [1]
The motivating use case was the prevalance of error-prone attempts
to achieve the same effect using "and" and "or". [...]
In other words, with python 2.5, there actually was a ternary operator! This is how to use it
def part2(s):
return s[6:].strip() if s.startswith('part1=') else 'part2'
I had learned python from copying-and-pasting snippets and checking a reference book that was still on 2.4 level. If I had known the area a little better, I could have saved myself quite a bit of time...
2 comments:
Don't feel bad, happens all the time.
You might want to take a look at the 'what's new' doc:
http://docs.python.org/whatsnew/whatsnew25.html
And maybe you could work your way back through 2.4 etc.
the old way to do ternary operator was
(cond and [trueVal] or [falseVal])[0]
kinda nasty.
Post a Comment