Doing my part to promote PyOhio.

It’s going to be a brain-melting conference with amazing swag. We got people you wouldn’t believe lined up to present. Google recruiters will be there with suitcases full of cash looking for new hires. Terminator robots will travel backwards in time to try to prevent all the amazing breakthroughs that will happen on this day. We’re gonna shake the foundations of science.

I already mentioned my topic but here it is again because I’m shameless.

My netflix problem

We’ve had the same three movies in our house for a REALLY LONG TIME.

netflix.png

I’m sure all three of these films are great. But they also seem really heavy and serious. I have enough stress in my own life that I don’t want to absorb fictional stress also. So every time my wife and I have two or three hours to relax, we end up watching something else, like Andrew Zimmern chowing through a plate of horse penises.

Wacky idea for python coroutines

Christian Dowski posts some uses for python’s enhanced generators. I tried to type a comment on that post, but I couldn’t figure out how to submit it successfully. Either comments are not allowed or I failed the CAPTCHA.

Anyhow, ever since I read about how common lisp handles exceptions, I’ve been daydreaming about how to do the same trick in python. In lisp, an exception jumps to some other place to get handled, just like in python. However, what is different is that the exception handler can repair the problem and then hand control back into the original block. For example, in the lisp toplevel, if you forget to define a variable before you try to copy its value to somebody else, the exception will propagate to the debugger. And in the debugger, you can then assign a value to that variable, and then resume your original program.

So that’s the background for my idea for generators. The generator that is trying the exception-raising code could yield the traceback to another generator when it hits an uncaught exception. Then the other generator, the exception-handling generator, could repair/log/do whatever, and then yield a value back to the original code.

For example, if the original code is iterating through a list of two-tuples, and for each two-tuple, it divides the first element by the second element, when it raises a ZeroDivisionError, it could catch that and yield it over to the exception handler. Then the exception handler could do whatever, like maybe prompt the programmer to choose a new denominator. After the programmer chose a new denominator, the exception handler could yield that back to the original generator and then the original generator could resume.

Lua calls generators that can receive values “coroutines” or “non-preemtible threads”. I think those are better labels because they hint that generators are way more than just iterators in drag.

How to connect to a wireless network from the Ubuntu command line

Why use a friendly GUI when there’s cryptic shell commands out there?

Phoenix Coffee offers free wireless access without an access key and they broadcast their ESSID. Here’s how I connect:

$ sudo iwlist eth1 scan # eth1 is my wireless card.
eth1 Scan completed :
Cell 01 - Address: 0A:1D:19:15:C2:C1
ESSID:"bestcoffee"
Mode:Master
Channel:5
Frequency:2.432 GHz (Channel 5)
Quality=88/100 Signal level=-44 dBm Noise level=-81 dBm
Encryption key:off
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s; 6 Mb/s
9 Mb/s; 12 Mb/s; 18 Mb/s; 24 Mb/s; 36 Mb/s
48 Mb/s; 54 Mb/s
Extra:tsf=0000003befa89182

That scan lists every available access point. The important piece of information to extract here is the ESSID. Now I set my wireless card up to connect to that ESSID:

$ sudo iwconfig eth1 essid "bestcoffee"

And finally, I tell my card to request an IP address from the router:

$ sudo dhclient eth1 # gimme an IP address plz!
There is already a pid file /var/run/dhclient.pid with pid 6911
killed old client process, removed PID file
Internet Systems Consortium DHCP Client V3.0.6
Copyright 2004-2007 Internet Systems Consortium.
All rights reserved.
For info, please visit http://www.isc.org/sw/dhcp/

wmaster0: unknown hardware address type 801
wmaster0: unknown hardware address type 801
Listening on LPF/eth1/00:1c:bf:96:7e:21
Sending on LPF/eth1/00:1c:bf:96:7e:21
Sending on Socket/fallback
DHCPREQUEST of 192.168.1.112 on eth1 to 255.255.255.255 port 67
DHCPACK of 192.168.1.112 from 192.168.1.1
bound to 192.168.1.112 -- renewal in 251284 seconds.

I can type these three commands way faster than waiting for the GUI to fire up. Here they are again, without all the output:

$ sudo iwlist eth1 scan
$ sudo iwconfig eth1 essid "bestcoffee"
$ sudo dhclient eth1

Sometimes, I need to connect to a network with a hidden ESSID. That’s just as easy. I just configure the ethernet card to connect to anything:

$ sudo iwconfig eth1 essid any # any is a keyword, not the name of an ESSID.

Finally, some networks require an access key. Sometimes, people can give you the human-friendly version, and you can type that in like this:

$ sudo iwconfig eth1 key s:password # translates to the hex for me.

Note the s: in front. That translates what I type into the hex jibberish.

Other times, people insist on giving you the goofy string of hex digits, so you can set it like this:

$ sudo iwconfig eth1 key ACDB-1234-1234-EFG2

defaultdict.fromkeys does not play nice.

I use defaultdicts a lot when I’m grouping elements into a dictionary of lists. Here’s a simple example:

>>> a = defaultdict(list)

>>> a['x']
[]

>>> a['y'].append('yellow')

>>> a
defaultdict(, {'y': ['yellow'], 'x': []})

Now here’s where I got silly. I used defaultdict.fromkeys to prepopulate the ‘x’ and ‘y’ key right away, because I know I needed those:

>>> b = defaultdict.fromkeys(['x', 'y'], list)

>>> b
defaultdict(None, {'y': , 'x': })

>>> b['x']

>>> b['z']
------------------------------------------------------------
Traceback (most recent call last):
File "", line 1, in
KeyError: 'z'

Wowsa! b calls itself a defaultdict, but it is not a defaultdict.

I haven’t really thought this through, but this behavior is so unexpected that I would prefer that defaultdict.fromkeys raised a NotImplementedError.