Tuesday, October 02, 2007

Problems Embedding Google Maps in Blogger

I decided to add embedded Google Maps showing routes to some of my recent Sustainable Adventure posts but I had some problems.

First, it's quite hard to get the zoom/scale to come up properly on the embedded map. It would either be zoomed out too far or zoomed in too far. Presumably the zoom in the embedded map is related to the zoom when you ask for the link/embed code, but there doesn't seem to be a simple correlation. With trial and error, zooming in and out and resizing the window, I could usually get it more or less right.

In some cases it seemed to help to copy the link address, open a new tab/window and go to that address. I'm not sure why that would help. Maybe it was just coincidence that it happened to work after doing that.

One of my maps refused to show the route. The map itself would display (although missing one tile). Eventually, after playing with it and making a minor change to the route it started working. (I gave up on trying to get the zoom right on this one, I was happy enough to just get it to work.)

It's sad how much the success of an "expert user" comes down to trial and error and randomly poking things. The equivalent of kicking the machine. Isn't software supposed to be consistent and predictable? The problem is that if the software gets complex enough (as most software is this days) then it becomes impossible to control/know all the inputs and state, so it ends up seeming random, unpredictable, and inconsistent. Yuck!

I searched for other people having this problem but I didn't find much. Is it something I'm doing different? Issues related to Blogger? But lots of people use Blogger. Maybe I just didn't hit on the right search terms.

Thursday, September 27, 2007

More Mac & Parallels Printing Problems

This is a continuation of the saga I've posted about before.

Recap: I had moved my Epson R1800 printer to Firewire to free up the USB port. But then I found out Parallels doesn't virtualize Firewire.

So I moved the printer back to USB. Things seem ok. Some time later I go to print from Lightroom and I find that I'm back to the CUPS+Gutenprint printer driver which doesn't support all the printer features. I'm not sure how that happened since before the USB->Firewire switch it was using the Epson driver.

More time passes and I go to print from Windows under Parallels. The print job goes into the queue and gets stuck. I can't even delete the print job or the printer. I try disconnecting and reconnecting the USB port to the Parallels VM. I try rebooting Windows. I try rebooting the Mac. At some point during this thrashing my print job comes out and the printer deletes. I recreate the printer, thinking that it's now going to work, but my test gets stuck in the queue as before. I thrash some more, but can't seem to hit on whatever combination it was that released that first print job.

I search on the web and find various discussions of various problems more or less related to mine. One person says it takes 5 minutes for his print jobs to emerge. Maybe this was what happened with me - not anything I did while thrashing, just the amount of time I thrashed. It seems bizarre that it would take 5 minutes. What is it doing all that time? And why does it work after whatever it is doing?

I had gotten an error message about the Epson Status Monitor 3 (why 3?) and some of the discussions mentioned this. I tried disabling it and killing it etc. but it didn't seem to make much difference.

The strange thing is that I could swear I had the printer working from Windows via USB before I switched to Firewire. So why doesn't it work now? Changes to Parallels? Who knows.

Eventually I found Finally got Epson Photo R800 printer working in XP VM on the Parallels forums. (an R800 is the narrow carriage version of my R1800) It gave instructions on how to share the printer from OS X and then access it using Bonjour on Windows. I had run across references to this before but they all talked about using a generic postscript driver on Windows which is not what I wanted. I needed to use the Epson driver to access the printers features. But these instructions used the Epson driver.

The instructions were for the printer connected by USB but they mentioned they would likely work with Firewire. Since that's what I really wanted I thought I'd try it. Nope, couldn't get it to work. (no URI for Firewire device?) Back to USB. This time it worked.

The only place where I had problems with the instructions was with choosing the printer type. Bonjour only showed the generic postscript option. I had to choose Have Disk and then find and select my Epson driver.

Several hours later, I think I have the correct, functioning printer setup in both OS X and Windows. And even better, I think I should now be able to use the same method to access the printer from other networked Windows machines.

A few days ago someone suggested buying a MacBook for someone else. I said it probably wasn't a good idea because they'd want to run Windows programs. They said "I thought you could do that now?". Yeah, well, you can, but ... it can get ugly.

Monday, September 10, 2007

School

Paul Graham's latest post, News from the Front, was irrationally comforting.

I've often wondered if I should have taken a high school biology teacher's advice and applied to somewhere like MIT. My life obviously would have been very different, but also, obviously, it wouldn't have made me any smarter. Heck, I didn't even finish university, and I don't think that has hurt me any either. (Aside from my father's disappointment, and even he came around.)

On the other hand, I might have met different people by being somewhere more "active" than the middle of nowhere in the Saskatchewan prairies.

I don't have any regrets, but it's interesting to wonder about.

Monday, August 27, 2007

Holding a Program in One's Head

Another good essay by Paul Graham:

Holding a Program in One's Head

I'm not sure I totally agree with this part:
Don't have multiple people editing the same piece of code. You never understand other people's code as well as your own. No matter how thoroughly you've read it, you've only read it, not written it. So if a piece of code is written by multiple authors, none of them understand it as well as a single author would.
...
If you want to put several people to work on a project, divide it into components and give each to one person.
I agree you can never understand someone else's code as well as your own. Initially, this is probably good advice, although, even initially, pair programming can be worthwhile. But in the long run, multiple people are going to need to work on the same code. Of course, by this stage it's not in anyone's head anymore anyway.

Monday, August 20, 2007

Web Mail

I'm surprised that so many people put up with the annoying ads inserted into their email by Yahoo Mail and Microsoft Hotmail. When I started using Gmail I never really thought about this issue, but now I'm very thankful that Google doesn't do this kind of advertising.

I guess if you're just using your email for unimportant stuff it's not a big deal. But when you're using it to apply for jobs, or for your work, do you really want stuff like this on your messages?
Moody friends. Drama queens. Your life? Nope! - their life, your story. Play Sims Stories at Yahoo! Games.
or:
Windows Live Hotmail. Even hotter than before. Get a better look now.
I would guess one reason people don't object is that they don't see it when they're sending a message.

I realize this kind of "viral" marketing can be effective, and when Hotmail first did it, it was a clever thing to do. But nowadays, I just find it offensive. Of course, I find TV commercials offensive too and that won't stop them doing it.

In any case, I'm glad Google doesn't do it. They do some "viral" marketing by suggesting you invite people to join Gmail, but it's fairly unobtrusive. And the ads they show beside Gmail are easy to ignore as well. (And fairly easy to block if you really want to.) And these things are only shown to me, the person getting the free service, rather than to people I'm sending messages to, who shouldn't have to "pay" for my service by viewing ads!

Interestingly, Google, who made a big splash by offering 1 gb of Gmail storage when most people were offering measly amounts like 10mb, is now offering the least amount of storage - "only" 2.8 gb compared to unlimited for Yahoo and AOL, and 5 gb for Hotmail. more...

Tuesday, August 14, 2007

Jing

This looks interesting:

Jing Project: Visual conversation starts here. Mac or Windows.

Watch the video tour for a quick introduction.

It's from Techsmith who make Snagit and Camtasia - products we use.

Wednesday, August 08, 2007

Parallels Annoyance

I went to print from Windows running under Parallels on my Mac and it didn't work, although it had in the past. I tried the usual highly intelligent :-) problem solving technique of rebooting (in this case both Windows and the Mac) but it didn't help.

Eventually I remembered that I had switched the printer from USB to Firewire, since the printer (Epson R1800) had come with a Firewire cable and it freed up a USB port.

But ... Parallels doesn't virtualize Firewire, only USB. There are several workarounds but none of them are great since they don't let me use the specific features of the printer.

Now something else made sense. I had wondered why I had an HP postscript printer set up in Windows. I hadn't set it up myself so I assumed some application I had installed had done it, although that didn't make much sense. Now I realize Parallels must have created it as a way to print to Mac printers.

Another workaround is to print to PDF on Windows and then print the PDF from OS X - a bit tedious, but it works.

I may end up moving the printer back to USB, but that'll mean messing with the setup on OS X which I'd rather not have to do.

The reason I wanted to print from Windows was because I was using Canvas, a program that combines many of the capabilities of Photoshop and Illustrator (i.e. both vector and bitmap at the same time). I really like Canvas but it's been somewhat abandoned. The product was bought by ACD who haven't done much with it. There was/is a Mac version but not for Intel, so I'm still using the Windows version. There are rumors of a new Windows version but not Mac. Too bad.

Windows Live Writer

 I'm writing this using the Windows Live Writer beta. Tim Bray has mentioned it a few times in his ongoing blog.

I haven't really felt the need for a separate tool to write blog posts - doing it in the browser seems to work well enough, especially with the real-time spell check in Firefox. But I can't resist trying out new free software :-)

I added this screen shot to test inserting images. That's one area where Blogger can be a bit awkward.

[screenshot removed to allow publishing]

It also looks like you can add tables which I don't think Blogger allows (unless you edit the HTML directly).

Humorously, Live Writer shows "Firefox" as a spelling mistake. (but "Blogger" is ok)

So much for images. When I tried to publish it said "the weblog does not support image publishing". Blogger certainly allows images, so I would interpret that to mean that Live Writer's interface to Blogger doesn't handle images. It did offer to let me configure an FTP site but I wonder how "user friendly" that is for most people. I assume if you use Microsoft Live Spaces for your blog then you can publish images.

Friday, August 03, 2007

Alarming Development : Beautiful Code

Sadly, I would have to agree with this:

Alarming Development : Beautiful Code

But that won't stop me from reading the book, we can still dream of beautiful code :-)

Thursday, July 12, 2007

Tagging

I find tagging really attractive as an alternative to strictly hierarchical categories. My main uses of tagging are in del.icio.us, LibraryThing, and Lightroom. Picasa, that I used to use before Lightroom, also has a form of tagging, but it never seemed very "natural" to use it there, probably because it's not very well implemented. Flickr is another big user of tagging, but for some reason I've never gotten into using Flickr much.

Tagging, especially in sites like del.icio.us and Flickr, is often promoted as a "social" tool. I've never really used it that way, maybe because I'm not much of a "social" person :-) Of course, I've benefited to some extent from other people's tagging, but that's never been my main benefit. I primarily use del.icio.us to maintain my personal bookmarks.

As far as implementation, del.icio.us has a nice system, especially for web based software. It shows you all your tags, auto-suggests as you type, shows recommended tags, and popular tags. I have wondered why they "hide" the popular tags (ones other people have used) down at the bottom of the page. I guess this is to avoid the problem of people just applying the same tags as everyone else, which would somewhat defeat the purpose of having a wide variety of people applying tags.

LibraryThing's tagging could definitely be improved. You often have to type tags just from memory, with no auto-completion or suggestions. A system more like del.icio.us would be a lot nicer.

Lightroom has auto-completion and lets you drag and drop tags, but its unique feature (at least, I haven't seen it anywhere else) is its "implied tags". A common issue with tagging is what level of detail to tag at, and how many tags to apply. For example, do I tag with "Saskatoon", or "Saskatchewan", or "Canada", or "North America" or several of these. Similarly, do I tag with "pelican", "birds", or "animals". Ideally (for searching) you'd apply all the relevant tags, but that would make tagging a tedious process. Lightroom lets you create tags as children of other tags, so "Saskatoon" is a child of "Saskatchewan" which is a child of "Canada". You manually apply the most specific tag, e.g. "Saskatoon" and the parent tags are automatically "implied". So if I search for "Saskatchewan", I'll automatically get anything I tagged with "Saskatoon". Very nice. I would like the same feature in del.icio.us and LibraryThing.

On this same topic, I listened to a Long Now talk by Clay Shirky on my run this morning. He was talking about the problems of hierarchical categorization, how it is mainly a result of having to organize physical materials, and that tagging is better suited for digital information.

Also on basically the same topic, I am currently reading Everything is Miscellaneous by David Weinberger (who also co-wrote The Cluetrain Manifesto). It makes many of the same points.

So it seems a little incongruous that a hierarchical system can make tagging better. Of course, in a way it's just a shortcut for entering tags, it doesn't really alter the tagging. And I wonder if the hierarchical part is really essential. At first when I saw "implied tags" in Lightroom, I wasn't thinking of a hierarchy, I just thought that one tag could imply others. But that could be tricky to handle since it would allow loops and if not used "properly" could end up with a mess. But it would be interesting to try.

I keep thinking there should be some way to apply tagging to our business software, but so far I haven't come up with anything really appealing. We could allow tagging things like equipment, but I'm not sure whether that would be a big benefit. Maybe we should try it and see whether people like it. Maybe we could replace things like "Type" and "Role" with more general tagging.

Wednesday, July 11, 2007

Font Rendering!

Here's more than you probably wanted to know about font rendering and why Windows, Mac, Linux, and Adobe Reader are different.

Texts Rasterization Exposures

I found this via Joel Spolsky in connection with his earlier post:

Font smoothing, anti-aliasing, and sub-pixel rendering

I'm afraid most of the time I don't even notice these fine details. But I have struggled with text sizes and layout issues in Windows. And really bad rendering can be quite annoying - Open Office (on Windows) used to be pretty bad.

Tuesday, July 10, 2007

New MacBook


My new MacBook arrived today. I tried to buy one locally, but no one had the model I wanted (a black 13" with 2gb ram and 160gb drive). I decided I might as well order it from Apple myself rather than get a store to order it. I ordered Thursday afternoon and it arrived Tuesday morning. Pretty fast. I also ordered a spare battery and it arrived at the same time.

I've been thinking about getting a MacBook for quite a while. Working on my old Windows laptop the other day and finding it quite slow tipped me over the edge to order the Mac.

As I would expect from Apple, the experience of opening the box and setting it up was a delight. I really like the little touches like the charge indicator on the batteries and the magnetic power connector.

The only (minor) problem I had was that I couldn't enter the key for my wireless connection from the setup process. I had to choose "no network" and then configure it later. No big deal.

I still have some setup to do to get things the way I want (e.g. installing Parallels) but so far, so good.

Thursday, July 05, 2007

New Network Hard Drive

With both Mac and Windows machines on my home network I decided I wanted some shared storage that they could all access equally. I can access shared directories on the Windows machine from the Mac (haven't tried the reverse). But that means I have to turn on the Windows machine. And it doesn't give the Windows machine any backup storage.

I looked at various possibilities but looking for something that explicitly supported Mac narrowed the choices. I ended up with a 320gb Lacie ethernet disk mini ordered through Frontier PC. I hadn't dealt with them before but they looked like a reasonable choice for a Canadian supplier. There were no problems dealing with them and shortly I had my drive.

I plugged it into my wireless router and it "just worked". It even came with a network cable.

I had no problem accessing it from Windows and it wasn't much harder from the Mac. The problem with the Mac was trying to get it to connect at start-up. On Windows this is a simple matter of a checkbox, and from the web I understand Mac OS 9 was the same. But not anymore. I found various suggested solutions, none of them simple or easy. One problem was how to supply the user and password for accessing the drive. In the end I used Automator. The funny part was that for all it's fancy drag-and-drop graphical workflow, it all came down to getting the right cryptic url. In other words, Automator ended up being window dressing on a command line.

In case any one is tackling a similar problem, what I ended up with was a "Get Specified Servers" action followed by a "Connect to Servers" action. The url for the "Get Specified Servers" needed to be "afp://user:password@ipaddress/sharename" with the appropriate user, password, and numeric ip address.

The other trick is actually getting it to run when you log in. Again, Windows seems simpler (but maybe just because it's more familiar), you just put stuff in the Startup folder. On OS X you do it through System Preferences > Accounts > Login Items - not exactly easily discoverable.

Originally I had thought I would keep the master copies of my music and photo libraries on the shared drive so I could access it from any of my computers. But this didn't work too well. For example, if the network drive was disconnected for any reason (as it often was when I was first struggling to get the connect at log in to work) then Adobe Lightroom would recognize (rightly) that the files were not available. The problem was when the network drive was reconnected, Lightroom would start checking the availability of the files - roughly 10,000 of them, one at a time - not a speedy process!

So now I'm mainly using the network drive as a backup. My next plan is to come up with a way to sync my music and photos between the Mac and the network drive, possibly using ChronoSync which I saw recommended.

One feature that I don't have on the Lacie drive is the ability to run the SlimServer for my SqueezeBox. Currently I am running the server software on my Windows machine - but that means it has to be turned on if I want to play music. Theoretically it should be possible since the Lacie runs Linux and there is a Linux version of SlimServer, but I couldn't find anything on the web about how to do it. It does support UPnP A/V but unfortunately the SqueezeBox won't accept that. It's the usual trials and tribulations of trying to get things to work together.

Friday, June 08, 2007

Slow Code Again

Although I agree with Larry's view, at the same time I continue to be horrified by some of the code I come across. There's no question premature optimization is bad, but I have to think so is code that blatantly disregards and abuses speed issues.

For some time I have been meaning to look at the start up process for our application. There was no particular reason for this - no one had been complaining. But speed of start up is one of the first things people encounter and first impressions can be important. And we had had some complaints and found some problems with opening the help being slow, and some of the code is similar.

The first thing I looked at was database queries since they often dominate speed issues. I turned on the query tracing during startup and to my horror, ended up with 1800 lines of query trace! At first I thought that was 1800 queries, but there are multiple lines per query so it was actually only about 600 queries. It's a testament to the speed of computers and networks these days, that this doesn't even result in a noticeable slowdown. Although I think we did have one customer complain that after restarting their server, when all the users tried to log back in all at once, it was slow. I can understand why! Of course, we discounted it, thinking that, of course it'll be slow.

I have various ideas for reducing these startup queries, but I was able to cut them in half within a few minutes. Most of these queries are reading the menu tree for the application. At the same time it is checking for any menu options that are "hidden" (e.g. not purchased by that customer). To do this, the code was calling a general purpose permissions function which did queries on the permission table. But in this case all we needed to know was whether an option was hidden, which depended only on some configuration data in the code. We had a more specific function that only checked the configuration so switching to call this (didn't even need to change the arguments!) instantly eliminated almost half (about 300) of the queries.

I don't give this as an example of someone "screwing up". We all make mistakes or overlook things. The lesson that I take from it is that it's not enough to write some code and have it appear to work. You have to assume that there are always hidden problems and that you need to constantly be on the lookout for them. And constantly fighting entropy by fixing and refactoring.

See also my previous post on Slow Code

Bad Documentation

The easiest way to write software documentation is:
Date Field
Enter the date.

Rate Field
Enter the rate.
Needless to say this is very obviously useless. And it's actually worse than useless because any useful information is buried deeply in masses of this garbage. No one would actually write this kind of stuff, would they? Yes, they would and do. And in an amazing example of how we can justify justify anything to ourselves, writers of this kind of documentation actually appear to believe they have produced something useful. (Of course, if someone else had written it, that same person would have no problem recognizing it as useless.)

Of course, it's often thinly disguised. Here are some examples (from real documentation I was given yesterday):
In the Type field, choose the Type this record applies to.

Tab to the Fleet field. Choose the correct Fleet.

Tab to the Abbreviation field and enter the Abbreviation.
I'm sure you get the idea.

The problem is that to write useful documentation is orders of magnitude harder. It requires you to think. You need to decide who the documentation is for, what you hope to achieve with it, what things people need to be told, and just as importantly, what things they do not need to be told.

I think another factor is that people hate to leave "gaps". Rather than just describe the few fields that you actually have something worthwhile to say about, they feel they have to say something about every single field. And this is not just obsessive-compulsive people - almost everyone seems to feel uncomfortable about "leaving out" some fields.

Google Desktop versus Mac Spotlight versus Vista

One thing that frustrated me when I started using Google Desktop Search was that I would type my search, it would correctly identify and highlight the top result, but when I hit Enter it would open my browser and show me the search results there (instead of just running/opening the top result). Eventually I discovered you could change this in the Preferences "Launch Programs by Default" (instead of "Search by Default").

I guess I should mention that I use Desktop Search as much or more to launch programs rather than find files. My Windows Start menu has so many programs on it that it is a hassle to use.

Now I have the same hassle on my Mac. Spotlight finds the right result, but when I hit Enter it brings up a search window instead of running the top result. Unfortunately, so far I have not found a setting to change this. It hasn't been too annoying yet because I don't have as much software installed on my Mac so I don't need to use it as much.

As much as I like to dislike Microsoft, they appear to have got this right in Vista. The new search box defaults to running the top result when you hit Enter.

I wonder how Beagle on Linux works in this respect?

PS. I normally have my Google Desktop set to show on my Windows task bar, but today it was missing. I thought it must have crashed or something so I rebooted. But still no search box. I checked whether it was still set to run on startup but that looked ok. When I tried running it manually from the Start menu it displayed in "pop up" mode, but came up so fast it must have already been running. When I checked my preferences I found it was set to not show up. I'm pretty sure I never changed this, so I'm not sure what happened. Maybe some automatic update turned this off?

Tuesday, June 05, 2007

Chapters web site annoyance

Lately I've been ordering from Chapters more often than Amazon because they seem to have more books in stock and deliver them more quickly. (This is in Canada i.e. amazon.ca)

But one part of ordering from Chapters really bugs me. Their web site does not understand that billing address belongs to the credit card. I order books both for work and personally. The billing address for my work credit card is different from the billing address for my personal credit card. Amazon handles this automatically. But Chapters not only doesn't handle this automatically, it makes me type in the address every time I switch between business/personal. They store multiple shipping addresses and multiple credit cards and let me pick from them rather than type them in, but apparently they only store a single billing address.

I guess I could set up a second account but I've got enough different accounts to keep track of!

It scares me to wonder how many similar annoyances our applications have that we're either unaware of or are ignoring.

Stevey's Blog Rants: The Next Big Language

An interesting (and cynically humorous) article about programming languages:

Stevey's Blog Rants: The Next Big Language

Sunday, June 03, 2007

Adobe Lightroom

I continue to be impressed with Adobe Lightroom. Like Tim Bray, although I prefer open source software, I can't help but like Lightroom.

I was also impressed by The Adobe Photoshop Lightroom Book by Martin English. Usually I'm not that impressed with books on how to use software. They're either reference manuals or beginner's guides. This book is neither. It gives helpful advice, covers both basics and more advanced features, and is full of examples and annotated screen-shots. Lightroom was designed to be "simple to use". But it still has a ton of features, so "simple to use" means lots of non-obvious features - like things you can click on or drag. The book helped me discover these a lot faster than I would have on my own.

One of the reasons I like Lightroom is that there are lots of innovative user interface features. It's not "eye candy" - the UI is very subdued black and grey (after all what's important is your pictures, not the software) Even if you're not interested in digital photography, I'd recommend spending some time with the trial version just to see how the UI works, although you may not discover all the features in a short test. The UI has already inspired some improvements in Suneido.

Thursday, May 31, 2007

Windows GetSaveFileName Frustration

GetSaveFileName is a Windows API call that displays a standard save file dialog. It has an option to specify a default file name extension that will be added if the user doesn't type one. (lpstrDefExt in the OPENFILENAME struct)

For some reason, this wasn't working. I wasted a bunch of time checking all my code and searching for known problems on the internet with no success.

Then I tried it again and suddenly it worked! But I hadn't changed anything!

Aha! I had changed something - I had typed a different file name. The problem is that if the name you type (with no extension) exists, then it doesn't add the extension. (e.g. I was typing "test" and I had an existing file called "test", with no extension) I guess it assumes that you are "picking" the existing file, even though I was typing it, not picking it from a list.

MSDN contains a huge amount of documentation, but all it takes is one little missing detail and you're in trouble.

Monday, May 28, 2007

LINA portable applications

It's not released yet, but LINA looks like a really interesting project that enables you to run the same binaries on Linux, Windows, and Mac with native look and feel.

Sunday, May 13, 2007

Inside the Machine

I've been reading Inside the Machine by Jon Stokes - An Illustrated Introduction to Microprocessors and Computer Architecture. It looks at Intel, IBM Power PC, and Motorola chips (i.e the ones used in PC's and Mac's), including the latest Core 2 Duo chips.

I'm not much of a hardware person these days, but it was pretty interesting to read about the techniques used to push performance. Apart from bigger caches, I had wondered how modern CPU's used the 100's of millions of transistors they now contain. (A Core 2 Duo has 291 million transistors as compared to the original Pentium's 3 million.)

Considering the subject, the book is well written and easy to read. If you're at all interested in this area, I'd recommend it.

Google Sketchup

Google Sketchup is a free 3D design tool (there's also a Pro version that costs money). I haven't got a particular use for it, but I thought I'd check it out. Here is the results of my first 10 minutes with it:
You can put your Sketchup models onto Google Earth.

Thursday, May 03, 2007

Threading Horrors

Just when I was starting to think that it might not be too bad to make Suneido multi-threaded...

Quick overview of how processes exit on Windows XP

I like this part:
Note that I just refer to it as the way processes exit on Windows XP rather than saying that it is how process exit is designed. As one of my colleagues put it, "Using the word design to describe this is like using the term swimming pool to refer to a puddle in your garden."
I'm not familiar enough with Linux to know how it compares, but even if it is much "cleaner" I suspect it still has it's own "gotchas".

Fields, Controls, & Context

In Suneido, a field has an associated control. For example, if the field is "category" the control might be a pull down list of categories.

For the most part this works well. The problem is that in certain contexts you want a different control or to modify the behavior of the control slightly.

For example, when you are entering new categories it doesn't make any sense to have a control that only lets you choose from existing ones. Actually, you probably want the opposite - to validate that what you enter is not an existing category (i.e. a duplicate).

These are the two main contexts - creating and using.

Once you use a category, possibly as a foreign key, you don't normally want to delete it. But business changes and you may not want to use a category any longer, in which case you don't want it showing up in lists to choose from. We would usually do this by adding an "active/inactive" flag to the categories.

However, when you go to view or modify old data, you don't want it to become invalid because it uses a category that was later marked "inactive".

One solution is to record the date when the category became inactive and so it can be valid for data prior to that date, but invalid after that date. But this means either you make the user enter the date when it became inactive (extra work for the user) or use the current date when they mark it as invalid (but that may not be the right date). The other problem is that if the record where it's used either doesn't have a date, or has several dates, then it becomes hard to apply this. (We use this solution in certain cases where it "makes sense" to users e.g. a termination date on an employee.)

The solution we normally use is to make the inactive categories valid in existing data, but only allow active categories on new data. If there is a list to choose from, it would only show the active categories, on the assumption that you're picking for new data.

This splits the "using" context into "using on existing data" and "using on new data".

But when we come to reports (or queries) there is another problem. If you are printing a report on old data, you want to be able to select currently inactive categories. But at the same time, if you pull down a list of categories on the report options you don't really want to see every category that has ever existed. Most of the time you're printing current data and you only want to choose from the active categories.

Our normal "compromise" on reports is that lists to choose from only show active categories, but the validation will allow you to type in an inactive category.

Another alternative might be to add an option (e.g. a checkbox) to the pull down lists that lets you show/hide inactive categories.

If you use an "inactive as of" date, you still have this problem. You can't use the transaction dates because you're printing a range of dates and different categories will be active for different transactions.

So we now have four contexts:
  • creating - no list to choose from, duplicates are invalid
  • using on "old" data - inactive values are valid for existing data
  • using on "new" data - only active values are valid
  • using in report selections - allow entering inactive values
"creating" requires a completely different control. The various forms of "using" can be the same control (with a list to choose from active categories), but with different options that affect what is "valid".

Currently, Suneido associates a field with a control by the field name. We normally make the "default" control one that handles the "using on old/new data" context. For creating and reports we rename the field to get different controls.

A better approach might be to make the context more explicit. You could allow associating multiple controls with a field name, based on the context. Or the control could be aware of its context and adjust its behavior accordingly. (We partially do this to handle the "using on old data" versus "using on new data" contexts.)

I'm curious how other user interface systems handle these issues. It wouldn't be hard to get a copy of e.g. QuickBooks and see how they address these issues (assuming they do). It's not something that I have seen written up in any of the user interface guides that I've read.

Monday, April 30, 2007

Embedding Google My Maps

Here's a useful tool for embedding the maps you create with Google My Maps:

http://www.dr2ooo.com/tools/maps/

Here's an example:

http://sustainableadventure.blogspot.com/2007/04/eagle-creek-paddle.html

The embedded map actually uses the dr2000 web site so I'm not sure about the long term stability. Presumably it's not too hard to do this yourself, but I haven't figured that out yet.

Wednesday, April 25, 2007

Custom Google Maps

Google Maps recently added the ability to put points and routes onto Google Maps and save the results. It's really easy to use. You can even attach photos or videos. (Note: you'll need a Google account, if you use Gmail you already have one, if not, it's free and easy to register.)

For example, here's one of my regular running routes:

Saskatoon Running Route

Of course, it can be used for a lot of other things - check out some of their featured maps.

Friday, April 20, 2007

Mac + printers

Ever since I got my Mac Mini I've been struggling with the printer issue. I have an Epson 2200 hooked up to a Windows machine. It took a fair bit of research to figure out how to connect to it from OS X, but I finally managed it. It is supposed to be easy, but it looks like a lot of people have problems. But I could only use the Gutenprint (formerly Gimp-Print) drivers which don't support all the features of the printer.

I downloaded the latest Mac OS X drivers from Epson, but I couldn't see how to use them. Finally I found out that you can't use USB drivers on a networked printer. This seems like a strange distinction - on Windows I can use the same drivers whether the printer is connected directly or networked. Maybe it works if the printer is shared from another Mac - I don't have two Mac's to try it.

I thought a network print server might do the trick but from what I could find out, I'd still have problems. It looks like Apple's new Extreme Air Port might handle it a bit better, but it still wouldn't let you run the Epson utilities (ink level, cleaning, etc.). And although they claim it's Windows compatible I wouldn't be surprised if there were issues.

In the end I physically moved the printer and connected it directly to the Mac. Rather than fight with sharing it from the Mac and somehow connecting from Windows I just went out and bought a new printer for the Windows machine. (I wanted the large format 2200 on the Mac since that's where I plan to print photo enlargements from.) I bought an Epson R260. (Epson's may or may not be the best, but I'm familiar with them.) It amazes me that a printer that has a resolution of several thousand dpi and produces 1.5 picoliter droplets costs only $120! I realize they make their money on the ink, but it's still amazing price/performance relative to a few years ago. Of course, I'd like the newer Epson R2400 to replace the 2200 but that'll have to wait.

It seems strange that Parallels and VMware can virtualize an entire computer, but for some reason OS X printer drivers are tied to hardware. I'm sure there are "good technical reasons" for this, but it seems pretty crappy to me. The Mac seems to lose to Windows on this front.

Friday, April 13, 2007

Three Stages of Design

I was listening to a podcast about software design and they were quoting Steve Jobs. So this is third or fourth hand and probably garbled from the original.

Stage One is where you are new to a domain and it seems simple and you design a simple solution. But the simplicity is really a lack of understanding so your design, while simple, is not very good.

Stage Two is where you see the complexity of a domain and you end up with a complex design. It might handle lots of things but the complexity makes it hard to learn and use.

Stage Three is where you figure out how to make a simple design that still addresses the complexity of the domain. This is the elegant solution. It doesn't have every conceivable feature, but it handles the important stuff for a majority of users. For example, the iPod. Lots of other music players have more features, but the iPod hits that sweet spot balancing simplicity and features. (100 million buyers testify to that)

Back when my company was doing custom software development for a wide variety of domains, a lot of our products were Stage One. A few progressed to Stage Two. Even now that we're focused on one domain, our product is still definitely Stage Two. Suneido, our development tool has some Stage Three aspects but doesn't really qualify overall.

Stage Three is hard. And there doesn't seem to be any formula for achieving it.

Friday, March 30, 2007

ETech 2007 Last Day

We started off with a few interesting keynotes. One on Adobe's new Apollo platform - an alternative desktop runtime for web apps (HTML, CSS, JavaScript, Flash). It looks pretty neat, especially the features for running apps when you're offline (not connected to the internet). But is HTML/CSS/JavaScript the best way to write apps? I'm not sure.

Next, Google gave a presentation on their project to add 1.6 MW of solar power at their headquarters. They also talked about other environmentally friendly practices at Google. Again, it seems Google is trying hard to not be evil despite their huge size.

After the break I went to a session by Andy Kessler on how Moore's law will soon be "invading" medicine - leading to better and cheaper health care. He was an entertaining speaker.

James Duncan's session on JavaScript and Zimki was quite interesting. He talked about some features of JavaScript that I wasn't aware of. Zimki is a JavaScript server and web app framework with some novel features. Fotongo offers paid hosting for Zimki, but it will also be released open source in the next few months.

At lunch I discovered a new coffee shop near the hotel - Brickyard. Although Starbucks is a good default, I like to find local shops especially if they have better coffee! It didn't hurt that it was another beautiful day and I could sit outside in their courtyard and enjoy the sun.

The sessions were thinning out by the afternoon. I went to one on why you should try to design your web app so it could be run as a text adventure (sounds crazy but actually made some sense) I hadn't recognized the presenter's name but he turned out to be the guy who had presented a Rails game (Unroll) at OSCon. He's an interesting character so I was glad I'd gone to this session although it ended up being quite short.

My last session was by Forest Higgs on building your own 3D printer. Commercial 3D printers still cost tens of thousands of dollars to buy and require expensive consumables. You can now build your own for a few hundred dollars. Forest has his own design but he also talked about the Reprap project. The goal is not just to make an open source 3D printer design, but also one that can replicate (most of) itself. (They use microprocessors which obviously can't be manufactured by a home machine yet!) He also talked about the implications of widespread grass roots manufacturing capabilities. Thought provoking.

And that was it for ETech 2007. Although I heard a lot of grumbling that it wasn't as good as previous years, I still think it was worthwhile. Lots of new ideas that will help fuel my brain.

I rounded off the day with supper at The Fish Market. I couldn't be bothered to wait for a table in the restaurant (long lineup) so I grabbed a table in the bar with a great view of the water. There was a limited menu in the bar but the fish and chips was the best I'd had in a long time, the waitress was cute and cheerful, and the sunset was beautiful - what more could you ask for!

Wednesday, March 28, 2007

Amazon S3 with cURL?

As I've talked about in previous posts, I've been searching for a good way to access Amazon S3 from Suneido (to use for backing up our customer's databases).

The SmugMug presentation recommended using cURL. We already use cURL for a variety of tasks (such as FTP) so we'd be happy to use this option. But S3 requires SHA-1 hashes which I didn't think cURL could do. Maybe you can calculate the hashes separately and use cURL just for the transfer. I'll have to look into this.

Day 3 at ETech 2007

Another good day at ETech. I've found a nearby Starbucks that is in a lovely courtyard and isn't very busy. This is where I start my day with a Grande Latte and a little peace before the mind-storm.

The keynotes were all good, but I really enjoyed Danah Boyd's presentation. It's hard not to appreciate someone who is so obviously passionate about their work. I also get a kick out of geeks who are brave enough to dress idiosyncratically. Personally, I can't imagine intentionally doing something to make myself stand out more! Except in my work, of course :-)

Lunch was outside in the Seaport Courtyard again. The weather was wonderfully sunny and warm (especially compared to yesterdays horrendous winds). After lunch I sat by the pond in Seaport Village for a quiet coffee before heading back for afternoon sessions. The sun was shining on the water and the ducks were entertaining. Mama duck brought her three ducklings within inches of my feet. I wished I had my camera.

The presentation on SmugMug's use of S3 was good. This year a number of the sessions have been thinly disguised marketing pitches, but this was a good, seemingly honest, first hand experience report.

Next was a combined presentation on Google's MapReduce and Hadoop - an open source implementation of MapReduce that is part of the Apache Lucene search engine project. Although map and reduce are familiar from functional programming, their application to processing large data sets with clusters of computers is pretty neat. In the past, this would have been out of reach of most of us who don't have access to clusters, but now you can "rent" as big a cluster as you want from Amazon EC2 (or you will be able to once EC2 is publicly available).

The last two sessions of the day that I attended were from Microsoft and IBM on various research projects. One of the Microsoft projects was Baku a "visual" programming environment for kids. I wonder if some of the ideas could be applied to allow end-users to do more complex "programming" in applications. One of the IBM projects was Koala - basically a macro recorder for the web with a unique slant towards sharing the resulting scripts on a wiki. Unfortuately, neither of these projects is publicly available yet.

I had supper at the Edgewater Grill in Seaport Village. The food and service were nothing great, but I enjoyed watching the sunset over the bay.

After supper I stopped in at the MAKE Fest but they only had a handful of exhibits so I didn't stay long.

Ideas from Jeff Jonas

There were some powerful ideas in Jeff Jonas's talk on analytics that I think are quite reasonable to implement in a simple form. One is the idea of "persistent queries"

Most of Jeff's work has been on identifying people - e.g. terrorists and criminals. For example, you get a tip that a criminal is flying into an airport using a certain name etc. So you query the passenger lists but you don't find anything. You're not sure when he's coming in, so you can keep querying every day or hour, but that's not really practical. Instead, you make the query "persistent" so if new data arrives that matches your query you will be notified.

The naive way to implement this is to simply run the query against incoming data. But that doesn't scale. The more persistent queries you have, the slower it will get to enter new data. You can do it as a batch process e.g. nightly - Jeff calls this trying to "boil the ocean" - but it still doesn't scale well and it also doesn't provide the results in real time.

Instead, you turn the problem around. You store the persistent queries as "data", and you treat the incoming data as "queries". So each incoming record requires one "query" regardless of the number of persistent queries. Very cool.

Obviously, there are some issues here. One is that a persistent query probably involves only a few attributes whereas the incoming data will have many attributes. So you're not doing a normal exact match. And you probably will need ways to expire queries.

You might think that this is cool but you don't need to search for terrorists. I think it can be more broadly applied. For example, lets say you're a real estate agent and someone comes in asking for a certain type of property. You do a search but you don't find anything. So you make the query persistent and a few days later you get notified of a new property that's come available. You call your client and make the sale.

Tuesday, March 27, 2007

ETech 2007

Just finished the second day (of four) of ETech.

I've heard some complaints that it's not as "good" as it used to be. The problem may be that a lot of this stuff isn't "new" anymore. When they're writing about stuff in mainstream magazines then you know it's no longer cutting edge.

I was signed up for the tutorials on Monday, but Kathy Sierra's was canceled (see her blog for more on the craziness behind this). They offered the option of upgrading to the Executive Briefing at no extra charge so I decided to do that since the alternatives to Kathy's tutorial didn't excite me. I was sorry to miss out on the other tutorial by Avi Bryant since DabbleDB seems to be such a great product. On the other hand, the briefing included a lot of speakers and topics that I enjoyed. However, a number of the briefing speakers were also included in the regular program so there was a certain amount of duplication.

Today (Tuesday) was the start of the actual conference. From experience I've learned that the best way to pick sessions is to go by the speaker rather than the topic. That doesn't work when you've never heard of the speaker, but it's a useful heuristic. For example, I'm not all that interested in TPM and DRM but I knew that Cory Doctorow would be interesting and he was. On the other hand, a session on Haml that looked really good (but I'd never heard of the speaker) was pretty mediocre. I also enjoyed Jeff Jonas in the briefing and his keynote so I made a point of attending his session, although again there was a certain amount of redundancy. And it was good to hear Jeff Hawkins, since I'm a long time fan of Palm and Handspring, and recently read his On Intelligence book. Unfortunately, I heard criticisms of his sessions from people who don't seem to see the same importance in his current work.

At lunch (great food, by the way) I sat with some guys from Sun. When I said I had a small company that developed software for the trucking industry one of them said they were surprised that someone like that would be at ETech. At first that seemed to make sense - I've never run into our competition (or other similar vertical software companies) at ETech. But then I started to question it. Isn't it just as important for small companies to be aware of emerging technology? I guess if you're really small you can't afford to go to conferences like ETech, but I don't think that's what they meant. And doesn't a lot of the emerging technology come from small companies? Maybe it's because they see ETech as an opportunity for big companies to come and see what the startups are coming up with. In any case, I think I can learn more, and more importantly, have a better chance of applying it, in my small company than they have in their big company.

So far, so good. I'll post more when I get a chance. I refuse to be one of the many people who spend the sessions with their heads down typing on their laptops. At times, the clicking of so many keyboards gets to be cumulatively loud enough to be annoying. Who are they chatting with? About what? Of course, this is from probably the only person there who didn't have a cell phone (if not two or three) and who asks the same thing about everyone on their cell phones - who are they talking to all the time? About what? I realize I'm not the most social person, but nor, supposedly, are many of these geeks. (Of course, this conference isn't all geeks.)

The trend towards Apple Mac laptops continues to grow. I would guess Apple has 60 to 70 percent of this particular market.

For pictures see Flickr/etech07

Monday, March 12, 2007

Air Canada Web Problem

Here's what I got when I entered my booking number and name into Air Canada's web site to check my booking:
java.lang.IllegalArgumentException: Empty country component in 'value' attribute in 
message:Empty country component in 'value' attribute in

stacktrace:
...
A good reminder to make sure you catch errors and give users a more friendly message. Most people probably don't want to see the stack trace :-)

PS. I managed to get it to work. The problem seems to be that I clicked on a link from an Air Canada email that took me straight to the bookings page, bypassing the page where you pick your language. Another good lesson - don't assume people will always enter your site via the "front" page. These days, a large percentage of people enter via searches that point to within the site. (In this case it was their own link so you'd think they'd handle it!)

Friday, March 09, 2007

Holiday Inn Web Annoyance

I've complained about this kind of thing before, but I continue to be surprised that someone doesn't catch (and fix) these kinds of annoyances.

I was making a booking on Holiday Inns web site and had to enter my billing address. When I submitted it I got an error saying "spaces are not allowed in zip/postal codes". I shook my head and remove the space. I get another error saying the format is invalid. I read the fine print and it says you have to enter postal codes with a hyphen. Huh? Since when do Canadian postal codes have a hyphen in them?

The "funny" part is, I bet they added that explanation because people kept getting it "wrong". I wonder if it ever occurred to them to simply accept a variety of formats? e.g. postal codes with space, hyphen, or no separator.

Even better, they could use a little JavaScript to validate fields "on the fly" so it would be marked as invalid as soon as you left the field.

Thursday, March 08, 2007

Those that can, do...

As the saying goes, "Those that can, do, those that can't, teach."

I just listened to a podcast by Jon Udell with Marty Collins the senior marketing manager with the solution architecture group. Also see Jon's blog post about it.

As I understand it, the goal of her group is to "evangelize architecture". I don't know Marty's background but she calls herself a marketing person, and she talks like one e.g. "how do I push our content". Her group consists of 18 ex-architects.

First, I should admit I have a bias against anyone who calls themselves an "architect". In the software world, if a project "fails", the "architect" rarely gets blamed. Even "real" building architects have been know to design buildings that look great, but the roof leaks. Of course, they would similarly have you blame the builders, not the architect.

Don't get me wrong, I still want good architecture, but my feeling is that good architecture comes less often from self-proclaimed "architects", and more often from good programmers. How many "architects" did Unix or Apache or Linux or TeX have?

Marty tells us that one of the reasons for their group is that architects tend to be possessive and secretive about their work. According to her, even the architects working internally within Microsoft won't (or aren't allowed) to share because of the fear of "losing competitive advantage". Or is it that their work doesn't stand up well to public scrutiny?

So the architecture evangelists aren't working architects. Hmmm... And they are led by a marketing person. Ouch. If the working architects won't share, where are they getting the material they produce? Are they just sitting around dreaming up architectures? That doesn't sound very useful to me.

One of the ideas discussed is that companies should watch for people blogging in their area and jump in and contribute comments. Great idea. Jon asked Marty to let him know when they start doing this. But apparently, first they have to get some fancy new tool that is still in beta to let them monitor and comment on blogs. To me this is very much the wrong approach. It's a perfect example of something that you can try out right away and find out if it works or not. If it works, and once you have done it for a while, then you can think about tools. Why can't each member of her group, sit down, find a blog and add a comment. Not next month, not after getting more "tools", but right now, today! I'm not sure if this is a psychological block, or a bureaucratic one.

I've always liked Jon Udell but I am still wondering about his move to go to work for Microsoft. One of his goals is to reach a broader audience and he feels that Microsoft can help with this, but I'm not so sure.

Saturday, March 03, 2007

Slow Code

One of the problems we run into with our code is that it ends up too slow.

Before I continue I want to assure you that I'm not suggesting "premature optimization". I fully agree that optimizing before it's necessary is the wrong thing to do.

What I am suggesting is that "too slow" is a bug, and like other bugs it should be avoided if possible, or at least caught as soon as possible.

One of the causes of slowness is code that is ON2 (or worse!). Nested loops are a common cause. Programmers either don't recognize the nested loops (hidden in separate functions or in recursion), or else they don't realize the dangers of them. For example, if you have 10 items and you iterate over them twice that's 20 loops. If you have one loop inside another that's 100 loops. 5 times as many loops but not a big issue. But what if you have 1000 items? Iterating twice is 2000 loops, but nested it's 1,000,000 loops or 500 times as many. If each loop takes .001 seconds then 2000 loops is 2 seconds, but 1,000,000 loops is 1000 seconds or roughly 17 minutes. In an interactive application that's a big problem.

I think one of the reasons for this problem is that programmers unconsciously relate speed to number of lines of code. So:
for each item
for each item
do stuff
can look shorter than:
for each item
do stuff
for each item
do stuff
Higher level languages, libraries, toolkits, frameworks etc. can make this even worse. Now one line of code can do a huge amount of work, but to the programmer it's just one little line of code. How bad can it be?

Programmers normally test with small amounts of data. When you're only dealing with a few items, both 2N and N2 are fast. You don't get the feedback about the slowness until much later, when the user has larger amounts of data. And programmers are inclined to ignore whining from users anyway!

Another related issue is the difference between dealing with things in memory and dealing with things in the database. The difference is huge, but again, in testing it may be barely noticeable. And, again, the actual number of lines of code may be comparable. (This can be a problem with tests. For one test it doesn't matter. For a whole test suite it can mean the difference between a suite that runs in a minute and one where you have to run it overnight.)

Unnecessarily reading "everything" from the database into memory is another common mistake. If you actually need all the data in memory at once, fine, but if you just need to find a particular record or set of records then it's an inefficient way to do it. In our Ruby on Rails project I regularly come across code that does model.Find(:all). At first glance it might seem harmless. But what happens when that table contains 100,000 records? (Sadly, part of the reason for this is that Rails doesn't seem to provide any way to iterate through a query, so the alternative to Find(:all) is to do your own SQL - an ugly choice.)

I don't have a solution to this problem, but I think we need to become more aware of it. I think it's one of the reasons why our software gets slower at the same time as our computers get faster!

The Trouble With Programming

An interesting article/interview with Bjarne Stroustrup:

http://www.research.att.com/~bs/MIT-TR-original.pdf

Sunday, February 25, 2007

The Old New Thing

I also really enjoyed The Old New Thing by Raymond Chen, a long time programmer at Microsoft. This is a collection of his writing, much of it from his blog of the same name, about Windows software development. It ranges from history, to how-to, to humor.

After I finish a book, one measure of how "interesting" I found it, is the number of sticky markers I've added. This book ended up with quite a few.

Although my impression of Windows as a baroque hodge-podge was reinforced by the book, at the same time I also gained a new sympathy for the difficulties of developing software as widely used (and abused) as Windows.

I've already applied one of the small exercises in the book (converting a bitmap to a brush) to Suneido to accomplish a task I've been wanting to do for a long time, but just didn't know a reasonable way to go about it. In the process though I struggled through a typical example of the difficulties in Windows programming. I wanted to find the size of the bitmap - something that wasn't covered in the example in the book. You'd think that would be an obvious, simple thing to want to do. Guess what API call you use? "GetObject". And, of course, it's not under the bitmap section of MSDN, because it works on other things as well as bitmaps. Nor is it linked to LoadImage, although I would think that getting information about the image would be the obvious next step after loading it. It's another one of those things that's trivial once you know it, but next to impossible if you don't. What did we do before Google?

I'm pretty sure I'll be able to apply several other things I learned from this book - definitely a worthwhile book if you're a Windows programmer.

Dreaming in Code

I recently read Scott Rosenberg's book Dreaming in Code - about the development of Chandler, the Open Source Applications Foundation (OSAF) personal information manager. I'd recommend it - it's interesting and well written. For anyone dreaming of creating software, it's a scary story.

If you haven't heard of Chandler, don't feel bad. Despite the project being started in 2001 it has yet to release an actual product. The web site says they're "getting close" to a "preview release". Coming from a small business background it's hard to comprehend how anyone can go that long and spend that much money without actually producing anything for people to use.

One lesson I think the book illustrates is that constraints are good. Given virtually unlimited time and money what will you produce? Judging by this story, probably nothing.

Drag and Drop to Firefox

This blog post - Upload Files in a Browser Using Drag and Drop - describes a great add-on for Firefox - that lets you drag and drop files to your browser instead of either typing the complete file path, or browsing to it. You can even drag and drop multiple files at a time.

Even my wife complains about the awkwardness of attaching files to Gmail messages. I've suggested zipping up multiple files so she only has to attach one zip file, but to her, that's just adding complexity. I think she'll be happy with this new trick. (Once I get around to installing it on her computer and explaining how to use it.)

Bad Code

Soon after writing my Good Code post I ran into some code that really sucked. It was hard to understand and hard to modify. The sad part was that it met most of my "good code" criteria - it had reasonable names, little duplication, and small methods. You could criticize some of the coupling, but that wasn't the cause of its "ugliness". (In the process of refactoring it I found several bugs, which demonstrates that "good code" is not just an aesthetic judgment, but really does affect the quality of software products.)

Knowing some of the history of the code, how it had grown, I could see why it ended up like it did. You could blame some of the problems on insufficient refactoring as it was worked on. The programmers working on it had just been concerned with getting their task accomplished. If they noticed how ugly it had become, they probably felt they didn't have time to do anything about it.

The lesson is that the criteria in Good Code are necessary, but not sufficient. You need to do them, but you also need to think about whether the end result is understandable.

Sunday, February 18, 2007

Monster Palm

I recently ran across Bruce Tognazzini's web site Ask Tog. (I'd previously read his book Tog on Interface - recommended.)

One of his articles was Make Your PalmOne a Monster Machine

My list would include:

TextPlus - Suggests words and phrases as you enter letters. This makes entering text on the Palm hugely more efficient. I'd have a hard time living without this now. The ability to add your own words and phrases makes it even better.

Wikipedia for Palm (and other platforms) - I have the 2 gb version on an SD card. It's great traveling to be able to look up information about where you're going. Or to scratch a curiosity itch when you're away from the Internet.

Noah Pro - a dictionary with 122,000 words. Again, great when traveling and away from the Internet. I always hate it when I come across a word that I don't understand, or aren't sure of the exact meaning.

Bonsai - an outliner for Palm and Windows. I use this to keep to-do lists, shopping lists, ideas, packing lists, etc.

Aigo - a Go game for Palm. Considering the limited capabilities of the platform it plays amazingly well. It probably won't be good enough for a real Go player, but for someone who just fools around like me, it's great. This is the only game I play at all, and I don't play it much. I had a chess game on my Palm for a while, but never used it.

I've also been checking out the software Tog recommends in his Make Your Mac a Monster Machine article.

Surprisingly, I couldn't find an RSS feed for his web site. Tog is falling behind the times!

My Mouse Has Two Buttons!

I'm almost embarrassed to tell this story! Again, Mac users will be shaking their heads.

Since I got my new Mac, I've been cursing the lack of a "right-click". I've gotten really accustomed to using this on Windows. It was especially bad when I was running Windows under Parallels. I kept thinking that Apple really needed to drop their old obsession with one-button mice.

I tried using the configuration where holding down the mouse button is eventually treated as a right click. But if the delay was too short I kept getting it by mistake, and if it was too long I got impatient. I could use CTRL+SHIFT+click but that seemed pretty awkward.

I knew my "Mighty Mouse" (who picks these names?) had an "extra" button if you pressed on the little scroll-ball since I annoyingly kept triggering it by mistake and bringing up the dashboard widgets. I wondered if I could re-configure this to be a control/right click.

When I went into the mouse settings, lo and behold there was a setting for clicking on the right hand side of the mouse! My Mighty Mouse does have left and right buttons! That's the problem with overly slick, seamless designs - there are no "affordances" to let you discover their capabilities.

I pull down the choices for the right button but there is no choice for CTRL+click. Strange. But there is a choice for "secondary button" - I wonder what that does? I try it and it seems to do the trick. And it works in Windows under Parallels. Problem solved!

This was a good lesson. It's so easy to make fun of stupid users. We're always amazed when we observe someone using our software in such awkward ways - why don't they do it the "right" way. Or getting complaints from customers about missing features when it's right there in front of them! Obviously, if I had looked at the specs or looked more carefully at the settings I would have solved this a lot sooner. But if I can fall into this trap, with umpteen years of experience in the business, it's hard to blame someone who has little or no experience.

Thursday, February 15, 2007

Mac OS X with Windows Printer

I struggled on this one for a while. My printer (Epson 2200) is hooked up to my main Windows box and shared so my wife and I can print to it from our Windows laptops via wireless.

I could find and add the printer in the Mac printer setup but it wouldn't work. I was getting NT_STATUS_ACCESS_DENIED.

Searching the web found many people with the same problem. I eventually got it working by using the Advanced printer setup (a little tricky to find) and using a URI of:

smb://andrew:@mckinlayhome/epson2200

Judging by what I found on the web this has been an ongoing problem with OS X. I wonder why it hasn't been fixed?

Funnily, my copy of Windows running under Parallels on the Mac had no problem connecting to the printer.

Monday, February 12, 2007

Rogers.com won't take no for an answer!

This is classic - they give you a checkbox to say whether you want email, but they won't let you save unless you say "yes"!


So I changed my email address to nospam@really.com :-)

Sunday, February 11, 2007

Good Code

After 30 plus years of programming, the basics of good code has boiled down in my mind to just a few things:
  • Good names
  • Consistency
  • No duplication
  • Small pieces
  • Loosely coupled
These are roughly ordered by scale - from individual "words", to lines, to modules.

None of these are original. They have all been endlessly discussed, analyzed, and written about.

Good names

Why is "i = j * 2 + k" bad? Because you have no idea what it means without studying a much bigger context of code to try to figure out what i, j, k, and 2 mean.

It isn't just that you should have long names, they also need to be accurate. A name that was once accurate but has since drifted into being use other ways is just as bad as a comment that gets out of sync with the code.

Not all good names need to be long. There's nothing wrong with using "i" for a loop index, where it's obvious what it is.

Good names often eliminate (or at least greatly reduce) the need for comments.

Consistency

Consistency ties in with good names. Use the same name consistently for the same purpose. Conversely, do not use the same name for different purposes!

Consistency includes:
  • Coding standards or guidelines
  • Coding idioms
  • Organization, design, architecture
If you can look at a few lines of code and tell who wrote it, then you probably don't have a high level of consistency.

Code reviews, pair programming, and joint ownership of code all help with consistency.

No duplication

Programming by "copy and paste" is easy and quick. It's code re-use - isn't that supposed to be good?

The problem is that code isn't "write-only". You're going to need to fix it, improve it, add features to it. And that becomes much harder when you've got the code in multiple places.

Another problem is that it usually isn't just "copy and paste", it's "copy, paste, modify". So now you not only have multiple copies of the code, but they're each slightly different. Even tougher to work with. And it lowers your consistency.

But there are subtle advantages to DRY (Don't Repeat Yourself) that are just as important as these obvious issues. To avoid duplication, especially when the duplication has variations, you have to think about the code, what is common, what varies, why it varies. Does it vary just because you used different variable names? Maybe you should be consistent. Does it vary because it behaves differently? Maybe whoever uses this code (end user or another programmer) would benefit if it behaved consistently.

Small pieces

In some ways this is both one of the easiest and the toughest guidelines.

It's easy because anyone can see whether you've broken your code up into bite size chunks. You can write automated tools to check function / method / class sizes.

It's hard because it's not just breaking it up, it's how you break it up. You want the pieces to have high cohesion and low coupling, and that's hard. We've been struggling with this one for a long time e.g. Yourdon & Constantine covered this in depth in Structured Design in 1979!

A big benefit of small pieces comes from giving the pieces good names.

Loosely coupled

If every line of code connected to every other line of code then complexity would go up as the square of the number of lines of code. N squared goes up fast. If this was the case we'd never manage more than tiny programs.

On the other hand if every line was totally independent, then complexity would only go up linearly with the number of lines of code. That's a lot more manageable.

The reality is somewhere between. The bigger a program gets, the more important it is to keep the pieces as independent, loosely coupled, as possible. The higher your coupling is, the bigger the risk that a change will have unexpected side effects (also known as bugs).

Again, this is easier said than done. Structured programming aimed to reduce coupling. One of the big goals/advantages of object-oriented programming is looser coupling. "Interfaces" are another tool. Our tools are getting better. But are programs are also getting bigger.

Thursday, February 08, 2007

Working at Home

Lately I've started working at home some of the time, nominally Tues. and Thurs. - so I'm still around the office at the beginning, middle, and end of the week.

As our business has grown my days have grown more and more interrupted and fragmented. I seem to go from talking to one person to helping another, to supervising another. I could close my office door, but that wouldn't stop people from knocking on it or cornering me when I went for coffee or to the bathroom. And I don't really like the idea of closing my door anyway.

I could tell people to get lost, but the truth is I still want to deal with all these things. I'm not ready to step back totally, even if somehow I could. I still want to guide and help people. I just don't want to do it 100% of the time. Or more accurately, I still want to spend some of my time programming.

I want to spend time programming because that's what I enjoy doing. But I think it's probably good for the company as well. There are things that I can work on that will be beneficial, that would never get done otherwise, either because they're things like Suneido C++ internals that no one else works on, or because they're general enhancements that will never be "urgent".

I'm finding my programming time at home surprisingly enjoyable. I guess it shouldn't be surprising - I wouldn't have been programming for 30 years if I didn't enjoy it. But it's been a long time since I was able to focus on it for significant periods of time. On top of the pleasure of coding, it's also nice to feel like I'm getting things done. You don't get that as much when you're managing. In the big picture you're still getting things done, but it's not as personal.

For a lot of people, there would probably be more distractions at home than at work, but I haven't found that. I don't sleep in or watch tv or read a book. I actually want to be programming. And because of that, I'm less likely to be sucked into email or surfing the web. At work, when I know I'm liable to be interrupted any minute, it seems like I might as well kill time, since it's pointless to start anything more serious.

I'm not sure what my staff thinks about it. I wonder if some of them might resent it or feel like I'm "abandoning" them. Hopefully they'll be ok with it. They're certainly capable of operating without me.

An added (intended) benefit is I've been getting on the treadmill first thing in the morning. That way I get my exercise for the day, and I only have to shower once :-) And since I don't have to travel to the office, I still start work at more or less the same time.

Funnily, I've still been going in to the office on the weekends, since it's quiet then.

Here's my new Ikea desk, Mac mini, JBL Spot speakers, and Starbucks coffee mug - all the essentials :-)

Saturday, January 27, 2007

Where is the User Interface Innovation?

It seems like a good user interface toolkit would lead to better interfaces, and I think at one level it does. But recently it has occurred to me that it also tends to reduce innovation. Where I'm seeing the most innovation in user interfaces is on the web with the new generation of Ajax web applications. HTML, CSS, and Javascript provide a pretty basic UI toolkit, certainly not as nice as the Mac or Windows. But it seems to be another example of constraints leading to good things. It seems like, because of its limitations, the web has spawned a rich variety of UI innovations. Of course, the variety means that there's not as much standardization, but so far that hasn't seemed like a big drawback. You have the same problems figuring out how to use an innovative Windows or Mac program.

For a good example, have a look at Dabble DB - the 7 minute video gives a great introduction.

Friday, January 19, 2007

My First Mac

A few days ago I received a Mac Mini I ordered directly from Apple Canada. I could have bought one locally but I was curious about how they're mail order would work.

Although the advertised prices make the mini look relatively cheap, by the time you upgrade the memory and hard disk to reasonable amounts, and add a mouse and keyboard it's ended up almost twice as expensive as a comparable PC.

My first chuckle came when the mouse and keyboard arrived in a box about six times the size of the box the computer came in!

Less of a chuckle when I found that I couldn't use the wireless keyboard and mouse until they were set up - which you couldn't do without a wired usb keyboard and mouse. This wasn't a problem for me since I had spares, but if this was your only computer (or if you only had an older PS2 keyboard/mouse) you'd be pretty frustrated. It might be nice if Apple's web ordering system warned you about this when you ordered a mini with a wireless mouse and/or keyboard.

Other than that, set up was quick and easy. It recognized my Samsung SyncMaster 215TW and set the right resolution automatically - something Windows handles but Linux never seems to be able to.

Of course, the first thing it did was start downloading updates - a good thing, I guess, but not something I like being bothered about. I was sad to see that the updates required a restart. I guess it's not just Windows anymore that wants to restart all the time. I thought maybe the first update was an exception, but the next one (a day later) also required a restart. Updates on Linux don't seem to require this unless there's a kernel change.

For the most part it connected to our Windows network with no problems. It took me a few minutes to figure out how to access network drives and printers but not too bad.

Next, I downloaded some software - Firefox, TextMate, and Parallels. This is where I really felt my unfamiliarity. On Windows, installing software is generally pretty easy - you run the installer and it does its thing. On the Mac I found it quite confusing. You download a ".dmg" file (disk image?) When you open that you see some files, and an icon appears on the desk top (the "disk"?). Now what? Firefox comes up with some graphic which I think is telling you to drag the program to the Application folder. It might help if there was a text explanation as well as the cryptic graphic. Of course, I made the mistake of running programs from the disk images which gave me grief because they were then running (even after I closed the window - another Mac / Windows difference). Experienced Mac users are probably laughing at my newbie confusion, but it's far from clear or consistent.

Eventually I got my programs installed. I haven't played with TextMate yet, but I've heard a lot of good things about it so I'm keen to give it a spin.

One of the first things I did was install Windows XP with Parallels. I could have used Bootcamp to dual boot Windows but having to reboot to run different software is pretty ugly. Parallels did a great job of installing Windows with no interaction (except for putting in the second cd).

It seems ironic that virtually the first thing I do with my Mac is install Windows! But since our business is all Windows software, it's a crucial feature.

I had downloaded the new Parallels release candidate since I liked the sound of the new "coherence" mode. It's awesome. I have my Windows task bar (set to auto hide) at the bottom of the screen, my Mac menu at the top, and my dock (also set to auto hide) on the left. Suneido seems to run fine. Our test suite runs as fast (if not a bit faster) than the brand new dual core PC I bought recently. It's pretty impressive to have OS X and Windows programs sharing the screen seamlessly.

I'm still having a little trouble getting used to the Mac mouse and keyboard. I keep trying to right click on things! And I keep trying to use Ctrl+C for copy instead of Apple+C. At least with Parallels Windows programs seem to accept Apple+C. And Home and End scroll to the top and bottom instead of going to the beginning or end of the line. Apple+right arrow seems to be end of line, but Apple+left arrow doesn't seem to work, at least in Firefox. Some of this is probably configurable.

Now I just need to install Ubuntu in Parallels and I'll have OS X, Windows, and Linux all in one wonderfully compact system.

Disclaimer - calling this my first Mac is stretching it a bit. I've worked with everything from Apple II's to Lisa's to Mac's, but I've never actually owned one for myself.

Tuesday, January 16, 2007

Amazon S3 Tools continued

Just to confuse things even more, I tried #Sh3ll from home on a big file and it worked fine (even over wireless).

So that would seem to indicate that the problem is with my network connection at work. Although that still doesn't explain why jSh3ll worked.

However, I didn't get around to trying the others and I only did the one test at home. So it could have just been lucky.

I'm not sure where that leaves me. Maybe we should try #Sh3ll (because it appears to be the easiest to deploy) on a few of our clients and see what happens.

Monday, January 15, 2007

Amazon S3 Tools

We ftp our client's database's back to our office nightly. This gives them an off site backup and it gives us quick access to their data to help support them. The problem is that as our client base has grown we have run into bandwidth limits at our office.

We could use a hosted ftp site, but I thought it might be worth trying Amazon's Simple Storage Service (S3).

The catch is that authentication is done with HMAC-SHA1 which we've never implemented for Suneido. So instead of writing our own interface to S3 I figured we could simply call someone else's command line tool.

There are quite a few available tools for S3. Here are some that I tried:

s3cmd - Ruby

#Sh3ll - C#

jSh3ll - Java

s3tools - Python

s3curl - Perl

I wanted something that would be easy to deploy on our clients, preferably without installing a language run-time. The best for this appeared to be #Sh3ll which was an exe that only required .Net 1.1 which should be installed on most recent Windows machines. However, there are tools to turn Perl, Python, or Ruby programs into standalone executables so that might be a deployment solution.

But the only one I could get to work consistently for large files was jSh3ll which requires Java 5. All the other tools give timeout errors. I'm not sure what jSh3ll is doing different, or whether Java just has better network support.

The question is whether it's practical to require the Java runtime to be installed on our customers servers. It doesn't seem unreasonable to me, but some people are touchy about it.

PS. There is a nice Firefox extension for S3

Saturday, January 13, 2007

eTrux

After reading The Innovator's Dilemma by Clayton Christenson some time ago, I decided to start a pilot project to make web-based trucking software. (Currently we develop and sell Windows desktop trucking software.) I'd also been hearing a lot about Ruby on Rails so it seemed like a good chance to try it out.

eTrux.com is the result so far. There's not a lot there yet, but it's coming along.

Unlike other people's "too good to be true" stories, we weren't able to produce this over a weekend. Perhaps if I or the programmer I hired had more (any) experience with Ruby or Rails (or even web application development) it might have gone faster. But it's been a slow learning process (many months) to get to where we are now. I think/hope that it will go quicker now that we have figured out the basics.

Have a look. Any feedback is welcome.

Thursday, January 11, 2007

Windows XP Annoyance

Ever since I upgraded my Windows machine it has insisted on weird paper sizes. Google Picasa showed crop sizes in cm and printing showed choices like A3 and A4 instead of Letter and Legal.

Eventually I tracked it down to choosing "English (Canada)" at some point in the Windows install. This shows up in the Control Panel > Regional and Language Options

Where should I start to complain about this?
  • When you choose "English (Canada)" during setup I'm pretty sure it doesn't give you any information or warning about what effect this has. I have a hazy memory of the question being phrased as "What is your language?" (nothing about units of measure or paper sizes)
  • Canada does use metric, so I can sort of see where the crop sizes in Picasa come from, but actually we still use inches for photo sizes e.g. 4 x 6, 5 x 7, 8 x 10
  • Canada does not use A3, A4, etc. paper sizes, we use Letter, Legal, Tabloid etc. When you go to the store to buy paper, that's what you find.
  • The Customize for the Regional Options doesn't even have a choice for centimeters versus inches or A3/A4 versus letter/legal.
The "solution" is to pick "English (United States)" even though I'm pretty sure I'm really in Canada.

Strangely, I don't recall having this problem before. Either something has changed or for some reason (it was the default?) I always made the right choice previously.

I realize many Americans think Canada is some obscure little outpost somewhere in the far north, but surely someone in Microsoft's hordes of developers and testers and QA people should know better! If nothing else, check officedepot.ca and see what paper sizes they sell!

Web Annoyance

Here's a good one - Holiday Inn's Priority Club web site requires a dash in Canadian postal codes e.g. S7N-2X8.

Why would this programmer decide to dream up their own unique postal code format? The only think I can think of is they didn't want to handle spaces, but that's pretty feeble.

There are standards for this kind of thing, why not use them?