From The Annals Of Trivial Programming Errors

It was pointed out to me that the alphabetical list of groups on my web site was very short.  It seemed to only list a tenth of the groups I probably had albums from.

Here’s the snippet that constructs an array by reading the directory that contains all the group names:

while ($group = readdir($dir))
  $groups[] = $group;

See the error?  Yeah, I had bought an album from the group 0, and that made that loop terminate when it reached that group name.  (readdir reads in unsorted directory order, so it didn’t terminate immediately, which is why I hadn’t noticed.)

0: The Bobby Tables of bands.

The fix is something like

 while (($group = readdir($dir)) !== false)
   $groups[] = $group;

PHP type coercion is usually convenient, but…

I Am The Product Chooser

I was too poor at the time (1993, I think?)  to buy the limited-edition version of This Rimy River by Vaughan Oliver, but reading the 4AD biography reminded me that I had to buy it.

The regular version is very pretty, and has an overview of Oliver’s design career.  The limited edition is weirder.

The slipcase is, er, traditional enough.  It comes in a velvet-ey slipcase with a bucket on the front.

DSC00755The book itself comes has a plexiglas cover.

DSC00756 DSC00757

So luxurious.

DSC00758

Which brings us to the interiors.  Oliver had his poor interns chop copies of the regular version apart, and then screen-print the hell out of the pages.  They mainly applied two layers — one black (obscuring the original stuff on the pages) and one in copper (one word per page from a poem Oliver’s wife wrote).

So compare: Limited edition version regular.

DSC00760 DSC00761

Limited edition to the left.  The page on the right completely obliterates the original page, while the black print on the left page is somewhat more subtle.

DSC00762 DSC00763

Again, limited edition on the light.  On these two pages the black additional printing is less overwhelming.

Oliver has a great sense of humour.  It’s both a “fuck you” to people who has money to buy these kinds of things (since you need the regular version to actually read it), and it’s also a beautiful object in itself.  <slow clap>

Everything Wrong With “The Golden Age Of Quality TV” In One Quote

From the Mad Men show-runner.

Before The Sopranos, when someone said, Make it deeper, I didn’t know what they meant. Or really, I knew in my gut—but I also knew that it was the one thing that crossed my mind that I wasn’t going to do. To have Peggy come into Don’s office after he’s had the baby and ask for a raise and be rejected, and look at the baby presents, so we know she’s thinking about her own baby that she gave away, and then to have her tell Don, “You have everything and so much of it.” There is something embarrassing about that. A scene that was really just about her getting turned down for a raise became a scene about her whole life. That was the sort of thing I learned from working with David Chase.

To which I’d like to respond, as respectfully as I can:

Fuck off.

Emacs DOM Traversal

I’ve been doing a bit of web scraping with Emacs lately, and I haven’t been totally satisfied with how my dom.el library worked.

But on Friday I was fiddling around with some jQuery stuff, and I noticed how handy it was that jQuery functions that dealt with a single node (like .attr()) could be fed a list of jQuery objects.  Whenever that happened, the function would just work on the first element in the list.

Which is totally what you want when doing web scraping.  You map over some objects, but a lot of the time you want, for instance, the text from the first <a> element underneath a node.

So I rewrote the library, and my scraping code became prettier, I think.

This is the code to scrape the concerts for the “Mir” venue before:

 (defun csid-parse-mir (dom)
   (loop for elem in (dom-by-id dom "program")
        for link = (car (dom-by-name
                         (car (dom-by-class elem "programtittel")) 'a))
        collect (list (csid-parse-month-date
		       (dom-text (car (dom-by-class elem "programtid"))))
                      (dom-attr link :href)
                      (dom-attr link :title))))

And this is the code after:

(defun csid-parse-mir (dom)
  (loop for elem in (dom-by-id dom "program")
        for link = (dom-by-name (dom-by-class elem "programtittel") 'a)
        collect (list (csid-parse-month-date
                       (dom-text (dom-by-class elem "programtid")))
                      (dom-attr link :href)
                      (dom-attr link :title))))

See? All those `car’s are gone. Much more eco-friendly.  Stop climate change!

Things indent so awkwardly when you have to sprinkle short functions all over the place.

Anyway, I have a bike-shedding query.  I’m pretty satisfied with function names like `dom-by-id’ and `dom-by-class’.  They’re pretty self-explanatory.  (Although if somebody has better (i.e. shorter and clearer) names, that’d be good.)

But I dislike `dom-by-name’.  It should really be `dom-by-node-name’, but that’s way too long.  And `dom-by-name’ is just confusing, and clobbers with name attributes, so it has to go.

But what should it be?  `dom-by-node’?  `dom-by-tag’?  `dom-by-type’?  WHAT!?!?