Sunday, November 14, 2010

Me and Aunt Marge

I'm hopeless. I'm an old, narrow-sighted, rigid UNIX-school developer. I will never be able to raise above the cultural differences between Windows and UNIX. Let's face it - I don't like Microsoft. After finally reading Joel Spolsky's article on Biculturalism I can appreciate the reasons behind the "Microsoft culture" but I guess I'll never be able to associate myself with it.

My wife has recently completed a course on VBA in Excel. A couple of days ago she suggested we sit together and try to implement something. Well, I thought it would be fun. If only I knew how wrong I was!

Now, what bothers me is that if Joel is right about this "Aunt Marge" philosophy, I wonder how it applies to VBA in Excel. Right, my wife is an accountant, not a programmer. But programming macros in VBA is as close to programming in a non-programmers' world as one could possibly think. Let's put it this way - I would be surprised to see this application in the Aunt Marge's toolbar (unless she has dragged it there by mistake).

Anyway, we opened Excel and started. Here's a spec of what we intended to do. In a certain column, find a cell that matches a certain template - this indicates a start of a section. A table is expected to be located two rows below this number. The table is concluded with a "total" line. Copy the initial number and the "total" to a new row in the second sheet. Repeat the search process until the end of the sheet, adding another row to the second sheet every time. Fairly simple.

Well, as a programmer having plenty of the first virtue, I assumed there must be a function that finds a cell matching a certain pattern. So I opened the Help and searched for 'find regular expression'. Great - here's a Find function! I'm starting to write the VB code, but when I hit the opening parenthesis I pay attention that the parameters in the tooltip do not exactly match, so to say, the parameters in Help. It took me a while to realize that there is more than one version of Find. No problem, I tried to locate another. Didn't work out. What does a frustrated programmer do these days? Google it! Surely, within a second I was able to find an article about the "correct" Find method.

Now, it seems that Microsoft developers have decided that since most of the programmers use Google anyway, API reference is no longer necessary. The internet's article hinted that in order to look for a regular expression, one should use the parameter "SearchFormat". Excel's help gives the following information about this parameter: SearchFormat - Optional - Variant. Description - "The search format". Duh! It's great they use a word breaker for automatically producing help files. Surely, no more light is shed on the mysterious "Variant" parameter in the Remarks section. And I'm not mentioning that the syntax of regular expressions is nowhere to be found. Oh, sorry, I forgot - Aunt Marge doesn't need those!

On the other hand, the mentioned Remarks section contains an absolutely remarkable (sorry for a wordplay) note that has shaken my concepts of good and evil. The values for the various optional parameters are saved each time you use this method. Which means that if you don't specify their values on the second invocation, the values from the first one are used! It seems that the designers of this particular piece have never heard of the Principle of Least Astonishment.

This is actually a very good proof of the Joel Spolsky theory. This behavior stems from pure GUI thinking. It's perfect for humans to have their previous choices remembered. For programmers it's disastrous because it makes the behavior unpredictable. I can bet there's a corresponding UI dialog for this Find function and it's simply a bad design to have this logic anywhere lower than the UI layer. But the Microsoft's culture is so "Aunt Marge" oriented that perhaps they simply don't have enough people who know how to write software for developers.

I'm ashamed to admit that I gave up trying to make this Find method work for me and resorted to some hand-made search with a While loop. Each one of us has his limits, sorry.

By the way, one of the times I desperately hit F1 brought me a third version of Find - something completely different! Which reminded me why back in 1999 I fell in love with Java. In Java there is only one type representing a sequence of characters - String. Young programmers who haven't seen the Win32-COM-MFC-ATL nightmare won't understand what I'm talking about. But those who remember words like char*, wchar_t*, TCHAR*, LPCTSTR, CString, CComStr, BSTR etc. would be nodding in agreement. Ah, yes, there was also an OleString. Wasn't it? Never mind. I'm sure every single one of those had its rightful raison d'ĂȘtre. But could someone please tell me what does it have to do with Aunt Marge?

Thursday, November 11, 2010

About usability

Recently I became concerned with the usability of the software we write. I came to it from two different perspectives in parallel. First, I have recently moved from one project to another. Being a newcomer, it's easy to criticize the product. It's also a rare chance because after a couple of weeks one gets used to various nuisances. They call it a fresh look.

The second perspective is much more narrow but is much easier to use for the demonstration. At my leisure time I'm developing a small Java application for my Nokia N97. A small thing that records a track using the built-in GPS and exports it in the GPX format. Just to prevent a flood of comments - I know there are dozens of application doing just this. But this one is mine - I like it, I can add little features to it and it also gives me a little insight into the J2ME world. Just for the fun of it.

However, this small application continues to teach me usability lessons. It's amazing how easy it is to write a "regular" application and what it takes to plan a really easy-to-use one.

As an excuse, I have to say that at first I did download some application for track recording, but didn't quite like it (usability-wise). This is what brought me to making my own. The sad thing is that the approach of that application "spoiled" me - I only "improved" it here and there but didn't change the whole concept.

A couple of examples to demonstrate what I mean. The first "working" version of my application constantly displayed the latitude and longitude, altitude and their respective accuracies (the numbers GPS has to offer). There was a "Start" button that changed the display to two text fields, "Name" and "Description". Name was mandatory but had a default value "Track", Description was optional. After entering the name one had to press "Start" again to actually start the recording. Then the application started accumulating points. Later, when the "Finish" button (displaying instead of the "Start") was pressed, the application dumped the file.

It took me a while to realize a number of problems with this approach. First, it doesn't make sense to accumulate points in memory when the application may start writing them to the file immediately. Apart from memory optimization, it's a huge improvement in usability. For one part, since I still didn't find out how to sign the midlet, there's an annoying security confirmation dialog popping up whenever the application is trying to open the file for writing. It's better to display it right away than to delay it to the end. Another immediate benefit is that now pressing "Finish" takes no time - the file is written already and the application only needs to close it properly. Finally, if the application gets stuck (unfortunately, it happens once in a while for some obscure reason), the part of the track accumulated before the lock-up doesn't get lost.

When trying to "reverse-engineer" why on Earth didn't I do it from the beginning, I recalled that in the original application there was a feature of adding waypoints along the way. In GPX, they have to be written in the beginning of the file, so the program has to defer the writing until all waypoints are known (which doesn't happen until the end of the recording). However, even if I decide to add this feature, it still makes sense to write the file along the way and store the waypoints in memory instead. When the track is finished, rewrite the file (if any waypoints have been added). By the way, this is a typical example of how a marginal feature has the potential of destroying the main flow. We, programmers, spend so much time with computers that we got used to think like them - 'then' is no different from 'else'. For humans it makes all the difference.

Another observation has to do with the fact that the phone is not a small computer. Well, technically it is, but not as far as the user is concerned. The user of the phone doesn't like using the keyboard! Even on N97 with full "qwerty" the keys are smaller than thumbs. However, in my first version the user had to change the default value for the track name - otherwise the previous one would get overwritten. An additional consideration is that the recorded track is later transferred to the computer anyway and may be easily edited there. So practically it doesn't matter what name is given to the track at the time of recording. From here the solution is obvious - give it a unique name automatically! The best is to encode the date and time so it would be easy to identify it later. In the current version I still display the "name-description" dialog, but I believe this should be removed altogether. I never entered a description and after having changed the default of the name to be unique I don't edit it either.

Here goes the last one (at least for now). After a couple of uses I realized that apart from the fact that they constantly change (and thus indicate that the application still works), the latitude and longitude numbers do not make any sense. On the other hand, on my trips I usually have a large-scale map and would love to make sure I am indeed at the point I think I am. Which made me find the formulae for calculating the "Transverse Mercator" projection coordinates (in practical words, the new Israeli coordinates network). So my current version displays these numbers instead, which is much more useful.

Surely, I'm rediscovering the wheel - Apple have understood for a long time already the difference between a regular product and a "great" one. Still, it's funny to watch this on a small and distilled example. Think usability!