Showing git status in my Zsh prompt

I like Zsh. It’s a powerful, efficient shell. It’s better than Bash by just about every metric (better performance, more features, better sh compatibility). I really have no idea why people keep using Bash.

Anyway, I put together a little piece of zshrc to show my current status in right-hand prompt – a prompt that’s shown right-aligned in the shell. Zsh has a couple of features that make this really easy.

First the prompt_subst options instructs the shell to do variable substitution when evaluating prompts. So if you were to set your prompt to '$PWD> ' then your prompt would contain your current directory. Of course you wouldn’t do it that way, %~ does that much more nicely, but that takes us to Zsh’s second feature, ridiculously powerful variable substitution and expansion. In my prompt I just use the simple $(shell-command) substitution, but there’s a full complement of file-io, string manipulation and more to be had.

Breaking into a debugger in Python

This is probably old news to most folks, but I only found out about this recently, more than twelve years into being a Python programmer.

The pdb (Python Debugger) module has a few useful functions. For years I’ve been using pdb.pm(), the postmortem debugger. It can be run from the Python shell to invoke a debugger after an exception. Traditionally I’ve done:

% python -i myscript.py
(some exception occurs)
>>> import pdb
>>> pdb.pm()
(Pdb) 

But for this to work you need to be able to pass arguments to the interpreter (-i) and the code needs to throw an exception that isn’t caught.

Enter pdb.set_trace(). It begins the same interactive debugger that pdb.pm() provides upon request, from code. So in the middle of a function that’s confusing me I add:

from pdb import set_trace;set_trace()

and my code will stop, ready for me to tear apart its runtime state. I just wish it had a more descriptive name so that I’d have found it earlier.

Bonus: printing stack traces
Python’s stack traces in exceptions are pretty useful. It used to be difficult to get the current stack in Python, involving raising and catching an exception. Now the traceback module has traceback.print_stack() and traceback.extract_stack() methods.

Python’s collections.defaultdict

Today I again came across code that I was able to make simpler, clearer and safer using collections.defaultdict. I keep coming across experienced Python programmers that don’t know about it. Perhaps it’s time to spread the good word.

The defaultdict type is a dict subclass that takes a factory function to supply default values for keys that haven’t been set yet. For example

from collections import defaultdict
frequency = defaultdict(lambda:0)
for c in 'the quick brown fox jumps over the lazy dog':
  frequency[c] = frequency[c] + 1

Will count the frequency of characters in a string.

I often use defaultdict for dicts of dicts (defaultdict(dict)) and dicts of lists (defaultdict(list)).

defaultdict replaces some pretty simple code, for example the above code could be written:

frequency = dict()
for c in 'the quick brown fox jumps over the lazy dog':
  if c in dict:
    frequency[c] = frequency[c] + 1
  else:
    frequency[c] = 1

but I find using defaultdict is not just shorter but also much clearer.

The other classes in the collections class, especially OrderedDict and Counter (which is an implementation of the pattern I just implemented here on top of defaultdict) seem useful, but I’ve never found myself actually using them, whereas defaultdict is a common part of my repertoire these days.

Updating software on your Mac in ten easy steps…

Launch your application, oh look, an update! Clicking “Update” takes you to the Mac App Store web site.

Click “View in Mac App Store” since apparently I’m not doing that yet, but wait!

Tell my browser that it’s okay to do what I just told it to do.

We’re launched into the Mac App Store app, so we need to click the grey on grey “Updates” button / tab / thing…

And click “Update all” or just “Update”.

Sign into my Apple account for some reason.

Oh we need to quit the app. Command-Tab…

Quit the app.

Back to the Mac App Store app again.

It’s updated and I can launch it again.

Ten only marginally confusing steps!

At least they got the gradients, drop shadows, rounded corners and noisy backgrounds right.

Scripting Google Voice in Python

In the interest of getting some of the fragments of code I’ve written off my hard disk and out where someone might find them useful I’ve decided to start dumping them into git repos with some very minimal documentation. Minimal enough that I actually kick them out there.

The first is a simple Python library to access Google Voice’s calling and texting functionality:

% python                  
Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) 
[GCC 4.2.1 (Apple Inc. build 5646)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from googlevoice import *
>>> gv = GoogleVoice('googleaccount', 'googlepassword')
>>> gv.sms('+1415MYNUMBER', 'this is a test')
>>> gv.call('+1415MYNUMBER', '18003569377')

The library depends on BeautifulSoup. It’s based on a bunch of work that I found on the internet. I don’t remember exactly whose techniques I ended up using, but there’s a bunch of example code out there, just not much that was simple to use and in Python.

DIY DDNS

For those of us on cable or DSL who are slightly too cheap to pay for a static IP, dynamic DNS services are really useful. My DD-WRT based router knows how to talk to dynamic DNS providers, so setting it up is really easy.

I’ve tried both DynDNS and No-IP, and while they work quite well they’re kind of annoying. They really want me to sign up for a premium service, after all that’s how they make money. As a result I need to periodically visit web pages to confirm that I’m using an address or pay a fee. It’s not a big fee, but I’m already paying someone, DreamHost to host DNS for me, and they’ve got an API

So I threw together a little script that implements the DynDNS API and modifies your own DNS zones using the DreamHost API. You can get it from here:
https://github.com/ianloic/dreamhost-ddns

The setup instructions are included in the README. Hopefully they’re pretty self-evident, but they are written from the perspective of someone who ran their own DNS servers (primary and secondary) for ten years.

Ikea obeys local labor laws, how outrageous

The LA Times wrote an article that was later picked up by a bunch of blogs about an Ikea factory in Virginia that pays workers minimum wage, gives them minimal vacation and tries to prevent them unionizing.

Laborers in Swedwood plants in Sweden produce bookcases and tables similar to those manufactured in Danville. The big difference is that the Europeans enjoy a minimum wage of about $19 an hour and a government-mandated five weeks of paid vacation. Full-time employees in Danville start at $8 an hour with 12 vacation days — eight of them on dates determined by the company.

I find it somewhere between sad and funny that instead of arguing for improvements in US labor laws the LA Times and the usual left-libertarian blogs complain about a company maximizing profit within the legal constraints imposed by the society. If we want better working conditions we need to make it part of the political discourse, not just whine about companies following the law.

Donna Dubinsky struggled to get individual health insurance (NYTimes)

The new health care reform legislation is not perfect. Nothing that complex could be. But I have no doubt that the system is broken and reform is absolutely essential. If we are not going to have universal coverage but are going to rely on employer plans, then we must offer individuals, self-employed people and small businesses a place to purchase insurance at a reasonable price.

via Money Won’t Buy You Health Insurance – NYTimes.com.

This is ultimately my big problem with the healthcare situation in the US. I’m sorry that poor people don’t have access to healthcare, but they don’t have access to healthcare in much of the world. The fact that successful, wealthy people don’t have access to affordable healthcare is ridiculous and unusual.

Looking for a present for your Valentine?

This item is one of the more disturbing objects in Henry Wellcome’s collection. A ‘Scold’s bridle’ is a fearsome looking mask which fits tightly on to the head. A scold was defined as a “rude, clamorous woman”. The bridle was used as a punishment for women considered to be spending too much time gossiping or quarrelling. Time spent in the bridle was normally allocated as a punishment by a local magistrate. The custom developed in Britain in the 1500s, and spread to some other European countries, including Germany. When wearing the mask it was impossible to speak. This example has a bell on top to draw even more attention to the wearer, increasing their humiliation. It was used until the early 1800s as a punishment in workhouses.

via Scold’s bridle, Germany, 1550-1800.