Archive for the ‘Uncategorized’ Category

User Error + QBQ → User Interface Error

November 7, 2009

About once a day, I sift through our aggregated Web server error messages.  My usual sorting goes something like “this needs to be addressed, that one is novel, this one is my personal test and can be ignored.”  Usually there’s at least one issue where my first reaction is “Oh, that’s just user error.”

One particular error kept coming up from our internal users to the point that it became a nuisance, and I cried out “Why can’t they get that right?!” Immediately, I was convicted by what I had read in QBQ: The Question Behind the Question (a must-read for the Dave Ramsey team).  That wasn’t a ‘QBQ’ question. What can I do so that my internal users will get that right? In this case, a drop-down list contained an invalid option entitled “Select an Option”   The solution was obvious, remove the invalid option and enhance the then-arcane validation message. This process can be generalized to the following:

User Error + QBQ → User Interface Error

Don’t get me wrong, some times a user behavior is just too bizarre to code around it.  (The customer isn’t always right.) Sometimes a customer just needs some education.  The point is that as the solution developer, I’m responsible (at least in part) for my end-users’ actions. It is neglect of this truth that yields the bad reputation programmers get for their people skills.

Let’s do better. The next time you’re faced with a “PEBKAC” error, before you write it off as ID-10-T, consider the UI or the UX or the messaging or the training. You’ll ultimately wind up with a better product.  Who knows, maybe you’ll even create documentation.

Zooming like a pro with MapQuests AS3 api!

October 21, 2009

Wow, so I have had a ticket sitting in my queue for some time now that I didn’t think would be easy. What we had to do was zoom into a location while leaving that location in the same relative position for the user. After much thinking (about two hours) I came up with my solution. We use MapQuests AS3 api to interact with our maps.

The principle is simple. Figure out where the users mouse is. Get the XY, zoom in, figure out what LatLng is in that XY Position, and get the difference. Then apply the difference to the center point and set the new center point.

public function zoomMapKeepingXYCoords():void
{
var mouseXY:IPointXY = new PointXY(myMap.mouseX, myMap.mouseY);
var mouseLL:IPointLL = myMap.pixToLL(new PointXY(myMap.mouseX, myMap.mouseY));
setZoom(myMap.getZoomLevel() + 1);
var newLLatXY:IPointLL = myMap.pixToLL(mouseXY);
var latDiff:Number = mouseLL.lat – newLLatXY.lat;
var lngDiff:Number = mouseLL.lng – newLLatXY.lng;
var centerAftZoom:IPointLL = myMap.getCenter();
var newCenter:IPointLL =
       new PointLL(myMap.getCenter().lat + latDiff,myMap.getCenter().lng + lngDiff );
myMap.setCenter(newCenter);
}

Have Fun!

Independence Delay

July 3, 2009

W3C announced today the end of the XHTML 2 working group charter.  It has long been apparent that HTML 5 would become a reality, much to my chagrin, but I had hoped deep down that XHTML2 would not die.  You see, HTML 5 is a great tactical move to progress HTML making multimedia easier (among other things) for content authors. However, strategically, I feel this sets back the Web, particularly the semantic Web. I am disappointed, not because XHTML 2 has better features than HTML 5, but because the promotion of HTML 5 over XHTML 2 moves the Web in the wrong direction.

What’s so great about XHTML2

What’s so great about XHTML2? There are some nice cleanups, like replacing <h1-6> with a simple <h>.  The <hr> is replaced with a more semantically-named <separator>. The generalization of the href and src attributes were also pretty exciting. However, the biggest thing is decentralized extensibility. In fact, the W3C mentioned this in their FAQ regarding the end of XHTML2. The very existence of HTML 5 exemplifies why this is a big deal. Decentralized extensibility means we can create our own vocabularies independent of browser implementations.

The current state of things

As a developer, you’re stuck with the elements a user-agent implements.  With HTML, you are limited to what a consortium managed to agree upon and browser authors implemented (somewhat) consistently. The needs of content authors and the capabilities browsers have outgrown the existing centralized vocabularies of HTML 4 and XHTML 1.  HTML 5 addresses this problem with a brute force method: keep improving the centralized vocabulary, and try to keep up with the developer community.

Where we could be headed

If we currently live in the era of the Web browser, we ought to be headed toward the era of the XML browser.With XML, we have more liberty. We can create XML documents with our own vocabularies. We can even define the vocabularies through DTDs or other schemata.  We can mix and match our vocabularies with others. We can define the layout and presentation of new languages with CSS and XSL-FO. Better still, we can define what our new elements and attributes mean through RDF and its related technologies. This is the key.

Every time I mention this, I get the same question, “How would a browser know that my attribute mynamespace:foo@fetcherator is the same as html:a@href?” This is where RDF comes in. With semantic technologies, we can define our vocabularies in such a way that a browser will know.

Why can’t we head there with HTML 5?

We can. In fact, I believe we will (though perhaps more slowly now). My concern is the motivation behind the HTML enhancements in HTML 5 vs XHTML 2. XHTML 2 was a continuation of the W3C’s efforts to bring the benefits of XML into HTML, while HTML 5 seems to bring the benefits of new user agent capabilities into HTML. We need to decouple the user agent capabilities from our document vocabularies. This is true independence.

We can still do this.  The future may still be bright. I hope that we do not lose the vision as we postpone liberty for the comforts afforded by the latest iteration of a centralized HTML.

Plan your escape

March 21, 2009

URL encoding is not character/entity encoding.

This should go without saying, but I frequently see this confused by experienced developers, especially when working with dynamic/loosely typed languages.

URL encoding is for URLs (URIs to be more generic).  The only time to URL-encode a string is when it is part of a URL.  JavaScript provides encodeURI(), encodeURIComponent(), decodeURI, and decodeURIComponent().  In ColdFusion, you can use the  URLEncodedFormat() and URLDecode() functions.  PHP provides urlencode(), rawurlencode() and their decode counterparts.

Entity encoding is used for representing characters in a document that lie outside of the document character set or have a special meaning within the document.  For example In XML, &, <,>,”,and ‘ have to be encoded as entities (‘&amp;, &gt;, etc.) in the document source code.  Typically, characters outside of “low” ASCII need to be encoded as well.  In client-side code, you typically need not worry about entity-encoding. You’re working with a DOM, not document source code, so entity expansion/subsitituion has already been done.

ColdFusion is a little tricky on this one.  There is no equivalent to PHP’s htmlentities.  You basically have two options, HTMLEditFormat and XMLFormat.  The former will encode characters with special meanings, but it misses high-ASCII (and higher).  The latter will encode high-ASCII, but will not use special HTML entity names.  It’s for (the more generic) XML after all.  XMLFormat escapes characters using character entity references.

The concept applies outside of this concrete example, but this is the example that led me to channel my angst into what I hope is a helpful guide post for others.  In fact, you’ll notice that two paragraphs above, Word Press has transformed my double and single quotes to right-double and left-single quotes, respectively.  What are some other escaping/transforming pitfalls you’ve seen?

User-Centric Development

March 18, 2009

The keynote at DevLearn 2008 this past past fall was given by Dan Roam, the author of The Back of the Napkin. Dan spoke about the importance of thinking visually, especially when problem solving.

His presentation spurred a conversation between myself and the other Lampo attendees at the conference: Jon Shearer and Michael Finney. We were discussing how bad things can happen when software engineers find a neat “feature” they can work into an app, regardless of whether the users want or need it.

This brought Finney to a perfect, real-life example of this concept in action. He had recently purchased a new Gateway laptop with a built-in 802.11n wireless network adapter. When using the wireless, however, he had noticed that it would occasionally slow to a crawl. It’s never terribly convenient to troubleshoot this type of problem, especially when so many components are involved (ISP, broadband modem, wireless router, laptop hardware, OS…) and the problem is intermittent.

Well, last weekend, he had a guest in his house with a laptop, and he was able to do a side-by-side speed test during one of these episodes, and he discovered that while the other laptop was getting about 20mbps down, his was getting about 20kbps down.

This took the network out of the troubleshooting stack, so he really dug into the laptop to locate the source of the problem. Before long, he found a “feature” that is new to Windows Vista.

As with prior versions of Windows, you can create and customize power schemes to use when on battery power in order to preserve battery life by throttling the power that certain components use. It is common to scale back the processor speed or the LCD brightness to achieve longer batter life.

Well, Vista has added Wireless Network Adapter Throttling into the default power saver scheme, effectively crippling your network speeds in the name of battery preservation. Let’s think this through for a minute. I want to preserve battery life, so having to sit and wait 1000x longer for a website to come up (all while my LCD and processor burn through battery while I sit and do nothing) is the answer?

Just because you can do something as a developer with the technology you have, doesn’t mean you should.

And just in case you got to this post by searching for an answer to your network slowdown woes, here’s how you change this setting in Vista. Control Panel -> Hardware & Sound -> Power Settings -> Change Plan Settings (on your currently selected power plan) -> Change advanced power settings -> Wireless Adapter Settings -> Power Saving Mode. That’s right, 7 clicks deep, one of which includes clicking on “Sound”. *sigh*

Look under the turtle

November 14, 2008

Developers understand that code reuse necessitates a simple-to-learn interface.  Typically, this leaves us adding another layer of abstraction (aka. “turtle”) to the existing turtle-pile.  This is all wonderful and leaves us feeling warm and fuzzy, except that abstractions are leaky at best.  Usually these new clever interfaces simplify doing whatever you need to do (as long as it is what the API author says you want to do). This means that in order to consume another’s code, I must first learn his or her clever new interface and the interfaces below it.

Recent projects have brought me to the realization that sometimes it’s better to remove a layer of abstraction.  I recently built a solution that involved thermal transfer printing bar codes on pre-printed ticket stock.

The printer uses a proprietary Postscript-like language for creating fields and updating their values throughout the course of a print job.  The printer also came with several half-baked utilities to almost simplify the job of getting it to print what I want, but not quite.  After perusing the developer’s guide, it turned out to be as simple as sending control characters to a parallel port.  I wrote a ‘driver’ in ColdFusion that reads the ticket records from the database and generates a .prn file (just ASCII control codes).  Now I can simply cat the generated file to the fancy printer from any machine that has a parallel port regardless of operating system and without having to install printer drivers.

Albert Einstein is quoted as saying “Things should be made as simple as possible, but no simpler.”  In the example above, I had to learn something new either way—the formatting codes or the libraries that came with the printer.  The libraries failed to simplify the interaction because they did not provide a complete abstraction; I would still have to delve a layer deeper for some of the things I needed.

Think about the abstractions you provide.  Do they really simplify? Will a user of your API need to delve a layer deeper?  If so, you’ve only created an obstacle.

Let’s be really clever developers; let’s learn the abstractions we already have and create clever documentation for other developers.

Little Changes and HUGE Effects

August 19, 2008

iTunes operates similar to a Digg type website. In this case, people vote by subscribing to a podcast inside iTunes. The more people click on your podcast, the higher the ranking goes. The top spot on the podcast ranking can be valuable real estate to hold, but how does one become (and stay) king of the mountain?

Of course, it really helps if you have a popular website that can drive people to your podcast. Then you can use a link like the one below (every podcast has their own unique url) to send people to the iTunes Store.

http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewPodcast?id=77001367
iTunes Podcast Subscription

The iTunes Podcast Subscription Page (Red Circle Added)

The above link brings up iTunes and preloads it to a screen like this one. Where iTunes ratings are concerned, it’s all about clicking that last button.

It’s also entirely time-based. You can have 3 Million podcasters sign up over the course of a year. Assume that all of them are avid listeners who hear the show every day. That would be 10,000 people/day. However, say a TV show ends and posts a snippet on iTunes, and they get 150,000 people to download the snippet over 3 days. Even though the theoretical TV show only has 5% of your theoretical audience, they would have 40,000 more subscribers per day and presumably take the #1 slot for 3-4 days.

It’s an interesting animal. A while back, we added images to our podcast feed, and almost immediately we jumped to #1 in the business category, and for the first time we broke the top 100 overall. Late last year, we started to combine 2 feeds, and jumped from an average ranking around 80 to an average ranking around 40 – and we have more changes coming. (I’ll detail what we’ve done in a future post.)

When you start working with groups of people in the millions, small changes can make a HUGE difference. We’ve seen it here many times in various forms, but to me it’s like a jet leaving the runway – it still amazes me every time.