« | » Main « | »

Hapland 3

Wednesday 29 March 2006

Hapland 3 is out. I no longer have the patience for these sort of mystery puzzle games, but I remember being in their grips for hours at a time. I like seeing new ones with a sort of nostalgia.

I hate filling out forms

Wednesday 29 March 2006

I've been asked to fill out a Statement of Health form for a life insurance benefit. I hate filling out forms. On the semi-cool side, it's a PDF form, so Acrobat lets me fill in the fields, and then can print the result. On the extra-annoying side, Acrobat is so proud of this feature, it puts up an alert explaining it to me about once a minute, even after I've already filled out part of the form. Also, there's no way to save the work I've put into the form other than to print it.

The worst part about forms, though, is that they are the quintissential boiling down of a person to a series of pre-categorized factoids. Some, like the one I'm filling out, seem to imply a judgement as well:

To prevent delays answer each question and give full details to "yes" answers.

[ ] yes [ ] no: In the past 5 years, has any person on whom coverage is requested had surgery, been hospitalized or consulted with a doctor, had blood or other diagnostic tests (other than for HIV antibody), or been advised to receive medical treatment?

Excuse me? Have I consulted with a doctor in the past 5 years, and if so, please give full details? I would think they'd want full details if I hadn't consulted with a doctor at any time in the past 5 years.

No sane person would ask this question this way, but the efficiencies demanded by modern bureaucracies seem to require scrambling human interactions and turning them into these sorts of robotic inquisitions.

The adventures of scaling

Tuesday 28 March 2006

A detailed and fascinating multi-phase account of how to make a web site scale up: The Adventures of Scaling. The site in question is written in Ruby on Rails, though very little is specific to that framework. There's much more about the other web infrastructure surrounding Rails: proxy frontends, server topology, database replication, caching strategies, and so on. If you're building a dynamically generated web site that you'd like to make serve tons of pages per day, this is well worth a read.

Migrating interest

Sunday 26 March 2006

One of the great things about having a site like this is that I can post small pieces of code that others might find useful. I hear from users of the code, asking questions or providing patches. It's open source writ small, and I like it. It provides a nice guild of craftsmen feel to sharing code.

The downside to this style of working is that my interests change over time, and so I may effectively abandon a piece of code I've posted. I don't intend to, but the time since the last revision gets longer and longer, and my familiarity with its details gets staler and staler. As time goes on, it gets harder and harder to get back to it.

I have a To Do folder in my email. I put emails there that I intend to act on. This weekend, I noticed that there are five emails there about id3reader, my Python module for reading ID3 tags in MP3 files. Four are providing patches or test cases, one is asking a question (that is in fact answered by one of the other four!).

I sat down to deal with those five emails, but I cannot. Writing a good module is hard work. It requires thought about how to organize data, it requires diligence in dealing with the unfortunate gaps in compliance in real world data. In short, it requires passion. I don't have passion for id3reader right now. From this vantage point, I guess I won't ever again, certainly not soon enough to do it justice.

I am hereby making it formal: I am retiring id3reader. I am not going to be updating it any more.

To those who took the time to write to me about it, I'm sorry. Perhaps one of you will take it over.

How not to run an ad service

Thursday 23 March 2006

Boing-boing is reporting that Yahoo's text ad service has a strange rule in their Terms of Service: You can't show the ads to people outside the US. When questioned, live reps report that this is indeed true, but they offer no technical help how to meet the terms, though one suggestion was simply not to show your pages to people outside the US. How lame. Maybe Yahoo needs to be reminded that the first two w's in www stand for World-Wide?

Why would anyone sign up for Yahoo text ads with this bizarre restriction hanging over them? And why wouldn't Yahoo get one of their script guys to whip up some examples of how you could possibly do it? Why have the limitation in the first place? It makes my head spin...

Lost Rhapsody

Thursday 23 March 2006

Workplaces have a shared culture. There are movies or TV shows that are the norm among co-workers. For example, I started watching The Simpsons because of how often it came up at Blue Ripple. At Kubi, the younger engineers convinced me to see Office Space.

At the new place, the buzz is about Lost. The problem is, you can't just drop into the middle of this show, because it so serial in nature, and full of old mysteries revealed, and new mysteries unfurled. So I'm hopelessly behind, and I don't see how to catch up.

At least I didn't until this handy synopsis came along: Lost Rhapsody. The guys in the office didn't tell me how funny this show is!

Entrepreneurial proverbs

Saturday 18 March 2006

Marc Hedlund's Entrepreneurial Proverbs are great. I don't know if they are all true, because some have to do with phases of startups I'm not familiar with (investor pitches, for example). But for the ones I am familiar with, he's right on the money, for example:

  • Build the simplest thing possible
  • Solve problems, not potential problems
  • Test everything with real people

These are the kind of mantras that should be tattooed on the backs of hands.

New idioms for old

Saturday 18 March 2006

I was spelunking through the Django source, and noticed two odd idioms (comment mine):

# Apply a function to every item in a list:
tables = [quote_only_if_word(t) for t in tables]

# Make a list of n None's:
l = [None for _ in range(n)]

Both of these use list comprehensions to accomplish jobs that could have been done with older Python facilities:

# Apply a function to every item in a list:
tables = map(quote_only_if_word, tables)

# Make a list of n None's:
l = [None] * n

I'm not saying they should have been done the older way. It's interesting to see how powerful list comprehensions are that they can displace other language features. I think in this case the new way is clearer for the first statement, and the old way is clearer for the second.

But for a new Python coder, list comprehensions are one tool to understand, compared to the finer-edged but more narrowly-applicable map. So I expect to see more use of list comprehensions like this, and less use of the classic ways.

Why I got fired from Apple

Thursday 16 March 2006

Not me, I didn't get fired from Apple. Eirik Ott, also known as Big Poppa E, got fired from Apple. He's a slam poet, and he has a video explaining (and demonstrating) why: Why I Got Fired From Apple. It's a funny performance, and a funny story.

Seems to me that Apple acted foolishly. The poem was private to Apple until they fired him, and now it is becoming very public.

BTW: Anyone know why Google Video uses enormous negative numbers for their ids?

Baseball's best burger?

Thursday 16 March 2006

I can't imagine eating this thing: Baseball's Best Burger is an unexceptional bacon cheeseburger, except that it is served on a Krispy Kreme doughnut instead of a bun. In addition to the caloric excess, doesn't the sweet doughnut clash with the burger? If this appeared in a Simpsons episode, we'd laugh at the absurdity of it. Never have I been more proud of our rich American culinary heritage!

Modifying library code

Tuesday 14 March 2006

One of the joys of developing software these days is being able to build on top of high-quality libraries. Finding just the right package to solve one of your problems can remove a huge burden from your development shoulders.

Unfortunately, sometimes you experience the disappointment of realizing your beloved library has a flaw. A bug, a missing function, whatever. Then you have to try to fix it. If you don't have the source, forget it, you have to work around it. But if you do have the source, do yourself a favor: before modifying the code, put in some protection to make sure your product really is using the modified source.

The problem with modifying library code is that you shift from using the library as shipped to using your modified version, and subtle changes is build or deploy environments can switch you between the two without even knowing it. For example, modified include files have to be found in a product tree before searching the standard include directories. So the first modification to the library should be to mark it as your modified version, and your product code should assert that it is using the modified library.

For example, in C++, in one of the headers, add a macro definition:

// ReportGeneratorLib.h header file

#define INITECH_REPORTGEN_LIB 1

//.. blah blah rest of the header ..

Then in your code where you include the library, check that you have the right version:

// Initech TPS Report system

#include <ReportGeneratorLib.h>

#ifndef INITECH_REPORTGEN_LIB
#error We need the Initech modification to ReportGeneratorLib.h
#endif

// .. rest of product code ..

This way, if a build machine's configuration changes, or a new devloper doesn't set up his enviroment properly, a very visible error message will appear, rather than subtle bugs manifesting themselves.

The same technique can be used in Python. Mark the library file:

# ReportGeneratorLib.py

IniTechReportGenLib = 1  # Mark our customizations

and then assert in the product code:

# Initect TPS Report system

import ReportGeneratorLib

assert ReportGeneratorLib.IniTechReportGenLib == 1

# .. rest of product code ..

It's a very simple technique, but can save headaches later, after you've long forgotten about having made the changes to the libraries.

Riven and Cone birthday cakes

Sunday 12 March 2006

For Max's 14th birthday, we made two cakes, one on the day itself, and one for his party a few days later. What can I say? We like making cakes.

The first was Riven-themed, but made in a hurry, so it was nowhere near as complex as last year's Myst Island cake.

Riven birthday cake

For those not familiar with Riven, here are two screenshots for reference, lifted from the comprehensive Riven Help and Graphics:

Riven dome screenshotRiven stone circle screenshot

The "New Age" reference is a pun, since Myst and its ilk are separated into Ages. The symbol is the D'ni numeral 14.

For the second cake, Max requested one on the theme of traffic cones. Yes, traffic cones. In the Uru game, areas of the D'ni city were cordoned off with traffic cones to indicate areas that weren't fully restored. So Max has become something of a traffic cone fan.

We considered creating a cake in the shape of a single 3D traffic cone, but decided that it was too bulky and unusual a shape to make work. A flat triangular cake decorated like a traffic cone seemed a little too straightforward. Then we hit upon the idea of having the cake itself be only partially completed, with traffic cones to indicate its Under Construction state:

Cake under construction

Ben helped out with the Lego figures, so we all enjoyed building it. The cones are ice cream cone tips, frosted orange. Max declared it very cool, so the customer was satisfied.

Producing poo

Saturday 11 March 2006

Danc at Lost Garden has a longish post boringly titled Software Development's Evolution towards Product Design. It's about the need for recognizing all the roles in product design (business, design, interaction, and development). His point is humorously illustrated with examples of the old way of doing things without all these roles properly represented, and the result is poo, lovingly illustrated.

I don't know whether he is right; I know I like his drawings.

Bliss Diss

Saturday 11 March 2006

I've been listening to Penn Jillette Radio as a podcast, and enjoying it a great deal. He's funny and articulate, and I appreciate his political opinions, even when I don't quite agree with them. He's had interesting guests (who knew that Gilbert Gottfried did expert impersonations?). And he talks about show biz, including clowns, magic, and juggling occasionally.

But I was surprised by his reaction to Chris Bliss, the juggler who juggled to the finale of Abbey Road. Penn didn't like the routine, asserting that the juggling skills were mediocre. I have two problems with this: First, Chris Bliss could have looked smoother during his routine (he grimaced a lot), and there are certainly more difficult routines, but he's hardly a mediocre juggler. Second, Penn and Teller to me have done a good job showing that presentation is almost more important than the technical challenge of the act. They've made a specialty of doing classic magic tricks in unusual ways. So Penn seemed a bit hypocritical for criticizing Bliss's technical abilities.

Penn claimed on the radio that Jason Garfield could do the same routine, but with 5 balls. Jason Garfield has incredible juggling skills, so I didn't doubt that he could do it, and he's also an angry competitive guy, so I didn't doubt that he would do it.

And sure enough, Garfield has done it. He's written a sputtering screed about Bliss's routine, called Bliss Diss, and included a video of his 5-ball routine to the same audio track. It's a remarkable routine, with many incredibly difficult tricks, including 5 balls in one hand, double back crosses, 5 over the head, pirouttes, and so on. Garfield is one of only a handful of jugglers technically accomplished enough to perform it, maybe the only one.

But, in the end (no pun intended), Bliss's is the better art. I'd like Bliss's routine to be more polished, but Garfield's is too complicated for audiences to relate to. Garfield berates Bliss for getting applause for a simple 3-ball cascade, but the genius of Bliss's routine is the way a simple trick can be fit into the routine at just the right spot to be appreciated, just as the Beatles put a simple piano chord into the song in a way that made it a masterpiece.

Jason Garfield clearly understands juggling, I'm not sure he understands art.

MoMB

Friday 10 March 2006

The Museum of Modern Betas is a sparely-designed list of over 800 web sites in beta. I often wonder what Beta even means these days, given how many years Google Groups (for example) has been in beta. Of course, I can't exactly throw stones these days...

In a similar let's-poke-fun-at-the-latest-crop-of-web-companies vein, here's The Logos of Web 2.0.

Pixoh

Thursday 9 March 2006

Pixoh is a charming little site. It's for editing photos. You upload a photo, or point it at a URL, then you can crop, resize, and rotate the image. That's all. When you're done editing, you can download the photo, or save it to Flickr.

It's nicely done, but does very little. It doesn't even let you manage more than one photo at a time. They are accepting nominations for new features, using a sub-reddit, which I hadn't seen before. It could be an interesting model for applications development. Create just one feature, and then build on it.

Everything in the same minute

Sunday 5 March 2006

The other day, I looked at a problem where we were displaying a list of things with dates and times. Although the times should have been spread out (it was an activity log), instead there would be many entries all at the same time:

Thing 1: 3/4/06 12:03
Thing 2: 3/4/06 12:03
Thing 3: 3/4/06 12:03

This looked familiar, and it became clearer when we looked at a larger sampling:

Thing 1: 3/4/06 12:03
Thing 2: 3/4/06 12:03
Thing 3: 3/4/06 12:03
Thing 4: 3/4/06 1:03
Thing 5: 3/4/06 2:03
Thing 6: 3/4/06 2:03
Thing 7: 3/4/06 3:03

Everything always happened at 3 minutes after the hour? That definitely wasn't right. Then it hit me: I'd seen this exact bug at my last job. The times are being recorded properly, but displayed wrong, through a simple typo.

Date and time formatting is often done with a formatting string. The components of the date and time are indicated with prescribed letters: Y means a four-digit year, H means the hour in a 12-hour clock, and so on. The letters are chosen to be mnemonic, but of course there's only so far you can take that without running out of letters, or colliding on mnemonics.

The problem at both workplaces was that instead of displaying minutes, we were displaying the month.

At the old job, we were using the .NET framework, so the date format string used M (numeric month with no leading zero) where it should have used m (minutes with no leading zero). The latest manifestation is in the Django framework, so the date format string used m (numeric month) where it should have used i (minutes).

At least this time I recognized it sooner.

Digi-Comp

Sunday 5 March 2006

Minds-On Toys is remaking the Digi-Comp. If you are too young to know it, it was a mechanical plastic "computer" that roughly amounted to six flip-flops. I owned one in the early '70s, and loved it. It couldn't do much, but it really did work. You could program it to count in binary, or play a simple numeric game.

It's hard to imagine now how a computer-destined kid felt then. There were computers in the world, I knew they were out there. Heck, my mother programmed them, so I was closer than most kids. But it was next to impossible to get my hands on one, and frankly, if I did, I wouldn't have known what to do with it.

So the Digi-Comp seemed very cool. It actually did binary stuff automatically. And because it was mechanical, you could study its action to try to understand it (though that was less applicable to electronic computers).

The one downside to the whole thing was the little plastic tubes that were placed on pegs in particular patterns to program it. I was given the toy at my aunt's house, and placed the tubes into a handy receptacle, an empty ashtray. My aunt, in her distracted rush to keep the house clean with so many visitors, thought that it was an ash-tray full of cigarette butts, and threw them all into the fireplace. Luckily, there was no fire burning, and we realized what had happened before one was lit. But we did have to fish a couple of dozen white plastic tubes out of the fireplace ashes.

Many features of the product are unavailable

Friday 3 March 2006

I have a copy of Microsoft Office pre-installed on my laptop, but it is a trial version that expired a few days ago. When I launch a .doc file, I get a box that says (in part),

Your copy of Microsoft Office Small Business Edition 2003 trial has expired. In this state, many features of the product are unavailable until you convert to the full product.

To convert the product, blah blah.

If you do not want to convert to the full product, you may use the Add or Remove Programs Control Panel to remove the software from your computer.

Click Cancel if you do not want to convert at this time.

Seems to me that "many features are unavailable" is kind of an understatement. The one feature left available is uninstall!

Actually, it's just a misleading dialog. If you click Cancel, Word opens the document.

Jason McElwain

Thursday 2 March 2006

Jason McElwain is an autistic teenager who really loves basketball. For four years, he helped manage the team at his high school. He tried out for the team each year, but his skills weren't up to team standards. On the last game of his last year, he was put in for the last four minutes, as a tribute to his dedication. Everyone hoped he would at least score one basket.

He sank six three-pointers.

It's a truly amazing video. I wondered (as my wife Susan did) how his abilities on court could vary so greatly from everyone's expectations of him. There are comments on Susan's post from people who know Jason, though they can't explain it either.

Thanks to all the people who sent the link.

An extraordinary act of public obedience

Wednesday 1 March 2006

A group decided to test unenforced speed limit laws by lining up four cars across a four-lane interstate and driving the speed limit in synch. They captured the event and their reactions on video: A meditation on the speed limit. I've long wondered what would happen if you tried this. It turns out that for the most part, you get a long line of cars behind you going 55, but you also get a few outliers who are willing to damage automobiles in their desperate attempts to go faster.

The problem with checkboxes

Wednesday 1 March 2006

Checkboxes are a difficult UI element to use properly. The problem is they are asking a yes/no question, but you can only see one of the choices. This morning I got a perfect example.

My son Max is trying to write an installer for a Windows program (sniff, they grow up so fast!). I pointed him at Inno Setup because I had used it in the past and found it to be straightforward, and it comes with a helpful wizard. He came back and said, "That wizard is no good, it just makes an empty install file!"

I tried the wizard, and saw the problem. At the bottom of the first page is a checkbox labeled,

Create a new empty script file.

Max had checked it, because he thought it meant, "I want to make a new installer." If instead, there had been two radio buttons labeled,

  • I want to start with an empty install script and fill it in myself
  • I want the wizard to ask questions, and create a finished script for me

he would have made the proper choice. He didn't know what the alternative to the checkbox was. The key word in the checkbox was "empty", but Max interpreted it as "new", or maybe even "script file". Explicitly listing the two alternatives makes the choice very clear.

BTW: This is the UI equivalent of Booleans suck.

« | » Main « | »