A Pythonic Tribute to xkcd

A place to discuss the implementation and style of computer programs.

Moderators: phlip, Moderators General, Prelates

klenwell
Posts: 18
Joined: Tue Jun 03, 2008 2:44 am UTC
Location: Southern California
Contact:

A Pythonic Tribute to xkcd

Postby klenwell » Tue Jun 03, 2008 2:56 am UTC

I had a little idle time at work today, so I ginned this up:

Code: Select all

#!/usr/bin/python

"""
a pythonic tribute to xkcd
http://phosphorusandlime.blogspot.com/2008/06/pythonic-tribute-to-xkcd.html
"""

xkcd = lambda x,k,c,d: (({k:False},d,c)[int(''.join([str(int(k in t)) for t in [c,d]]),2)])[k] or x

X = 'webcomic'
K = 'romance'
C = {'romance': 'at last!', 'sarcasm':'grep -R soulmate /', }
D = {'math':complex(6,9j), 'language':'to be or not to be'}

print xkcd(X,'language',C,D)
print xkcd(X,'microsoft',C,D)
print xkcd(X,K,C,D)


Enjoy.

For a clue, see http://phosphorusandlime.blogspot.com/2 ... -xkcd.html

User avatar
sparkyb
Posts: 1091
Joined: Thu Sep 06, 2007 7:30 pm UTC
Location: Camberville proper!
Contact:

Re: A Pythonic Tribute to xkcd

Postby sparkyb » Tue Jun 03, 2008 3:37 am UTC

I figured out what it did even before following the link to your website. The binary string trick is pretty cool, but I could think of a lot of better ways to do this. Were you just trying to do it or were you intentionally trying to come up with something more obfuscated? Also, I think there are two problem, although they only occur in certain cases and I'm not exactly sure what your preconditions are. I am assuming that the goal of the lambda function xkcd is to take some value x, some key k, and 2 dictionaries c and d, and return c[k] if c has a key k, otherwise d[k] if d has a key k, or x otherwise. If that is so I find the following problems. First, what if k is in both c and d? You will get an index error. If you really wanted it to match that PHP expression then all you'd need to do is add another c:

Code: Select all

xkcd = lambda x,k,c,d: (({k:False},d,c,c)[int(''.join([str(int(k in t)) for t in [c,d]]),2)])[k] or x


Second, what if c[k] or d[k] exists but is False (or any other false value)? The function would return x instead. This could be a very good time for one of my favorite lambda tricks (wrapping ever term in a list and then taking index 0 at the end) but wouldn't also be as easy to write it as:

Code: Select all

xkcd = lambda x,k,c,d: (({k:x},d,c,c)[int(''.join([str(int(k in t)) for t in [c,d]]),2)])[k]


Now, I think a much more straightforward way to write this (using the trick I described above to prevent the previous problem):

Code: Select all

xkcd = lambda x,k,c,d: ((k in c) and [c[k]] or ((k in d) and [d[k]] or [x]))[0]


But I think the simplest way (although which does not get to benefit from any short-circuit logic) is:

Code: Select all

xkcd = lambda x,k,c,d: c.get(k,d.get(k,x))

klenwell
Posts: 18
Joined: Tue Jun 03, 2008 2:44 am UTC
Location: Southern California
Contact:

Re: A Pythonic Tribute to xkcd

Postby klenwell » Tue Jun 03, 2008 5:11 am UTC

sparkyb wrote:But I think the simplest way (although which does not get to benefit from any short-circuit logic) is:

Code: Select all

xkcd = lambda x,k,c,d: c.get(k,d.get(k,x))

Well done. Someone at the office eventually spoiled my fun by pointing me to dict.get(). But, by that point, I'd thrown off the bonds of any earthly restraint. Plus, every once in a while we have a stupid lambda trick contest during our weekly code review and I gotta think I'm the front runner for the next one.

sparkyb wrote:First, what if k is in both c and d? You will get an index error.

Good point.

sparkyb wrote:I'm not exactly sure what your preconditions are.

The one practical scenario where I use this quite frequently in PHP, and that prompted this exercise, is in tracking a session variables across page calls in a web app. In this case, I usually want an empty value to revert to the default. Something like:

Code: Select all

$_SESSION['foo'] = ( !empty($_POST['foo']) ) ? $_POST['foo'] : $_SESSION['foo'];


Throw in COOKIE or GET values and we get closer to the situation originally imagined here.

klenwell
Posts: 18
Joined: Tue Jun 03, 2008 2:44 am UTC
Location: Southern California
Contact:

Re: A Pythonic Tribute to xkcd

Postby klenwell » Tue Jun 03, 2008 5:14 am UTC

sparkyb wrote:This could be a very good time for one of my favorite lambda tricks (wrapping ever term in a list and then taking index 0 at the end)

By the way, that's a neat trick. I'm going to make a note of that.

Please don't double post (post two comments without any intervening ones). You can edit what you wanted to add into the first one instead.

User avatar
sparkyb
Posts: 1091
Joined: Thu Sep 06, 2007 7:30 pm UTC
Location: Camberville proper!
Contact:

Re: A Pythonic Tribute to xkcd

Postby sparkyb » Tue Jun 03, 2008 2:55 pm UTC

klenwell wrote:
sparkyb wrote:This could be a very good time for one of my favorite lambda tricks (wrapping ever term in a list and then taking index 0 at the end)

By the way, that's a neat trick. I'm going to make a note of that.


Well then maybe you'd do well to read that Stupid Lambda Tricks page that you yourself linked to. I didn't get it from there, but later I did follow that link and it is on there. They describe it better than I do, of course I think you got the idea.


Return to “Coding”

Who is online

Users browsing this forum: No registered users and 10 guests