Coding Horror

programming and human factors

STOP! Having Trouble?

From Engadget's review of the iRiver H10:

So the first thing we noticed about this player when we opened it up was, unfortunately, a huge orange flyer [..]

From Larry Osterman's review of the iRiver H10:

My concerns started when I opened the box. To the left of the H10 was a plastic bag with the manual etc. On the top of the plastic bag, plain to see was a bright orange piece of paper with:

STOP! Having trouble? Visit www.iriveramerica.com/support Before you return it... contact iriver America. We Can Help

Do you really want your user's out of box experience to be a bright orange warning sign that screams STOP! and Having Trouble? That negative first impression sets the tone for the rest of the device's life. It's all downhill from there.

It's details like this that drove Omar back to the iPod. But that's a natural consequence, as Omar points out, of the business model: Apple owns the device, the software, and the music licensing. They control the entire experience. Nobody can screw that up behind Apple's back.

Now compare that with the out of box experience of the new Lenovo T60 Thinkpad we received at work today. This is the taskbar after the machine has literally been booted for the first time:

Lenovo Thinkpad T60 OOB taskbar

The operating system is loaded down with so many pre-installed craplets that the taskbar takes up half the screen. The hardware is excellent, but you'd never know that based on the abysmal software experience you're about to have. And that's just the taskbar! Take a look at the full desktop screenshot. It's even worse.

Is it any wonder that I recommend people wipe their systems as soon as they receive them and perform a clean install of Windows XP SP2? If I've learned anything about computers in the last 35 years, it's this: if you leave the user experience up to third parties, they will screw it up behind your back. Royally. Every single time.

That's why I'm encouraged by the Windows Media Center team's insistence that they tightly control the core user experience. As Charlie Owen explained to me at MIX06, third parties can create all the external add-ins they want, but they can't mimic the Media Center UI, and they definitely can't muck around with the core functionality of Media Center.

Good call.

Discussion

I Shall Call It.. SomethingManager

Alan Green rails against the meaninglessness of SomethingManager:

How many classes do you come across named SomethingManager? Any decent sized commercial system seems to have plenty – SessionManager, ConnectionManager, PolicyManager, QueueManager, UrlManager, ConfigurationManager, or even, sadly, EJBManager.

A quick look at the dictionary entry for "manager" and "manage" gives at least ten different meanings - from "to make and keep compliant" through to "to achieve one's purpose". I remember one day when the receptionist briefly retitled herself as Switchboard Manager. The common semantic to all these definitions seem to be a vague "looks after stuff".

This imprecision makes Manager a bad word to use in naming classes. For instance, take a class named UrlManager – you cannot tell whether it pool URLs, manipulates URLs or audits the use of them. All the name tells you is that this class does something with URLs. On the other hand, the name UrlBuilder provides a much clearer picture of what the class does.

In the Java world, the Manager suffix is thrown around a lot. Almost anywhere you have a class that is responsible in any way for other objects, it automatically earns the Manager label.

There's nothing more ambiguous than a SomethingManager. Avoid this word. Alan proposes a few alternatives in his blog post that might be helpful in narrowing down what your class actually does.

Giving your classes and objects good, descriptive names isn't easy. Steve McConnell provides a few helpful guidelines for routine naming in Code Complete:

  1. Describe everything the routine does
    And we mean literally everything. If that makes the name ridiculously long, the name isn't the problem. Your routine is.

  2. Avoid meaningless, vague, or wishy-washy verbs
    Like UrlManager, or HandleOutput(), or PerformServices(). Be specific. What does it do? If you can't answer that question succinctly, it may be time to refactor the code until you can.

  3. Don't differentiate routine names solely by number
    I include this only for completeness. If you ever find yourself writing OutputUser1() and OutputUser2(), God help you. And God help the team you work with.

  4. Make names as long as necessary
    According to McConnell, the optimum name length for a variable is 9 to 15 characters; routines tend to be more complex and therefore deserve longer names. Make your names as long as they need to be in order to make them understandable.

  5. For functions, try using a description of the return value
    An easy, straightforward rule. Some examples are printer.IsReady(), pen.CurrentColor(), etcetera.

  6. Use opposites precisely
    For every Open(), there should be a Close(); for every Insert(), a Delete(); for every Start(), a Stop().

  7. Establish conventions for common operations
    This is best illustrated with an example, and McConnell provides an excellent one:

    employee.id.Get()
    dependent.GetId()
    supervisor()
    candidate.id()
    

    Now how do I get an Id again?

I'd say renaming classes and variables is one of my most frequent refactoring activities. Creating good names is hard, but it should be hard, because a great name captures essential meaning in just one or two words

It's difficult to tell what something should be named until you're completely finished writing it. And like most code, it's never quite done, so the name may change over time. Succinct, descriptive variable, object, and function names can make the difference between Daily WTF code and… well, code you'd actually want to work on.

Discussion

How Not To Become a Rockstar Programmer

Tom's criticism of Mikael Grey's article, How to Become a Rock Star Programmer, starts off promisingly enough:

Let's start with the title. There is no such thing as a "Rock Star Programmer," so if you want to become one, you already have problems that reading a blog post can't fix. Rock stars get sex, drugs, parties, limousines, fame, glory, dates with supermodels, and Rolling Stone covers. Good programmers get . . . uh . . . fewer compiler errors. Or fewer runtime errors, depending on which language you're using. So let's not pretend that "Rock Star Programmer" makes any more sense than "lighter-than-air paperweight" or "Rock Star Babysitter."

Michael Angelo, guitar shredder

But the tip he offers is just as flawed as the top ten list he's criticizing:

The best way to improve is to study code that is better than your own. Read good code written by experts, in a variety of programming languages. Study it until you understand how it works and what makes it good. That's it. That's the one tip.

You won't become a better programmer by passively studying other people's code. Similarly, you don't magically become a better writer by reading a lot of books. You become a better writer by.. wait for it.. writing.

Studying code is reasonable advice. It's helpful. But the absolute best way to improve is to write your own damn code! Nothing teaches faster than making your own mistakes, on your own time, on your own terms.

So study "good code*" all you want, but write as much code as you can.

* whatever that is

Discussion

The Ideal Computer Desk

A few years ago, I did a bit of research on computer desks and decided on this AnthroCart model:

The Anthrocart Console Unit Desk

And it's a fantastic computer desk. But its Wife Acceptance Factor (WAF) is abysmal for a few reasons:

  • It's absolutely enormous
  • It's black
  • Its design is better suited to an office than a home

Plus, we just bought a small home in the Bay Area*, and we need to optimize for space. Looks like I'll be selling the Anthrocart.

Which means I'm looking for a smaller desk now.

I had to buy an additional desk when I moved to California, prior to all our stuff arriving. Since we have easy access to IKEA, I went with the IKEA Jerker desk.

IKEA Jerker Desk

You can see the edge of the Jerker in the bottom-most photo of Phil's dog Twiggy. There's something about the Jerker that inspires people: Behold! The shrine to the IKEA Jerker desk!

Although I really do like the Jerker-- and the name alone is worth the 99 bucks-- I'm still researching my options. What is your favorite computer desk, and why?

* Holy crap. That was written in 2004, so add another ~20% appreciation for 2005.

Discussion

Making Considerate Software

I'm currently re-reading the book About Face. I hadn't revisited this book since I bought the original version way back in 1995. The update, which was published in 2003, is a significant overhaul – and frankly much better than the original. Adding the second author, Robert Reimann, was a smart move. Alan Cooper is a usability legend, but he can be bombastic and overbearing at times. Having another viewpoint in the book helps moderate and refine the message. (Since this was written, About Face 3.0 was released, with yet another author added to the mix.)

One part of About Face that I found particularly compelling was the section on considerate software:

  1. Considerate software takes an interest

    To the programmer writing the program, it's a just-in-time information world, so when the program needs some tidbit of information, it demands that the user provide it. The program then discards that tidbit, assuming it can merely ask for it again if necessary. Not only is the program better suited to remembering than the human, the program is also inconsiderate when, acting as a supposedly helpful tool, it forgets.

  2. Considerate software is deferential

    Inconsiderate software supervises and passes judgment on human actions. Software is within its rights to express its opinion that we are making a mistake, but it is being presumptuous when it judges our actions. Software can suggest that we not not Submit our entry until we've typed in our telephone number. It should also explain the consequences, but if we wish to Submit without the number, we expect the software to do as it is told.

  3. Considerate software is forthcoming

    Most software doesn't attempt to provide related information. Instead, it narrowly answers the precise question we ask it, and it is not forthcoming about other information even if it is clearly related to our goals. When we tell our word processor to print a document, it doesn't tell us when the paper is low, or when forty other documents are queued up in front of us, or when another nearby printer is free. A helpful human would.

  4. Considerate software uses common sense

    You can easily find menus offering simple, harmless functions adjacent to irreversible ejector-seat-lever expert functions. It's like seating you at a dining table right next to an open grill. Horror stories abound of customers offended by computer systems that repeatedly sent them checks for $0.00 or bills for $957,142,039.58. One would think that the system might alert a human in the accounts receivable or payable departments when an event like this happens.

  5. Considerate software anticipates needs

    A web browser spends most of its time idling while we peruse web pages. It could easily anticipate needs and prepare for them while we are reading. It could use that idle time to preload all the visible links. Chances are good that we will soon ask the browser to examine one or more of those links. It is easy to abort an unwanted request, but it is always time-consuming to wait for a request to be filled.

  6. Considerate software is conscientious

    If we rely on a word processor to draft a new MicroBlitz Contract and then try to [save it in the same folder as an existing, but older, MicroBlitz Contract], the program offers the choice of either overwriting and destroying the old contract or not saving it at all. The program not only isn't as capable as [a human assistant who saw the name conflict and appropriately renamed the contracts], it isn't even as capable as [a human assistant who put the two contracts in the same folder]. It is stupider than a complete idiot. The software is dumb enough to make an assumption that because they have the same name, I meant to throw the old one away.

  7. Considerate software doesn't burden you with its personal problems

    Software whines at us with error messages, interrupts us with confirmation dialog boxes, and brags to us with unnecessary notifications. We aren't interested in the program's crisis of confidence about whether or not to purge its recycle bin. We don't want to hear its whining about not being sure where to put a file on disk. We don't need to see information about the computer's data transfer rates and its loading sequence, any more than we need information about the customer service agent's unhappy love affair.

  8. Considerate software keeps you informed

    We don't want our local bartender to grouse about his recent divorce, but we appreciate it when he posts his prices in plain sight and when he writes what time the pregame party begins on his chalkboard, along with who's playing and the current Vegas spread. Nobody is interrupting us to tell us this information: it's there in plain sight whenever we need it.

  9. Considerate software is perceptive

    Software should watch our preferences and remember them without being explicitly asked to do so. If we always maximize an application to use the entire screen, the application should get the idea after a few sessions and always launch in that configuration. The same goes for placement of palettes, default tools, frequently used templates, and other useful settings.

  10. Considerate software is self-confident

    Are you sure? Are you really sure? Are you really, really sure?

  11. Considerate software doesn't ask a lot of questions

    Choices can be offered in different ways. They can be offered in the way that we window shop. We peer in the window at our leisure, considering, choosing, or ignoring the goods offered to us -- no questions asked. Alternatively, questions can be forced on us like an interrogation by a customs official at a border crossing: "Do you have anything to declare?" Software should never put users through this kind of intimidation.

  12. Considerate software takes responsibility

    Most programs are filled with data and settings. When they crash, that information is normally discarded; the user is left holding the bag. Let's say you are downloading your email from a server, when your email program runs out of memory at some procedure buried deep in the internals of the program. The program, like most desktop software, issues a message that says, in effect, "You are completely hosed," and terminates immediately after you click OK. You restart the program, or sometimes the whole computer, only to find that the program lost your email and, when you interrogate the server, you find that it has also erased your mail because the mail was already handed over to your program. This is not what we should expect of good software.

  13. Considerate software knows when to bend the rules

    In most computerized systems, there are only two states: non-existence or full-compliance. No intermediate states are recognized or accepted. In any manual system, there is an important but paradoxical state -- unspoken, undocumented, but widely relied upon -- of suspense, wherein a transaction can be accepted although still not fully processed. The human operator creates that state in his head or on his desk or in his back pocket. For example, a digital system needs both customer and order information before it can post an invoice. Whereas the human clerk can go ahead and post an order in advance of detailed customer information, the computerized system will reject the transaction, unwilling to allow the invoice to be entered without it.

    The characteristic of manual systems that let humans perform actions out of sequence or before prerequisites are satisfied is called fudgeability. It is one of the first casualties when systems are computerized, and its absence is a key contributor to the inhumanity of digital systems. It is a natural result of the implementation model. The programmers don't see any reason to create intermediate states because the computer has no need for them. Yet there are strong human needs to be able to bend the system slightly.

Lots of food for thought there. So many applications I use fail even the most basic criteria on this list. I wish I could get every working developer to read Don't Make Me Think and About Face.

Discussion