A coworker turned me onto the webcomic
xkcd earlier this summer. If you are reading this (there’s a philosophy joke here somewhere…), then you’ll probably appreciate the humor of this guy.
Need more proof? Aside from syndicating the comic directly in
his RSS feed (I’ve never seen that before), he also (a) does not have a “www” subdomain, and (b) runs his own IRC channel (#xkcd on irc.foonetic.net). An IRC channel for a web comic must rank up there somewhere on the uber-nerd scale. Even my wife admits that would give me a run for a my money.
I’ve been slowly going through the archives. My current favorites:
and
Sidenote: Firefox flagged the word “webcomic” as a misspelling. For shame! Anyone know where you can submit new words to their system? I just love seeing OSS adopt new vernacular before Webster or M$ jump on the bandwagon.
Update: I realized that the post title is probably absolutely gibberish to most people. It’s written in
leet speak, which replaces letters with numbers and symbols. Several origins have been described, but I see it used a lot in gaming circles simply to ensure uniqueness (since you cannot have two players with the same name).
Whenever I get into a discussion about web usability or UI, I always use the same analogy to describe how to succeed in making happy users. At this point, it’s stood up to a fair amount of scrutiny in conversation, but I’ve never put it onto paper. I firmly believe that all good ideas should be written down, so consider this the next time you’re building a user-heavy web application…
The Science Channel has a series called “How It’s Made.” Any given episode will give you the background on how any number of consumer products are produced. Tires, chainsaws, trumpets, bacon, and even British police helmets have
all been covered. It’s worth the half-hour.
One segment covering modern dairy farms particularly struck (not what you were expecting, I’m sure). You won’t find this one listed in the link above, but I did
track it down on YouTube. I’m pretty sure it came from a pilot episode, as the narrator and opening animation are different. You may want to watch it first, but it’s not necessary for this analogy to make sense.
One huge caveat: I do not think my beloved web users are a big dumb animals. The analogy goes a fair bit deeper. Also the word “teat” is used a number of times in the video above, so do your best to keep your head out of the gutter.
Take care of your users. Just as happy cows get “45k of feed” each day and wander as they please, you must take care of your users at every step in their experience on your site. Your navigation and overall usability are the top priorities here; don’t let them get lost, and make the available actions on each page as clear as possible. To ensure there’s no thumb-twiddling, keep load times down. Yahoo maintains
the definitive list in this regard, and complements well with their
YSlow add-on for
Firebug. You can also use a
speed tester to see how your site stacks up in the wild. You know you’re doing this right if users don’t complain. Like I’m always telling my staff, “Successful web design is not determined by the presence of compliments, but rather the absence of complaints.”
Keep things clean.You may not have to worry about manure on a barnyard floor, but you better still be in there sprucing things up on a regular basis! For any information-based site, the worst offense of all is stale content. Keep delivering fresh information to keep your users entertained and engaged.
Professional-level sites are often maintain by several developers, and must meet the needs of different (and sometimes conflicting) departments and business interests. Here you must also stay vigilant against website sprawl, which is the natural inclination of a website to grow and spread out in an ever-increasing number of directions. Does each board meeting really need its own minutes page? Can that hacked-up marketing tool find a formal home in your admin somewhere? Keep it tight, and if you don’t need it, lose it. If your boss says otherwise, try to keep it corralled along with similar pieces of politically necessary stuff, like the junk drawer in your kitchen. Where are those scissors…?
Performance is also an ever present concern. Watch your logs for badly behaving pages, black holes (pages that constitute a large portion of exit traffic), and hack attempts. Browser updates and standards compliance will also keep you busy. I recommend you try to stay as close to standards as possible, but not at the expense of site functionality. If it works in the “big 4″–Firefox, Safari, Opera, and IE (listed last for a reason)–you’re good to go.
Track your users. Like the cow’s ID tag, you should use session data for general behavior tracking, to identify just how your site is being used. If you add user logins to mix, you can track individual performance, for even more detail, and provide data, search results, and product suggestions customized to the user.
Guide your users. The thing that struck me most about this dairy farm was the complete lack of farmhands. Everything was automated, including the milking process. This is very much like a user on a service based site, or online store. I’m sure the farmhands were there, off-camera, just as we provide help windows, email support, and phone numbers when a user hits a wall. However things run best when the user simply gets what they need, without any additional effort on their or your part.
Give your users clear indicators of where they are and what they are doing. You can’t force your users down the line of the milking stall (think checkout procedures), but you can give them explicit boundaries to show them where they should be going. Again, your attention to usability will win the day on this one.
What other analogies do you see at work here? Do you have any of your own analogies that you use when describing proper techniques to colleagues or the occasional lay person? I’d love to hear what you think!
When writing SQL statements, sometimes I want to filter the result set based on a value that must be computed out of the stored data. Here’s an example:
SELECT widgetID, count( widgetID ) AS totalWidgets
FROM table_widget_sales
WHERE totalWidgets > 1
GROUP BY widgetID
ORDER BY totalWidgets DESC
I want to see which widgets have been sold more than once, and how many times each of those remaining widgets have sold. Obviously we could pass a simpler query into a scripting language to calculate it for us, but that’s more cycles and memory. I love to squeeze as much out of my SQL statements as possible.
Problem is, when I run that query above, I get this error:
#1054 - Unknown column 'totalWidgets' in 'where clause'
My first reaction is, “I can use that column in the order by clause, why not where clauses!?” Simple, the value doesn’t exist when the WHERE clause is evaluated. The number is calculated as each matching record is passed. By the time we reach the ORDER BY clause, we have the data we need. But the WHERE clause is used to actually figure out what records we need to perform that calculation, so we’ve got a chicken-egg issue.
The solution is to use a
subquery, sometimes called a “sub-select statement.” Using two select statements, we can split the duties for filtering (more than 1 widget sale) and counting (total number of sales per widget).
Here’s the working query:
SELECT w.widgetID, COUNT( ws.widgetID ) AS totalWidgets
FROM table_widgets AS w
INNER JOIN table_widget_sales AS ws ON ( w.widgetID = ws.widgetID )
WHERE (
SELECT COUNT( ws.widgetID ) AS number
FROM table_widget_sales AS ws
WHERE ws.widgetID = w.widgetID
) > 1
GROUP BY widgetID
ORDER BY totalWidgets DESC
See what’s going on? We’re doing the same count twice, but the subquery returns everything (number of sales per widget for all widgets), while the first select only grabs the results we want (sales greater than 1).
Over at
ClassicWines, we recently experienced a login issue, where data was not being saved to the session after submitting valid credentials. Enter your username, password, and you would end up back at the home page as if nothing happened. I was banging my head against my desk (literally) looking for the cause.
Cut to the happy ending: PHP
introduced a new “feature” that deconstructs objects BEFORE writing and closing the session. This means that if you use classes to manage your sessions, those classes are gone before the script executes your methods to save the session. There’s a warning at the bottom of the PHP
manual page for session_set_save_handler() that identifies the issue succinctly.
For anyone who ended up here looking for help, the workaround is to call
session_write_close() before the classes are deconstructed, usually with a combination of the
__destruct() magic method and
register_shutdown_function(). PHP documentation claims it was introduced in v5.0.5, but I did not have this issue using v5.1.2. If you like examples, Zen Cart
built in a fix in the latest versions of their package.
This is a small example of a much larger problem in our industry: blind devotion to “the rules.” Technically speaking, the PHP team’s decision was correct: items loaded into memory should be destroyed in the reverse order in which they were created. It’s typically a good assumption to make, because often the younger processes were spawned by and rely on the ones that came before it.
But in this situation it makes absolutely no practical sense. I need my classes in order to close the session properly (as do many developers), and so ideally they should exist when I need them. This is, in fact, the way things worked prior to the bug fix.
The documentation warning I mentioned above even describes the situation as a “chicken and egg” problem, indicating some tacit acceptance of the fact that you cannot have one without the other. The case can be made for either one taking priority.
All that being the case, why make the change at all? It did not make anyone’s life easier. Quite the opposite, in fact. The new setup requires more logic, and hence more lines of code, to write and maintain. The fact that the session came first in the load order is totally irrelevant. Breaking the order of destruction is merely a break in convention, nothing more.
When you go too far up, abstraction-wise, you run out of oxygen. Sometimes smart thinkers just don’t know when to stop, and they create these absurd, all-encompassing, high-level pictures of the universe that are all good and fine, but don’t actually mean anything at all.
The PHP team is, by nature, a pretty high-floating group. To a certain extent, it’s to be expected; they’re writing a programming language, after all. But this decision definitely shows a lack of oxygen.
My number one concern is always making my code do what it needs to do in the most efficient way possible. If that breaks a socially accepted norm or two, I have absolutely no problem with it, and neither should you.