The Official Google Blog has a post detailing the usability tests they put Advanced Search through.  It brings to light a few important nuances, such as users many times don’t actually think about the searches they submit.  This causes the problem of designing both for thinking users and for non-thinking users.  This problem is much like having to design both for power users and non-technical users.

The most important part of their redesign, however, comes from the feature that Dan mentions at the end of the post:

One of the other things we noted in the field study was that people often didn’t understand how the Advanced Search page worked. So we added a “visible query builder” region at the top of the page. As you fill in the blanks, the box at the top of the page fills in with the query that you could type into Google. It was our way of making visible the effects of advanced search operators.

This is extremely important, as it will help users get acquainted with power searches.  The syntax of power searches, once learned, can provide an easy way to find exactly what you’re looking for.  Knowing how to limit your searches to a certain site or to eliminate search terms can help zero in on what you are looking for.  I don’t know how many times I use that feature per day, but it significantly increases my work output when I am looking for how to do something.

The “visible query builder” fulfills two key things.  First, it provides a powerful tool for non-technical users to help decrease the time it takes to find what they are looking for.  Second, it can teach those users how to use power searches more quickly and easily each time they use the tool.  Eventually, it is hoped, they will be able to use power searches without relying on the crutch of the query builder.  This seems to be much like the approach of SQL query builders that have been around for a while.  Granted, it won’t streamline searching as much as the SQL builders have streamlined that process, but that’s in the nature of the beast.  It’s impossible to automate anything that requires user input, after all.

I like to see Google improve their products and make them more usable.  It’s also interesting to see the process they go through to improve.  This is why they are on top of the search market and if they keep up their current practices, they will stay on top for a while to come.

I have been a Half-Op (HOP) for an IRC channel that belongs to the World of Warcraft server I have played on for a while now. Currently I am using NoNameScript, an extension to the ever-popular mIRC that is the workhorse of Windows IRC clients. Most of the time I’m satisfied with its features and what is easily done with it. However, I curse mIRC Script and bring a plague upon both its houses.

It’s a complete nightmare to script in. Here’s an example of a simple part of a script that is used in a “no swearing” script that completely boggles my mind:

; When you are an op in #Dorvan and anything is said in the channel
on @*:text:*:#Dorvan:{
 var %swear = these,are,swear,words  ; The swear words to look for
 var %i = $numtok(%swear,44)         ; The number of words separated by commas
 var %u = 2                          ; The number violations before kick/ban
 while (%i) {                        ; While loop counting the number of words
   ... snip ...
 dec %i                            ; %i--
 }
 ... snip ...
}

Now let us start analyzing the significant eccentricities found in mIRC script.

on @*:TEXT:*:#Dorvan:{}

This little brick is one part that I don’t have too many complaints about. Given the nature of the program, this makes a fair amount of sense. It is saying “on receiving text in the channel #Dorvan, where you are a channel operator”, which is pretty self-explanatory. Here’s a breakdown for those a little more inexperienced in programming:

  • The @* section instructs that this block of code will only be executed if you are a Channel Operator (commonly denoted as @ in IRC clients) for the channel #Dorvan.
  • The TEXT section says that it will look for a TEXT event in the channel. This is actually an abstraction of the actual IRC message that denotes a user message. In RFC 1459, user messages are actually denoted as PRIVMSG <channel>; TEXT is an abstraction to make it easier to understand that you want any incoming text from another user.
  • The * says the code will execute regardless of what the text reads. A programmer can put a string there that will execute the code block if a user says that string. For this script, however, we have several substrings that we want to parse for.
  • The fourth parameter specifies what type of messages to look for. The actual parameter used in this demo will look for any message to the channel #Dorvan. Other choices would be # for any channel, ? for any query (message from peer-to-peer), or * for any received message.
  • Now we come to the first eccentricity that is throwing me through hoops. We have another parameter where one can specify a one line command or a | separated list of commands. Being primarily a Python and C++ programmer, I prefer to have individual commands on their own line; therefore I use the brace syntax. The funny thing about this is that you still have to include the fourth colon, so the syntax looks very odd. A small thing, I know, but little irksome things like that build up after a while.
var %swear = these,are,swear,words

The next line is pretty self-explanatory. It just declares a local variable named %swear. I know it should be a global, but the script was made to be distributed, and this is much easier to distribute as it’s all in one block of code.

var %i = $numtok(%swear,44)

The next line takes a little bit of explaining, I think. It sets a variable %i to the number of comma-delimited tokens in %swear. Yes, the 44 is the ASCII code for a comma. Why they can’t just use the string “,” is beyond me, but that is the convention the mIRC developers chose to use. In my opinion, this adversely affects both readability and writeability, unless one is very familiar with ASCII codes.

var %u = 2

A very self-explanatory line, all this does is set the local variable %u to 2.

while (%i) {}

A while loop would not be my first choice for this script; I wanted to use a for loop. However, mIRC script does not contain a for loop. Counter loops are just semantically cleaner for most iterative loops, and logical loops just aren’t as semantically “happy” for me in cases like this. I suppose it works and cuts down on the parsing needed for the scripting engine, but I wish counter loops existed in mIRC script.

dec %i

The last line I included is the command to decrement %i. inc and dec are interesting choices to me for these instructions. What ever happened to the good old ++ and –? Or even Python’s simpler x += 1 and x -= 1? Those choices would make more sense to me than this apparent “I’m going to try and be Lisp without the parenthesis” instruction.

There are many things about mIRC script that I just don’t like. This drove me to find an IRC client that is either written in Python or uses Python as its scripting language. Either would work for me. I like Python because programs just plain work with it. My professor is a big proponent of Python because it is easy to teach beginners, but powerful enough to use for full-fledged programs.

While looking for a Python IRC client, I realized how easy it actually is to create an IRC client in Python. For example, here is some code that will connect to an IRC server, join the channel #testserver, say “Hello, world.”, and then part and quit:

import socket
network = 'enter.a.network'
port = 6667
irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
irc.connect((network, port))
irc.send('NICK TestPy\r\n')
irc.send('USER TestPy TestPy TestPy :Python IRC\r\n')
irc.send('JOIN #testchannel\r\n')
irc.send('PRIVMSG #testchannel :Hello, world.\r\n')
irc.send('PART #testchannel\r\n')
irc.send('QUIT\r\n')
irc.close()

The ease of doing this got me thinking about writing my own IRC client. Handling the entirety of RFC 1459 is a semi-daunting task though, so I might start implementing and see how it goes.

I’m just wondering if there is a market for this outside of myself. On GNU/Linux, BSD and Mac OS X, a user can choose Konversation, KDE’s graphical IRC client. It supports shell scripts, Ruby, Python, Perl, Java, C++, C#, and Javascript for scripting. That’s quite a formidable list. Quite a formidable development team. Not something that a sane person would consider competing with. I’ve always wanted to start a project that people will use. Maybe one person other than me would use it. That will have to be good enough.

I got to thinking about software installation today. The reason for this is actually quite important to why this post is occurring in the first place. I was updating my system, which runs Gentoo Linux (and Windows XP) as its operating system. For those of you who have not used Gentoo, I will explain the packaging system Gentoo uses.

Gentoo is a so-called “meta distribution” of Linux. This term is used to describe how customizable the operating system is. The entire system is built from source, which means that there is essentially unlimited customization and optimization possible in a Gentoo system. The software that fetches the program source for compilation is called portage — this powerful software is the soul of Gentoo. It’s really quite amazing to use; to install a piece of software, one must only find its package name (made easy by tools like eix, which indexes the entire portage tree to be searched instantly) and enter one command into a console:

emerge [options] [package-name]

The software is then compiled and usable afterward. The first time I used Gentoo, I was amazed at the simplicity of installing software. No longer did I have to surf the Web to find the installer for a program and any dependencies needed. It was all easy-to-find and easy-to-do. It was super-powerful “yum”, which is the tool used to install packages on a number of other Linux distributions.

It wasn’t until later that I realized that this power came at a price.

Portage is amazingly powerful, but in this power resides its weakness. First of all, it takes an incredible amount of manpower to maintain the ebuilds, or packages of software, and each ebuild needs a maintainer. Since these maintainers are people who do this out of the goodness of their hearts, a lot of the time the ebuilds are not up-to-date or installing properly, at least for the lesser-known packages. Now to counter this, Gentoo has the best user community I have ever seen — rarely have I had a problem that has taken more than a quick search at the Gentoo Forums to fix. The second weakness of portage is one that is seen quite often with high-power, constantly-evolving software: it breaks. Often.

When I was updating my system this evening, it returned an error about the Manifest for a package being incorrect. When I was running Fluxbox, I was using a desklet system called aDesklets. One of the dependencies for aDesklets is Fontconfig, a library for font customization. The problem was that aDesklets depends on version 2.3.2-r1, while I have 2.4.2 installed as a dependency for 20+ packages. Since these packages are (well, the same thing, for one thing) meant to accomplish the same function, they occupy the same “slot” in portage. This makes portage try and downgrade Fontconfig to the version needed for aDesklets. The problem arises when the 20+ packages that need the new version of Fontconfig are to be emerged — the dependency isn’t there and portage knows it just downgraded the package; thus the error in the Manifest.

Now, it was a simple fix for me — I’m no longer using aDesklets, so I just unmerged the package and am currently running emerge -uDavN world (ask to verbosely emerge all packages in the “world” file, with the “upgrade”, “deep dependencies”, and “new” use flags) to update the 41 out-of-date packages I have. In a half hour or so, I will have a complete bleeding-edge system.

This whole debacle brought up a thought in my mind: why does software installation have to be so troublesome? Granted, for the most part it’s trouble-free and easy on most systems, but occasionally you have a program that just won’t install. For example, when Battlefield 2 came out, I went out to pick it up on the release date.

While I was readying to leave the store, my friend called me and said, “Hey, you haven’t bought Battlefield yet, right?”

“No,” I replied, “I’m just going to pay for it now.”

“Well, hang on for a minute or two. I’m having problems installing it.”

This friend is the most tech-savvy guy I know — when he has a problem, I listen. It turns out that the DVD-ROM he was using could not read the type of DVD media that EA used to print the games. He fixed the problem by cannibalizing an old 2x DVD-ROM out of what was then our game server.

But why did he have to do this in the first place? Shouldn’t that sort of thing be caught in quality assurance tests? One would think that a publisher as large as EA should be able to release a game that will at least install. (As it turns out, the game wasn’t ready for release in the first place, as a lot of major functionality was broken in the 1.0 version — but that’s another post.) Idealistically, yes, but in reality, it’s virtually impossible to test things on every kind of machine. The fact that my friend had a Sony DVD-ROM that couldn’t read this kind of media is not something that EA checked in their QA tests, apparently. It seems like a strange thing to miss, but it’s there.

With how necessary an activity software installation is, it seems we should know all the problems that could arise in the installation process and have counter-measures for these problems. The sad fact is that we don’t know all the problems and can’t fix some of them. That’s one thing that should be studied — how to improve the user experience by preventing “blockers” in the installation and configuration process. How this might be accomplished, I don’t know — but it’s something I would be interested in studying. After all, aren’t users the most important part of software?