Coding Horror

programming and human factors

It's Better Than Nothing

I was struck by this quote from a New Yorker article on Muzak:

"Our biggest competitor," a member of Muzak's marketing department told me, "is silence."

The problem with comparing something to nothing is that nothing is, well, nothing. James Bach elaborates:

I was watching Dr. Stuart Reid talk about model-based testing, some months ago. During the presentation, he complained that so few people used UML for model-making. Why don't more people use UML, he asked the audience?

I suppose his question was rhetorical, but I couldn't help myself. I called out "Because it's clunky!"

"It's better than nothing," he replied.

Think about that. Think about that phrase. A comparison is offered between something and nothing. Who could prefer nothing? Nothing is a void. It's scary and black. It makes us think about death. Ick. But wait a minute, the comparison that matters is not between something and nothing, it's probably between something and some other thing.

As Bach points out, any comparsion that ends in "It's better than nothing" is an invalid one. There are always alternatives, whether the person speaking chooses to acknowledge them or not. Instead of UML, you could..

  • model in your head
  • model via pencil and paper sketches
  • model through your source code

In my opinion, code is a perfectly reasonable place to model. That's why I was so encouraged by the fact that visual, two-way class modeling support was pushed down from Visual Studio Team Edition for Software Architects into almost all the editions of Visual Studio 2005 (Standard or better). It isn't formal UML, but it is a kinder, gentler modeling tool that a lot more people are likely to use.

As code   As model
Account class in code form   Account class in model form

Discussion

(Very) Basic Textbox Keyboard Shortcuts

Everyone knows how to use the arrow keys to navigate within textboxes. But not many people know there are a slew of handy keyboard shortcuts for editing text in textboxes. And these keyboard shortcuts work everywhere, even in the most basic input areas – including vanilla HTML forms, such as the Wikipedia edit box.

(Note that on a Mac you may need to substitute Cmd for Ctrl.)

Moving the Cursor

Ctrl+
Move cursor to next word

Ctrl+
Move cursor to previous word

Ctrl+
Scroll text area up (only works in some apps)

Ctrl+
Scroll text area down (only works in some apps)

End
Move cursor to end of line

Home
Move cursor to start of line

Ctrl+Home
Move cursor to beginning of text

Ctrl+End
Move cursor to end of text

Cut, Paste, and Undo

Ctrl+X, or Shift+Del
Cut selected text

Ctrl+C, or Ctrl+Ins
Copy selected text

Ctrl+V, or Shift+Ins
Paste selected text

Ctrl+Z
Undo last edit

Ctrl+Y
Redo last edit

Deleting Text

Ctrl+Del
Delete forward to word break

Ctrl+Backspace
Delete back to word break

Selecting Text

Ctrl+A
Select all text

Shift+
Extend selection one character to the right

Shift+
Extend selection one character to the left

Shift+
Extend selection down one line

Shift+
Extend selection up one line

Shift+Home
Extend selection to beginning of line

Shift+End
Extend selection to end of line

Shift+Ctrl+
Extend selection to next word break

Shift+Ctrl+
Extend selection to previous word break

Shift+Ctrl+
Extend selection to below paragraph

Shift+Ctrl+
Extend selection to above paragraph

Shift+Ctrl+Home
Extend selection to top of text

Shift+Ctrl+End
Extend selection to bottom of text

Navigation

Tab
Move to next input area on form

Shift+Tab
Move to previous input area on form

Other

Shift+Enter
Add a manual line break

Ctrl+Enter
Submit form (if textarea is part of a form and has support)

All of these shortcuts work in any standard textbox, like the ones on every web page and in most apps for your operating system. Try them out!

Discussion

How Much Power Does My Laptop Really Use?

I've determined power usage on my desktop and on my server, but I hadn't gotten around to testing the power usage of my laptop. As battery life is always a concern with a laptop, I was particularly curious to see which parts of the laptop draw the most power. So I ran a few tests with my trusty kill-a-watt on my Dell Inspiron 300m. It's an ultaportable 2 pound laptop of late 2003 vintage with the following specs:

  • Intel Pentium M 1.2GHz low voltage processor
  • 640 megabytes of RAM
  • 60 gigabyte hard drive
  • 12.1" 1024x768 LCD screen
  • Windows XP Pro

Let's start with some baselines:

Laptop off, battery charging 63w
Laptop off, battery disconnected 1w
Laptop off, sleeping 1w
Laptop on, idle at Windows desktop 15w

All subsequent tests were run with the laptop connected to AC power and the battery physically removed from the machine.

How much power does the LCD display use?

maximum screen brightness15w
minimum screen brightness11w

How much power does the hard drive use?

hard drive sleeping14w
hard drive idle15w
hard drive defragmenting18w

How much power does the onboard WiFi use?

wifi disabled15w
wifi enabled16w
wifi bandwidth test19w

How much power does the CPU use?

cpu idle15w
cpu running prime95 torture test26w

How much power does the integrated video use?

Running 3dMark2001 produced a peak power usage of 29 watts. We can subtract the Prime95 number of 26 watts -- which is entirely CPU-only-- to estimate about three watts are used exclusively by the integrated Intel "extreme"* video hardware.

Bear in mind the kill-a-watt is only accurate to plus or minus a watt. And these are all rough figures based on a sample size of one laptop. But I think the rules here can be generalized to most laptops.

Here's what I learned:

  1. The CPU is, by far, the biggest consumer of power in a laptop. No surprise there. If you want to drain your battery lickety-split, run a bunch of apps that peg your CPU at 100 percent.
  2. Putting your hard drive to sleep isn't worth it. Ever. You save a whopping.. single watt. Why bother?
  3. For maximum battery life, dim your screen. I was surprised that the screen alone accounted for 25% of the total power draw of my laptop at idle. You can moderate use of WiFi or your hard drive, but you can't exactly moderate the use of your screen. Plan accordingly.

Of course, your mileage may vary.

* it's extreme, all right. Extremely crappy.

Discussion

Best Practices and Puffer Fish

James Bach's seminal rant, No Best Practices, is a great reality check for architecture astronaut rhetoric. It's worth revisiting even if you've read it before.

Some might say Bach's viewpoint is pessimistic, even cynical:

The way to get rich in this world is mainly by making people feel large hope about a small exertion (i.e. "six-second abs", lottery tickets, voting in an election, maturity models, and stuff like that). If you want to get rich, do not tie yourself to the truth.

I say his viewpoint is not only healthy, but necessary. If it feels painful, that's good. The truth is always a little painful.

You should question all the advice you get. And you should especially question any so-called "best practices". The very utterance of the words "best practice" should set off warning klaxons, sirens, and flashing red lights. At that moment, you've left the realm of opinion and advice. You've entered the realm of evangelism and true believers.

And yet the world is full of best practices and tidy little checklists. Developers are all too eager to preach the one true solution ..

In way too many meetings, the fastest talkers win. And by "fastest talkers", I mean those who are the first to articulate an idea, challenge, issue, whatever. Too many of us assume that if it sounds smart, it probably is, especially when we aren't given the chance to think about it.

.. but problems are rarely that simple in the real world. Why? James Bach has a theory:

Do you know what's behind all this? I think it's simply that so few of us know how to do our jobs. Like puffer fish, many of us feel that we need to huff ourselves up so that predators won't devour us. We fluff ourselves full of impressive words.

A puffer fish

All this impressive talk is fueled by fear. The field of software development is so vast-- and the piece of it we know is so impossibly tiny. We're constantly living in fear that people will find out how little we know. That people will realize we're impostors who are lucky to still have a job.

Rather than simply stating what we've done and how we did it, we feel compelled to puff it up into a spiny, intimidating best practice. We attach our egos to our code frameworks. If someone doesn't agree with our approach, they're attacking us personally. If someone has a different best practice, they're amateurs who don't understand the problem domain.

Fear can make you do some irrational things. Being honest and humble is difficult-- it's painful to admit that you don't have the answer; that you're not an expert; that there are so many variables you can't control. But whatever you do, always avoid the empty trap of the puffer fish.

Discussion

Blocking Image Bandwidth Theft with URL Rewriting

I like to periodically watch the HTTP traffic on my server. I can see what I'm actually serving up over the wire, and how much bandwidth I'm using.

That's how I noticed that I've become somewhat popular with direct-link image bandwidth thieves. In other words, people who thoughtlessly (or maliciously) embed these IMG links in their web page:

<img src="http://www.codinghorror.com/blog/images/qbert_regex_16.png">

That means the image qbert_regex_16.png is served by my webserver to every user who happens to request this myspace profile page.

Warning: like all myspace pages, that page is

  • Not really safe for work
  • Incredibly, mind-bendingly ugly
  • Filled with thousands of images, animated images, flash, MIDI samples, embedded MP3s
  • Utterly and completely incomprehensible

In short, a trainwreck. Every time I visit myspace, I feel a little bit stupider, ala Billy Madison:

Principal: Mr. Madison, what you've just said is one of the most insanely idiotic things I have ever heard. At no point in your rambling, incoherent response were you even close to anything that could be considered a rational thought. Everyone in this room is now dumber for having listened to it. I award you no points, and may God have mercy on your soul.

Billy Madison: Okay, a simple no would've done just fine.

I have no idea why myspace is so popular. I guess the best I can hope for is that those damn kids stay off my lawn.

Anyway, back to business. The most common technique for blocking direct image links is to check the HTTP referer header. Here's the complete HTTP header set of an image request that just came through:

GET /blog/images/logitech_g15_keyboard.jpg HTTP/1.1
Accept: */*
Referer: http://www2.gamelux.nl/forum/topics/10072/38/
Accept-Language: nl
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: www.codinghorror.com
Connection: Keep-Alive

Prior to serving up the image, we should check the Referer HTTP header, and make sure it's either:

  1. Blank
  2. In a list of known whitelisted referring domains

If it isn't, we will serve up either a 404 error, or a "hey, stop stealing our bandwidth" image of some kind. Because I'm a nice guy, I chose this image:

All this can be done through incredibly powerful URL Rewriting, which has been standard on Apache for some time. There's a nice walkthrough on how to set up image link blocking in Apache on Tom Sherman's site.

Unfortunately, IIS 6 doesn't have native support for URL Rewriting*, but there are any number of third party ISAPI filters that can do it. The one I use is ISAPI Rewrite. It's very similar to the Apache version, in that it is driven by the httpd.ini file in the root of each website. I struggled a bit with the rules, but thanks to a helpful forum post, I realized that I needed to put all the whitelisted domains on a single line to get a boolean "or" that included the empty referer case, like so:

[ISAPI_Rewrite]

# Block external image linking RewriteCond Referer: (?!http://(?:www.codinghorror.com|www.bloglines.com|www.google.com)).+ RewriteRule .*.(?:gif|jpg|png) /images/block.gif [I,O]

So, as outlined above: unless the referer is blank, or in the whitelist, they get shunted to the blocked image.**

Take that, 26 zillion myspace users.

* I'm pretty sure URL Rewriting will be in IIS7, since they're finally getting around to making a really good copy of Apache's modular architecture in version 7.

** This is done at the ISAPI level, so unlike the cheesy ASP.NET "URL rewriting" solutions, it also works on generic URLs, not just URLs that end in .aspx or some other extension that is sent to the ASP.NET handler. This has long been a pet peeve of mine, but it's really the fault of IIS. And it's changing in IIS 7.

Discussion