Category Archives: essay

Essays

Eight Python warts

I love Python, but a few things still bug me about it. I’ve bashed on several other technologies; here’s some Python bashing. In no particular order:

Update: This has started a pretty good discussion on Reddit. Many people correctly guessed that I’m using singleton in the mathematical sense, not in the sense of the programming pattern. The comments from Cairnarvon and tghw are particularly worth reading.

Worst website ever

Zzzphone.com. Excessive use of flash. Unsolicited, over-compressed, auto-starting audio (on the specs page; there’s no surer way to get users to leave a site and never come back than automatically assaulting them with unexpected audio when the page loads). Random fonts and sizes, and graphics containing text. Best part: click on the shopping cart link at the bottom of the page (obviously without ordering anything first), and this comes up:

Step 3 of 6? Am I allowed to skip steps like that? Buy another nothing? Can I get a discount on that? (via Max.)

Oh, and in case anyone out there needed reminding that you can design complex, interactive, highly graphical sites in HTML without Flash, check out Shiftn’s Obesity System Influence Diagram.

Bad journalism

Consider the following two quotes from this BusinessWeek article by Susan Berfield. From the first paragraph:

He has Asperger’s syndrome,

On the second page:

Cohen never sought a formal diagnosis

If it’s not clear why this is bad journalism, replace “Asperger’s” with schizophrenia, or Bipolar disorder or with any other psychological or even any physical condition. How can the author of a story about a person living with something like Asperger’s, where the journalist admits that that person has never been diagnosed, be trusted? What other key details in this story come from single sources and make it into print unchallenged and unverified? How many other stories in BusinessWeek suffer from the same sloppy reporting?

When I worked on the bi-weekly underground student newspaper at UC Santa Cruz, our editors and faculty advisors in the journalism department would have flayed us alive for committing such an oversight.

Full disclosure: I also used to work for Bram at BitTorrent, but, unlike Susan Berfield and the BusinessWeek editors, I don’t consider myself qualified to comment on any medical diagnoses.

Helping fix Firefox and adapting to it at the same time

Hank Williams over at Why does everything suck? wonders how to best report an obscure and weird browser bug.  He’s got the right idea: save a static copy of the HTML, JavaScript, and CSS, and then strip out everything unrelated until you have the minimal chunk of code required to duplicate the bug. You can speed this up by making an educated guess at which code is related, and doing a binary search from there. Include the minimal test case with the bug report, and the Firefox (or WebKit) team will love you for finding a test case for such a wacky, rare bug.

I’ve done this a few times for Mosuki, and each time, I discovered a workaround before I got to reporting the bug. Each time, the bug was either the result of a interaction between components I thought were unrelated, or I found some other method of achieving the same result that didn’t trigger the bug. (Of course, it was usually an Internet Explorer bug that I was fixing, so there was no way to report the bugs.)

Rebuild mail-notification to support SSL under Ubuntu/Debian

Because of a four-year-old disagreement on the legal interpretation of the GPL and OpenSSL licenses, Debian is shipping a neutered and useless version of mail-notification without SSL support. Ubuntu hasn’t resolved the issue, so they’re shipping the same broken package too. People arguing about why they can’t fix bugs bores me. So here is a script to download the source packages, and rebuild them with SSL enabled. It even bumps the version number so that the package manager doesn’t try to overwrite your working package with the broken one in the repository. It also keeps track of the (on my system) thirty-seven megabytes of build dependency packages that it installs and removes them once the package is installed.

Continue reading

Announcing: The Periodic Table of the Europeans

Take heed, chemists! The forty-nine countries of Europe have finally been organized in their very own Periodic Table of the Europeans!

I came up with this early in my most recent trip, somewhere in Turkey, and finally got the chance to make it. Read all about it and see a bigger version here, or get it on a poster, or on light and dark t-shirts.

I wish XML were becoming obsolete faster

XML sucks at (almost) everything it’s used for. Google has open-sourced Protocol Buffer, a typed, backwards compatible, compact, binary data-interchange format. Combined with YAML for configuration and data-persistence files that need to be human readable, there’s even less reason to use XML for any data-serialization.

XML, in the form of (x)HTML, seems ok for markup, and the XML-based (x)HTML templating in Genshi is the best templating language I’ve ever used (and I’ve used XSLT, Mako, Mighty, PHP, and a few others). I wonder if the reason that HTML (and XML) templating is so difficult, and templating language code is often so ugly, is because XML is actually a poor solution for markup too. HTML is obviously here to stay, but it would be an interesting thought experiment to design a successor markup language that is not strictly hierarchical, more human-readable, and designed with templating in mind.

What reading Tufte won’t teach you: Interface design guidelines

Edward Tufte’s books do a beautiful job of illustrating how to present huge amounts of information clearly and simply. Well presented information is critical to good interface design, but it’s not the whole story. Guidelines on how to present complex functionality clearly and simply are harder to find.

I’ve just spent two months carrying a terrible, ancient cellular phone and a mediocre non-Apple music player around the planet, and interacting almost exclusively with Windows XP terminals at internet cafes and hostels. As my frustration with these poor interfaces grew, I started a rough list of interface design guidelines. Here they are:

Read on for explanations and examples of good and bad design related to each one of these rules. There is a great deal of overlap between some of them, and that’s OK — they’re just guidelines. (Perhaps I, or someone else, will someday condense them into eight or nine fundamental principles of good interface design.)

The application interface should be fast and non-blocking. If it cannot be fast or non-blocking, it should appear fast and non-blocking by being immediately responsive. Many old-school web applications had disclaimers next to submit buttons saying “Click this button only once.” Submitting data over the network wasn’t fast back in the days of 56.6kbps modems, and it’s still not fast enough today. Most web applications now deal with this by disabling the submit button (good) or by changing it to a progress spinner (better) with JavaScript the first time it’s clicked. The application isn’t fast or non-blocking, but it imitates immediate responsiveness.

The application interface should be consistent. The phone I traveled with had the standard five buttons between the screen and the numeric keypad. When navigating through and controlling various applications, sometimes the left top button meant “select”, and sometimes it was the right top button. And sometimes the center menu button also meant “select,” but not always. This lack of consistency made it just plain impossible to develop a motor memory for “select” on the phone — I constantly had to think about how to select an item or confirm an action. The cross-platform widget toolkit wxWidgets ensures that dialog boxes it creates match the standard order of OK, Cancel, Yes, and No buttons on whichever platform the application is running on.

Don’t interrupt users in the middle of common, nondestructive tasks.The basic, core functionality of the application should be free from confirmations, interruptions, dialog boxes, configuration questions, multiple steps, wizards, and other garbage. Get out of the way and let users do what they need to do. Windows XP’s information bubbles that pop up out of the system tray, on top of other windows, are particularly egregious violators of this rule. Dialog boxes in Windows and on Linux also break this rule, as an error in a background application can interrupt the user mid-task in another application. Mac OS X’s design that puts dialogs into “sheets” attached to the parent window ensures that a dialog box never interrupts a task in a different application. If one application, or the operating system, violates this rule, it can interrupt users while they are using a different application and therefore affect the usability of the entire system. Websites for DTF publications like the New Yorker violate this rule when they split their articles up into multiple pages — maybe this is motivated by some weird desire to mimic turning of a page, but more likely it’s to track readers and increase ad views. Don’t do it. Reload ads and track readers with JavaScript if necessary.

Avoid notifying users of success. In general, an application should allow users to assume that everything is successful unless they hear otherwise. If a delayed or background process or command has completed, and notification of its success will help users to continue their work, then that notification must be radically different than failure notification. Windows’ information bubbles are a serious violator of this rule too. When plugging a new device into a Windows machine, it will often emit three or four info bubbles, with a sequence of messages like this: “New hardware connected,” “CanonSony XJ-4000 PowerCyberShot found,” and then “Your new hardware is ready to use.” OS X gets this right; plug in a camera and iPhoto launches, ready to import the photos. It doesn’t say, three times, that a camera has been connected. iPhoto launching is an implicit indication of a successful connection with the camera. Lots of web applications are doing the right thing by putting success notifications in the page, in little unobtrusive boxes, and putting error messages in red, in a different place on the page. Using dialog boxes for errors, confirmations, and informative messages, as most applications did for years, just trained users to always click “OK.”

Avoid giving users information that they cannot use. Users still must read, think about, and decide that the information is useless. If the information is useless to begin with, why risk confusing them? Why slow them down to read it? Every time I plug my USB CF card reader into a Windows machine, it gives me an info bubble that says “This device could function faster if it were plugged into a USB 2.0 port.” And it says this even if the computer has no USB 2.0 ports at all. What are users supposed to do with this information? Run out and buy a USB 2.0 card? Or a new computer? How many non-technical users actually know what “USB 2.0” means, and can correctly decide to discard this information? The information bubbles in the previous example fail here too. Users don’t need to know that new hardware has been connected, or what model of camera they just connected, because, he or she is the person who plugged the camera in. When people are working together on a project, they don’t call each other every thirty seconds to tell the rest of the team that they successfully typed another word into the report or entered another figure into the spreadsheet.

Rare, destructive actions should be harder to complete than nondestructive ones, but always possible. Closing a file without saving or emptying the trash are examples of destructive actions. If most of the actions in an application are destructive, consider building an action history with an “undo” command or a back button into it. Make as many actions as possible nondestructive. And don’t just skip implementing destructive actions — building a web application without a “delete account” command is criminal. For a long time, one of the t-shirt sites that I’d used didn’t have a way to delete a shirt — just a blurb saying to email customer support with the shirt ID. In the rare case where users do want to perform a destructive action, they are positive that they want to perform it. If it’s missing, the application seems ten times more unfinished and underpowered.

Give the user the chance to ask for forgiveness rather than forcing them to confirm a (destructive) action. Gmail and other web applications are pioneering this one.  Rather than asking something like “Are you sure you want to delete this conversation?” they provide a success notification “The conversation has been deleted” with an “undo” button next to it.  The insight here is that, although the application must provide a way to immediately abort a destructive action like this, 99% of the time, users actually intended to perform the destructive action. That should be the easy, one-click case, and aborting the destructive action should be the rarer, two-click case.

If the application pesters users with a confirmation dialog for destructive actions, users memorize a multi-step destructive command: click delete, then click OK — and when they accidentally delete the wrong thing, they miss the chance to abort. Many, many applications are guilty of this.

Deal with application failure gracefully. Don’t lock users out or lose state in the event of an application failure. Users witnessing an application failure are in the most stressful and worried mental state they will ever be in while using the application. The interface for alerting users about an application failure and recovering from it should be the smoothest, simplest, most comforting part of the interface.

Preserve state, mode, and user input for as long as it is relevant, until the user saves or discards it. Never make users answer the same question or enter the same information twice. Was there an error when saving? Show the form again with everything the user entered. Did the user switch the telephone keypad to Title Case? Stay on title case when the word isn’t in the predictive text dictionary and the user has to spell it. Take advantage of the fact that computers are better at remembering than anything else.

Provide multiple, complete navigation paradigms. Keyboard and mouse control, back and forward buttons, search and choose, scroll and jump, broad and deep, fast and slow. Digital bedside clocks and watches are particularly bad violators of this.  Often they provide, to set the time, just “up” and “down” buttons, or “fast up” and “slow up” buttons. With these two-button interfaces, users must hold down one of the buttons and watch the time change. While performing boring, slow tasks like this it’s easy for humans (your users) to get distracted, miss the target time, and have to go all the way around again, or back in the other direction, slowly. A speed sensitive knob, like on analog watches, or even just ten numeric buttons, would be a much superior navigation interface.

The iPhone lets the user scroll slowly through their address book, or click on a letter and jump ahead in the alphabet. The speed of the scroll when dropping an item into a long list in a scrolled window should depend on how far from the edge the item is being dropped. Would an e-commerce site succeed with just browse-by-category and no search? The phone I carried had one button to cycle to the next word in the group of words offered by the predictive text system, but no way to go back to the previous word. Press next too many times? Sorry, you have to cycle through all nine words all over again.

Design the interface before starting to code. Even just a sketch will help — what commands and what functionality is going to be accessible? When and where? What will need extra heuristics? What will need custom widgets? What are the trouble spots? And don’t just copy what some other application has done. Even great interfaces have problems — copy what’s good and improve what isn’t. Didn’t design the interface before starting to code? Stop now and design it.

If the application violates one of these rules because its design makes implementation of a better interface too complex or too difficult, then the application needs to be refactored until it supports a better interface. This one is sometimes the hardest to swallow — how could an application with a mathematically perfect algorithm and beautifully coded implementation of it need to be re-engineered? If the excuse for not implementing a powerful new feature is a back-end that can’t support it, then that back-end, no matter how awesome it is, is not good enough, and rewriting is the only option. A better UI is one of the most powerful new features that can be added to an application, so if it requires a redesign and a rewrite, so be it.