Thursday, April 09, 2009 
iframe

New post to the Cozi Tech Blog: Iframes: thinking outside the box.

Using an iframe to host some content turned out to be a big pain, so I came up with a different approach.

posted on Thursday, April 09, 2009 7:02:09 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Wednesday, April 08, 2009 
James Joyce's Ulysses

As I mentioned the other night, I introduced two narrators into the chapter of Ulysses that we're reading in June.

I'd say from the rehearsal tonight that the additions are successful, that they clarify the text for the listener, without being intrusive. I expect that I'll have to produce a third draft of the script in a few weeks, but I think the next round of changes will be minor. The second draft required hundreds of small changes.

We gained three new readers tonight. There are plenty of parts to go around, so it's all to the good. We had great difficulty initially last year in getting enough readers from the old guard, until we recruited several new readers.

posted on Wednesday, April 08, 2009 7:18:47 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Tuesday, April 07, 2009 
Marriage in Vermont

On Friday, the Iowa Supreme Court struck down their state's gay marriage ban. Today, the Vermont Legislature legalized gay marriage.

It's been a great week for fairness. We still have a long way to go: 29 states have constitutional amendments banning gay marriage.

I'm sure the right wing are beating the fund-raising drums for all they're worth. We can expect more Proposition 8-style backlashes, I'm afraid.

But the news still made my day.

posted on Wednesday, April 08, 2009 6:57:05 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Monday, April 06, 2009 
James Joyce

Moments ago, I completed the second draft of the Circe Part I script for this year's Ulysses reading.

The chapter is couched in the form of a play, making it relatively straightforward to convert to a staged reading. There are, however, huge numbers of “stage directions”, often ironic, generally unactable: A vast, detailed procession in Bloom's honor; Bloom burning at the stake; camels offering mangoes to Molly; and much, much more.

In addition, there are over one hundred characters, most of whom have a line or two, then disappear. They need to be introduced somehow.

So I added two narrators to handle all of this. They steer the reading along, adding much-needed context to aid the audience who won't be nearly as familiar with the text as we are.

Next rehearsal is Wednesday, when I'll get to hear the changed text for the first time. I'm confident that most of the changes that I made will work, but I'll probably need to produce another draft in a few weeks.

posted on Monday, April 06, 2009 8:07:21 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Sunday, April 05, 2009 
Grill Brush

In Seattle, it is said that moss grows on the north side of the rain. To be sure, moss thrives in the shadier parts of our yard.

On a cold, dry February day, I rented a pressure washer with the intention of scouring the moss from the ground and the flaking paint from the garage walls. Although it was quite effective at removing moss, it made a godawful mess. There were muddy flecks of moss everywhere. Against the flaking paint, it made little impression and I still have to deal with that. I had dealt with perhaps a third of the moss when the pressure washer died. I got a partial refund, but didn't feel like renting another one.

The following weekend, I scraped up more moss with a shovel. Not messy, but not wholly effective either, leaving small, low patches of moss that are starting to return.

Today, I took on the exterior basement stairs. They are always in shade and the moss carpeted the steps. I used an old grill brush that had grown too foul with grease to be used on the grill. It did an excellent job; I've never seen those steps look so clean. The scraper peeled most of the moss off the ground and the brass bristles ripped up the roots with ease.

Bloody hard work, though.

posted on Monday, April 06, 2009 4:01:41 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Saturday, April 04, 2009 
Barbecue

It's been a long, dreary winter in Seattle. After a horrible, wet Saturday, last Sunday was glorious, the first nice day in weeks. Then the cold and rain came back. It snowed on April 1st, for Pete's sake.

And now we have another lovely weekend, with promised highs in the high Sixties tomorrow. I did some yard work today and cleaned the grill and outdoor furniture. We've invited a handful of friends over for dinner tomorrow night.

posted on Sunday, April 05, 2009 6:52:50 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Friday, April 03, 2009 
Iowa Ruling

I am greatly heartened by today's news of Iowa's Supreme Court unanimously striking down the state's gay marriage ban. The passage of Proposition 8 in California was a setback. The Iowa Court made a strong ruling, gutting the arguments against same-sex marriage.

It's hard to believe now that interracial marriage was illegal in many states until 1967. President Obama's parents could not have married in those states. We look back at that now with bemusement and a little horror. The opposition, then as now, was led by cultural conservatives, making religious arguments.

Someday soon, we'll look back at the gay marriage debate with the same bemusement and wonder what all the fuss was about.

posted on Saturday, April 04, 2009 6:59:14 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Thursday, April 02, 2009 
ColorSchemeDesigner.com

About three weeks ago, I answered a question on StackOverflow about generating the most readable color of text on a colored background.

I suggested flipping the top bit of each component, (r ^ 0x80, g ^ 0x80, b ^ 0x80). This has the same effect as adding 128 if the component is less than 128, and subtracting 128 otherwise.

Another way to think about it is to imagine the 256x256x256 color cube. Inside that cube, erect another cube half as wide. One corner is at your original color and the diagonally opposite corner is the one computed above.

The questioner liked my answer the best, but I decided to experiment further. I wrote some JavaScript to compute that color. As you can see in the table of 549 colors below, it works well most of the time, but it's not perfect.

Someone else suggested an earlier SO question on good-looking font colors. Looking at that thread, I decided to try inverting the HSL value to (h + 180, s, l + (l < 0.5 ? 0.5 : -0.5)). That works well too. Generally, it yields different colors than my first approach. It looks like one of the two always contrasts well.

I found that the most effective approach was to compute the gray-level intensity of the original color, (0.30*r + 0.59*g + 0.11*b). If it was dark, use white; otherwise, black.

Really, though, unless you have a requirement to work with arbitrary colors, you should pick your color scheme carefully. I found a really nice site this afternoon, ColorSchemeDesigner.com

Here's the source of my colortable.

posted on Thursday, April 02, 2009 7:13:06 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [1]
Wednesday, April 01, 2009 
Allergies

I love Spring. The winter recedes, the weather grows warmer, the young plants appear, the dormant trees bloom, and all is right with the world.

I dread Spring. My nose itches, it runs, it blocks up, it explodes.

This year, my eyes itch too. A lot. It's really, um, irritating.

posted on Wednesday, April 01, 2009 7:39:19 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Tuesday, March 31, 2009 
House from Southwest Corner

Our neighborhood was built in spurts. The brick Tudors, like ours, were built in the 1930s. The houses adjoining mine were built in the years after World War II.

There's a house for sale a few doors down that's very like ours. We snooped around on Sunday during the open house.

Our house was built in 1931; the other, the year before. Ours is slightly deeper, but the floor plans are very similar. Theirs has no eyecatching yellow brick trim. Our kitchen was remodeled in the sixties, taking over part of the next room. Theirs never was and it's tiny. Our basement is half finished and it had a bathroom added in the seventies. Their basement is unfinished. Our dormers upstairs are walk-in closets; their dormers are unfinished attic. Our living room and dining room windows were replaced with picture windows, while they still have leaded panes.

Dark wood trim predominates in their house, the electrical outlets and light switches look like the originals, and the paintwork was shabby. In short, it had changed little in the eight decades since it was built.

Quite an eerie experience, seeing our house much as it started out.

posted on Wednesday, April 01, 2009 6:59:51 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Monday, March 30, 2009 
Big Ben

The Cozi Tech Blog needed some love, so I wrote a post on augmenting Python's strftime.

posted on Tuesday, March 31, 2009 6:17:58 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Sunday, March 29, 2009 
Black Dossier
Title: Black Dossier: The League of Extraordinary Gentlemen, Volume 3
Author: Alan Moore, Kevin O'Neill
Rating: 3.5 stars out of 5
Publisher: America's Best Comics
Copyright: 2007
Keywords: graphic novel
Reading period: 28 March, 2009

England, 1958: an alternate universe where famous fictional characters really lived and the regime of Big Brother has just come to an end. Sixty years ago, the British Crown gathered together the Murray Group, extraordinary adventurers charged with sensitive missions. The remnants of the group fled England in World War II. Now they've come back to steal their dossier from MI-5, a dossier that could lead the Government back to them, a dossier that details the exploits of earlier groups over the last 300 years.

LXG3 pulls in everything, from Gulliver's Travels to James Bond, Orlando to Fanny Hill, Prospero to Toyland, Dan Dare to Billy Bunter, and Bertie Wooster and Jeeves battling Cthulhu. It's way over the top. Mostly it's fun.

posted on Monday, March 30, 2009 5:34:35 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Saturday, March 28, 2009 
By Myself
Title: By Myself
Author: Lauren Bacall
Rating: 4.5 stars out of 5
Publisher: Knopf
Copyright: 1978
Pages: 378
Keywords: autobiography, movies
Reading period: 10–28 March, 2009

Betty Bacal is an only child, abandoned by her father, raised by her Rumanian Jewish mother in New York. Stagestruck from an early age, she takes acting classes for years but gets little stage work. Modeling work is a fallback. A cover shot for Harper's Bazaar leads Howard Hawks to bring her out to Hollywood. Within months, Hawks' protogée, now Lauren Bacall, is the lead in “To Have or Have Not” and falling in love with her costar, Humphrey Bogart. Bogie is 45 to her 20, but it doesn't matter. He's married too; that doesn't matter either. They marry, of course, and have a dozen great years together until Bogie's death of cancer in ’57. She's devastated but she has two young children. On the rebound, she takes up with Frank Sinatra. It's not right for either of them and Sinatra dumps her. She spends the Sixties married to Jason Robards. Like Bogie, he's a drinker and that marriage falls apart, leaving her with a son. Her movie and theatre career has been hit or miss for years, but revives in the Seventies with a long-running stage hit in Applause (the musical version of All About Eve).

Bacall writes frankly about her life and shortcomings, looking back with hard-earned wisdom from middle age. She spends half of her girlhood at a high emotional pitch. When she plunges into something, it's total commitment; no holding back, for better or worse. Her early screen persona was as a knowing sexpot; in reality, she was unsure and inexperienced. The “Look”, her trademark upward tilting look with her chin pressed against her chest, was born of the need to still her nervous shaking.

She tells a good story, pulling the reader along. She drops many big names, having moved in high-powered circles all her adult life. The Hollywood elite of the 40s and 50s are there. Katie Hepburn becomes a close friend after The African Queen. She was close to Adlai Stevenson when he ran for President in 1952. Bobby Kennedy was a friend. The book becomes most affecting when she writes of the death of Bogie and of her beloved mother in 1969, of those last, lingering months of denial and her wrenching pain afterwards.

Highly recommended.

posted on Saturday, March 28, 2009 8:43:14 PM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Friday, March 27, 2009 
Toastmasters Competition

I've been to a few Toastmasters competitions in the past. Tonight was the first time that I helped out at one, as one of the timers. It was the combined Area 35 and 36 competition.

A typical Toastmasters competition has two parts, a speech competition and an evaluation competition. In the speech competition, the competitors give a prepared speech on a topic of their own choosing. Some speech competitions are humorous; tonight's wasn't. In the evaluation competition, the invited speaker gives a speech heard by all the competitors. They are taken out of the room, then one at a time, they come back in and evaluate that speech.

The speech competition is always fun. You get to hear several good speeches. I heard speeches tonight about a teenage boxing experience, watching a mother's peaceful death in a hospice, our collective obsession with "better", and choosing a high school for a son.

In the evaluation competition, it's interesting to hear different people's take on the same speech.

posted on Saturday, March 28, 2009 6:58:19 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Thursday, March 26, 2009 
Seattle, early evening

For various reasons, I hadn't cycled to work in about three weeks, just before the clock went forward.

It was very pleasant to cycle home in broad daylight for a change. Very pleasant.

posted on Friday, March 27, 2009 2:05:18 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Wednesday, March 25, 2009 
Ack!

On a StackOverflow question about favorite Vim plugins, I learned about Ack, a replacement for grep that's smarter about searching source trees.

Ack is written in Perl. The built-in :vimgrep is rather slow. It seems to have some Vim-specific overhead, such as creating swap files and executing BufRead autocmds. Ack is noticeably faster, though somewhat slower than GNU grep.

Which would you rather type to search a tree, ignoring the .svn and .git subtrees?

$ ack -i -l foobar
$ grep --exclude='*.svn*' --exclude='*.git*' -i -l -r foobar .

The ack takes 6 seconds to search 4500 files, while the grep completes in 2. This does not count the time that I spent trying to figure out the correct syntax and argument quoting for --exclude. The help says both --regexp=PATTERN and --exclude=PATTERN, but the latter is a glob (file wildcard pattern).

On Windows, I wrapped ack with pl2bat.

posted on Wednesday, March 25, 2009 8:40:10 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Tuesday, March 24, 2009 
Refinancing

When we bought our house in 2000, our interest rate was about 8.5% on a 30-year loan. A couple of years later, we refinanced it down to 6.875%, which reduced our monthly payments by several hundred dollars.

Today, we signed the paperwork to refinance it again, down to 4.75% over 20 years. That drops our monthly payment by another $300, which is most welcome, as Emma's unemployed.

All of these are fixed-rate mortgages. We're really not fans of adjustable-rate mortgages: too many horror stories about people starting out a low rate and not being able to cope when the rates go up.

We went through the same guy each time, Sanjay Pitroda of MetLife Home Loans in Kirkland.

posted on Wednesday, March 25, 2009 3:52:40 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Monday, March 23, 2009 
Exuberant Ctags

Exuberant Ctags is an essential complement to Vim: it generates an index of symbol names (tags) for a set of source files. In Vim, just place the cursor on a function name and type C-] to go to its definition.

Ctags works well for most of the languages that I deal with, but falls down badly on modern JavaScript. Its built-in parser simply doesn't handle declarations like these:

Sizzle.selectors.filters.animated = function(elem) { // ...
ajaxSetup: function( settings ) {

I came across Unbad's workaround earlier tonight. His code didn't work for me, so I hacked on it until it did:

--langdef=js
--langmap=js:.js
--regex-js=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\{/\1/,object/
--regex-js=/([A-Za-z0-9._$()]+)[ \t]*[:=][ \t]*function[ \t]*\(/\1/,function/
--regex-js=/function[ \t]+([A-Za-z0-9._$]+)[ \t]*\(([^)])\)/\1/,function/
--regex-js=/([A-Za-z0-9._$]+)[ \t]*[:=][ \t]*\[/\1/,array/
--regex-js=/([^= ]+)[ \t]*=[ \t]*[^"]'[^']*/\1/,string/
--regex-js=/([^= ]+)[ \t]*=[ \t]*[^']"[^"]*/\1/,string/

Simply add the above to ~/.ctags or $HOME/ctags.cnf.

posted on Monday, March 23, 2009 7:08:18 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Sunday, March 22, 2009 
No Country for Old Men
Title: No Country for Old Men
Author: Cormac McCarthy
Rating: 4.5 stars out of 5
Publisher: Picador
Copyright: 2005
Pages: 309
Keywords: fiction
Reading period: 20–22 March, 2009

Rural Texas, 1980. Llewelyn Moss, out hunting in the middle of nowhere, finds the remains of a drug buy that went wrong: dead bodies, shot-up cars, black tar heroin. And a satchel with two million dollars in cash. Moss takes the money and runs. He knows it's stupid, he knows that people will come after him, and he does it anyway.

Anton Chigurh is the worst of the killers on his trail. Relentless, remorseless, untroubled by conscience, and offended by the wrongness of Moss's act. He and Moss will be locked in a dance of death.

The bodies were found in Sheriff Bell's patch. Ed Tom Bell is near retirement, an old-school lawman at odds with modern life. Bell is slow, deliberate, and perceptive. He wants to catch Moss before Chigurh does.

McCarthy's prose is spare and evocative, as dry as the harsh landscape. These men are laconic, not given to frivolous chitchat.

Highly recommended. I'll have to get around to the Coen Brothers' movie soon.

posted on Monday, March 23, 2009 5:54:00 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Saturday, March 21, 2009 
Irish Rugby Football Union logo

I grew up hating rugby. I spent eleven years at a rugger-bugger school in Dublin. I couldn't stand the game. I was a small, unathletic child with no interest in sports. Rugby, even the modified rugby that they teach seven-year-olds, was violent and unpleasant and involved running around cold, wet fields. I had a big operation on my feet when I was 10 and I parlayed that into an excuse never to play rugby again.

I can't remember when I last watched a rugby match, but it was surely back in the '80s, as I doubt I've seen one over the 20 years that I've been in the States.

So imagine the improbability of my watching rugby today. Truly a historic occasion. But not just for me, but for Ireland too. The Irish team won the Grand Slam for the first time in 61 years.

Some Irish friends invited us over for a big Irish breakfast and to watch the match. To be honest, I was more tempted by the food than the match, but I ended up enjoying the game. It was a close game and a nail-biting finish. It was the first time that Emma had watched rugby and she thought it was more interesting than the slow, staged plays of American Football.

I was also reminded why I had never wanted to play rugby. It is often said that rugby is a hooligan's game played by gentlemen, while soccer is a gentlemen's game played by hooligans, and the former was borne out today. A dangerous, bloody game.

posted on Saturday, March 21, 2009 7:51:56 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Friday, March 20, 2009 
List Comprehension

Python has list comprehensions, syntactic sugar for building lists from an expression.

>>> [2 * i for i in (2, 3, 5, 7, 11)]
[4, 6, 10, 14, 22]

This doesn't work so well when the comprehension expression is itself a list: you end up with a list of lists.

>>> def gen():
...     for l in [['a', 'b'], ['c'], ['d', 'e', 'f']]:
...         yield l
...
>>> [l for l in gen()]
[['a', 'b'], ['c'], ['d', 'e', 'f']]

This is ugly. Here's one way to build a flattened list, but it's less elegant than the comprehension.

>>> x = []
>>> for l in gen():
...     x.extend(l)
...
>>> x
['a', 'b', 'c', 'd', 'e', 'f']

It took me a while to find a readable list comprehension, with a little help from Google. Use sum() on the outer list and prime it with an empty list, []. Python will concatenate the inner lists, producing a flattened list.

>>> sum([l for l in gen()], [])
['a', 'b', 'c', 'd', 'e', 'f']

Alternatively, you can use itertools.chain().

>>> import itertools
>>> list(itertools.chain(*gen()))
['a', 'b', 'c', 'd', 'e', 'f']

That might be slightly more efficient, though I find the sum() to be a little more readable.

>>> import itertools
>>> list(itertools.chain(*gen()))
['a', 'b', 'c', 'd', 'e', 'f']

That might be slightly more efficient, though I find the sum() to be a little more readable.

Edit: I forgot about nested comprehensions

>>> [inner
...     for outer in gen()
...         for inner in outer]
['a', 'b', 'c', 'd', 'e', 'f']

Somewhat cryptic on one line however:

>>> [j for i in gen() for j in i]
['a', 'b', 'c', 'd', 'e', 'f']
posted on Friday, March 20, 2009 7:05:07 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]
Thursday, March 19, 2009 
The Choirboys
Title: The Choirboys
Author: Joseph Wambaugh
Rating: 3.5 stars out of 5
Publisher: Dell
Copyright: 1975
Pages: 387
Keywords: crime, fiction
Reading period: 17–19 March, 2009

Ten LAPD patrolmen congregate regularly in MacArthur Park for “choir practice”: late-night bitchfests, marathon boozing, and group sex with a couple of cocktail waitresses.

LA's finest are not exactly fine specimens of humanity, but then neither are the people they serve, whom they consider little better than the ones they arrest. The choirboys include an idealist, a psychopath, a prankster, and a world-class mooch. They fight and they drink and they argue: everything but discuss the things that really bother them. Wambaugh lampoons the choirboys, but he reserves his full contempt for their supervisors, martinets concerned more with coverups than justice.

There isn't much of a plot. It's more of a series of anecdotes about his characters, sometimes grim, often hilarious, frequently profane.

posted on Friday, March 20, 2009 5:42:28 AM (Pacific Daylight Time, UTC-07:00) 
#    Comments [0]