Tuesday 26 August 2008

Voodoo

I've always been a little superstitious when it comes to computers. After all, "Any sufficiently advanced technology is indistinguishable from magic." I remember the behaviour from when I was about 7 years old, when I first started playing games on my ZX Spectrum, and 25 minutes into the load from tape I'd be muttering "please work, please work, please work" under my breath (I was used to loads failing regularly).

These days, I'm sure I do plenty of unusual things while using my computer, but I don't tend to notice them until somebody points them out to me. The thing is, like all good superstitious behaviour, the reason gets forgotten and only the ritual remains.

Occasionally I'll remember the reason why I do things in a certain way. Even more rarely, I'll see someone else doing something that I've seen myself do, and feel vindicated!

Here are some of my superstitious actions, and reasons why (where I remember them).

Left-Right click to bring up a context menu.

The normal way to open a context menu under windows is to right-click. I click left then right (like I'm drumming my fingers). Reason: Some programs interpret the first click (right or left) as a "focus" click, so a single right click doesn't always pop up a context menu.

Click-Enter instead of double click.

The normal way to navigate into folders in windows explorer with the mouse, is to double-click the folders. I use the mouse to select the folder, then press enter on the keyboard to open the folder. Reason: Sometimes double-clicks are missed by windows (if I have a poor mouse, or my finger movements are too slow). Also, after double-clicking for the hundredth time in the day, I start to feel the RSI kicking in... I've seen someone else exhibiting the exact same behaviour :)

Hyperlink click follow-up click.

After I left-click a hyperlink in a web page, I click in some white space on the page. I don't know why I do this. It may relate back to when I had a dial-up connection and I wanted to know if the page was responding. It may just be that I don't like the link being outlined. I really don't know about this one.

Mark as read, before delete.

In Microsoft Outlook I read email in the preview pane. If I don't navigate away from an email in my inbox, it stays marked as unread. If I don't need to action an email I don't just delete - I press "Mark as Read" then I press delete. Otherwise my "deleted items" folder draws attention to itself by being written in bold with a number beside it, telling me how many "new" emails I have in it.

I'll post more if I think of any.

Monday 25 August 2008

Music to my ear

I first noticed it about 10 years ago. It only happens when I'm really tired, but can't sleep, and in the almost complete stillness of night. And it only happens very rarely, but when it does, it's amazing.

I was on a caravan holiday with my parents, and late one night, while I was trying to sleep, amongst all the other night time noises, I could hear a dripping sound coming from the refrigerator. The dripping was very regular, and sounded almost like it was a percussion instrument, setting the beat, setting the rhythm. And then something very strange happened. I started to hear music. Not just a simple tune, or melody, but I could hear the whole damn orchestra. I could hear the percussion. I could hear brass. I could hear strings, first playing legato, then pizzicato. I could hear woodwind. There were changing dynamics. There were melodies and counter melodies. I could hear the whole thing.

I knew it wasn't on a radio or cd player somewhere because the music was in perfect time with the dripping refrigerator. And I noticed something else about it - that I could decide where the music went. I realised that even though I was awake, it was almost as though I was dreaming, but whatever the explanation, the music was going on in my head. While it was happening, I remember feeling as though the music was just inside my ear.

At the time, I was a budding musician - and I was trying to come up with my own pieces. And when I heard this music, I felt that if I could only transfer it to paper, it would be a masterpiece. But I was also aware of the similarity between this music, and any regular dream, and knew that it would all be forgotten soon afterwards. Sure enough, after I woke up, I couldn't remember the themes, the tunes, any of what sounded so amazing at the time.

Over the years since, I've heard similar music, just inside my ear. It normally occurs when I'm really tired, but maybe after I'd been drinking alcohol, or caffeine, and I can't get my body to switch off and go to sleep.

I'd thought about looking it up on the Internet, but had no idea how to go about searching for it. "Music in my ears" seemed a daft thing to search for, so I let it be.

Just last year, I was in a bookshop, and saw a book on display called "Musicophilia - Music and the Brain" and as I was flicking through, I came across a letter to the author from a lady who had been hearing music in her ears when there was no external source of music. You can imagine my excitement when I realised I may have found something that could help me research what I was experiencing. The phrase "Musical Hallucination" was mentioned, and that was all I needed to type into Google.

The explanation that seems right to me is that tinnitus (ringing in your ears) is being picked up, not conciously, but subconciously by your inner ear, and your brain decides to interpret the ringing as music.

I've seen stories of people hearing choirs, christmas carols, and orchestras. There is advice on how to control the sounds and make them fade away - but to be honest, I actually enjoy the music. I only wish I could transcribe it as fast as I hear it!

I last heard the music a few weeks ago. I once got up in the middle of the night to sit at the piano and tried to repeat what I'd heard. I'm going to try to keep that up, and one day, who knows, I might be able to share my masterpiece with everyone else!

Sunday 24 August 2008

Depth First Coding and Spirograph

Various analogies come to mind when I'm coding. Recently, the terms "Depth First Coding" and "Spirograph" have come to mind.

I'll explain.

When writing software, there's so much that needs to be done. But of all the items on the todo list, we coders prefer to work on new features than the other things like fixing bugs, dealing with security issues, general code "housekeeping" and basically doing what we know we ought to, but never quite finding the motivation for it. I know I certainly want to get to a stage where I can see the whole process of using my software from start to finish.

I think it's good practice to get a proof of concept up and running as soon as possible. As well as making sure you're not wasting your time with a project, you can get feedback right from the start, you can adjust your plan based on what you see, and let's face it - it's more fun - it can keep you motivated through the more mundane tasks.

To me, this feels like depth first programming - get the skeleton of the app complete, from top to bottom, then go back later and fill in the breadth - the bugfixes, the tidying up, the refactoring - the meat.

A breadth first approach would be to get all of the minutiae sorted - making sure each function was written as efficiently as possible, making sure the variable and function names were as descriptive as possible, commenting anything that wasn't clear, and basically trying to make each component as near to perfect as possible.

My problem with this approach is summed up in the phrase "Premature Optimization." Here we are going for perfect first time round, but at a cost. Then, if it turns out that the routine that we just spent the last day working on is no longer needed, then that's a day that's been wasted.

The way that a program grows, almost organically, reminds me of Spirograph. After the first iteration, a very basic, bare bones implementation is produced. After several more iterations a pattern starts to appear. After hundreds of iterations, the final picture is revealed. The pen traces a path around the spirograph, never lingering in one area for long.

This is how I see code growing organically. On top of the initial foundation, the coder grows the program piece by piece, often moving from one area to another. By jumping around the project, the coder doesn't get bored with the area they are working on.

But it's also worth noting that no matter how many times you go around a spirograph, and no matter how many different places you choose to start from, the pen doesn't touch every part of the paper - there are always some holes.

I wonder how the holes fit into my analogy...

Saturday 23 August 2008

CloudLauncher

Every time I press Windows-D (show desktop), I think "FAIL".

I've laid out my shortcuts on my desktop. The shortcuts are there because they are the quickest way still available of getting to what I'm after. I say "still available" because the absolute quickest way, in my experience, is a WinKey shortcut, but there are only so many apps you can assign to obvious keys before you start having collisions.

Now for better or for worse, the layout of the stack of windows on my desktop, usually ties closely with the stack of tasks I have in my head. If I have 10 windows stacked on top of one another, chances are the topmost is what I was most recently using, the next is the next most recent, the one after that is the next most recent, and so on.

Ok, admittedly, 10 windows is a bit excessive, and I'll probably only remember two or three things that I was doing. But at work I use three monitors, so with plenty of screen real estate, spatial location of windows can also help me with remembering what I was working on and where it is in my mental stack.

Unfortunately, undoing "Show Desktop" doesn't work. The window stack is all messed up, and so now I have to spend time working out where I was. It may have only been for a few seconds, but if I was concentrating on something it could take a while to pick up all my trains of thought. If I'm frequently running the various shortcuts from my desktop, that's a lot of shoving my brain in and out of context. This is why I think of a "Show Desktop" as a FAIL.

I want to run my target app as quickly and seamlessly as possible. From this thought comes the seed of my idea for CloudLauncher.

As I've already mentioned, the most efficient way of doing something depends on your context. If I'm sat back in my chair, with a cup of coffee in one hand and the mouse in the other, there's no way I'm going to start typing a command to run an app. Similarly, if I'm in touch typing mode with both hands on the keyboard, it's going to slow me down to reach out for the mouse to click on a shortcut icon. Depending on context, Winkey, Quick Launch, or even the Start Menu may turn out to be the quickest way to achieve my goal. And when I happen to be in keyboard and mouse mode, Windows-D to show desktop, followed by a double click on an icon on my desktop is usually the quickest.

However, since showing the desktop (or hiding everything, as I like to think of it) has fallen out of favour with me, I'd like to write an app that can fill the gap - so a keyboard shortcut to launch my launcher app, then a click (or double click) to launch my target app.

I experimented with Skil, which almost does what I want, but it looks like you're constrained to an auto-arranged grid, whereas with the desktop you can place your shortcuts wherever you want.

Various ideas went through my head, such as a radial menu, where you group items at one level, then when you move through the group name it expands into another level of groups and shortcuts.

To save on desktop real-estate, the items could move relative to the mouse, similar to apple's dock.

Some shortcuts are useful when you first set them up, but become less useful over time. Laziness usually keeps me from cleaning up unused shortcuts. So I was thinking that shortcuts could gradually migrate towards the edge of the screen until they drifted off completely. (This is where the name Cloud Launcher came from).

But then I decided all of these can wait until version 2! You can fit a heck of a lot of shortcuts on one screen. Let's think about saving screen space when it actually needs saving!

I'll post more on how I'm getting on.

Friday 22 August 2008

Recycling

If I save up all my cardboard and all my cans and all my jars, in order to recycle them, then I drive to the recycling depot in order to recycle them, how much recycling do I have to do in order to "break even" where the benefit of recycling outweighs the "damage" caused by me driving there? (By damage I mean using fuel in my car).

Thursday 21 August 2008

Wizards

The wizards I see on a day to day basis don't go to Hogwarts. They live on my computer, and do things like installing applications.

Once upon a time, I used to carefully check every option on each wizard - the option wouldn't be there if it wasn't important, right?

So I'd agonize over which help files to include with spybot, and worry about whether I'd be missing out if I didn't include additional skins for winamp.

But after a while, the wizards start to get in the way. So what if German help files are installed on my computer and I don't speak German? Winamp in it's entirety is only a few megs - what am I saving if I carefully untick the "additional skins" checkbox?

So how about instead of presenting me with lots of options to tweak and adjust to my liking, why not just install with the defaults, and hide the optional extras out of the way for power users to dig out for themselves?

These days, I tend to click-click-click the next button until it does what I want it to do.

It doesn't work for the Zip extraction wizard in Windows XP though. When I tell a file to extract, first it tells me it's an extraction wizard (well duh!), then it asks me where I want to extract to (defaulting to the folder that contains the zip file - that's good enough for me), then it starts extracting. But the next button is still enabled. Which means I can start extracting into the same location again and again. But that upsets the wizard because he doesn't want to overwrite the files he's already written.

So I have to be careful when I play with the extraction wizard.

I'm sure there's a moral to the tale in there somewhere...

Wednesday 20 August 2008

Cutting Edge

When working on a team project, how often should you update from source control?

Broken builds can take hours or even days to fix. On several occasions I have updated source code (sometimes even by accident) only to find that the build was broken. I would then spend the rest of the day trying (and failing) to fix the bug, go home frustrated, come in the next day, update my source code, and the bug had been fixed. On those occasions I felt like I could have just gone home when I found the build was broken and not come back until it was fixed, and that my time would have been better spent.

Of course, sometimes I'm the one who fixes the broken build - somebody has to do it. Which, if I'm honest, means I can't really justify the go-home-when-it-breaks approach.

Back to the question of "how often should I update?"

On the one hand, you could adopt the attitude of "I'm only interested on sub-component X. Therefore I'm not going to update the entire codebase unless I really have to." It's a sensible approach. It means you don't risk killing your productivity every time you update.

The trouble I've had with that approach is, whenever I found a bug in a section of the code, and asked the owner of that code about it, the first thing they would ask is "have you updated?".

On the other hand, you could get the latest code whenever it becomes available. The trouble with staying cutting edge is that not only do you get cutting-edge bugfixes - you also get cutting-edge bugs!

I guess like a lot of development issues, there is no right or wrong answer...

Monday 18 August 2008

Destination Desktop

Once upon a time, I used to think that icons on the desktop just made a mess.

There's a saying - "Tidy house, tidy mind". Not only do I agree with the saying, I think it extends to computers too. As I've already mentioned, I want my computing experience to be as efficient as possible. Too much clutter on the desktop was counterproductive - especially when the dreaded Auto-Arrange was turned on! I've even gone as far as removing the My Computer icon.

A few weeks ago I started "allowing" myself to add one or two shortcuts to my desktop. Nothing overboard - a shortcut to a folder here, a shortcut to an app there, a shortcut to a batch file over there. But one folder wasn't enough. One app wasn't enough. Soon I needed access to a few folders, a few apps. When I had about 10 shortcuts, I started to cluster them on the desktop. Gradually, completely by accident, my desktop had become a launcher.

Using the desktop has pros and cons.

On the plus side, by arranging my shortcuts into clusters, spatial memory gets to play a part in finding my shortcuts, which could, in theory, speed things up. In a static, alphabetical menu I would have to scan through names in alphabetical order to pinpoint my shortcut, which is fine when dealing with files on a one-off basis, but using the same shortcuts on several-times-a-day basis, can get a little tedious.

Also, desktop icons are larger than icons in the start menu, which makes them quicker to hit.

On the minus side, I have to minimize whatever is in front of my desktop every time I want to access the shortcuts. This can really disrupt my flow.

So I decided that what I needed was an launcher app that could let me arrange shortcuts in a spatially convenient way, that could pop up in front of my other windows on demand.

The closest I found to this was Skil. It's close to what I'm after, but it ain't perfect. I want to be able to place my icons wherever I want - not confined to a side-by-side grid.

So if I don't find an app that does this, then I'll give writing it a go.

Update: 19th July 2008
How ironic. When writing about the cons of using the desktop as a launcher, I considered putting something about windows "forgetting" where you left the icons and "helpfully" auto arranging them for you. But I thought "I haven't seen windows forget my icon positions for a long, long time. Perhaps it's fixed."

I arrived at work today, my machine had crashed, and all my icons had piled up in a mangled mess at the side of my screen.

Saturday 16 August 2008

Estimation

Ok, maybe I wasn't clear in my inspiration post. Just to clarify: the "inspiration thing" usually only happens for me once in a blue moon!

Strangely, my time estimation ability seems the opposite way around to most people. I think most people tend to underestimate the "bigger picture" and it's only when they drill down to the sub tasks and really think about what each element consists of that they put a more realistic estimate together for the overall project.

I think I tend to overestimate projects on a whole (because I'm pessimistic / realistic), then when I try to estimate how long sub tasks will take, I forget how pessimistic I am and grossly underestimate them.

Many years ago, I came up with a rule of thumb: ANYTHING you do on a computer will take 10 times longer than you expect it to. The simplest of tasks always seemed to take an order of magnitude longer than I had planned. (I wanted to call it "Tim's law of computing" - then I discovered Douglas Hofstadter already coined a virtually identical law).

I still forget the rule of thumb, even today.

Saturday 9 August 2008

Code Re-use

I've always believed re-using code is a good idea, but it's not until recently that I've felt that I'm doing it properly

When I programmed for myself (before I was hired as a programmer), I wrote in C++. I tried to make libraries (libs and dlls) for re-use in future projects. My friend / housemate / mentor Denis advised me not to bother making libraries and just copy the code into the latest project. I guess for personal projects there isn't really any point wrapping up functionality in dlls. But what about bigger projects? I'm starting to think that even with bigger projects, it's not worth the hassle...

Denis gave me some more advice, when I was trying to put an engine together to help me write games. "Write the game, not the engine". Which I suppose is correct if you want to write the game, but if the process is more of a learning exercise, then i think it's right to work on the engine. But then, I suspect that every closet games-coder is working on their own engine, and a lot of games don't end up written.

I used to write whatever kind of module I thought was necessary for my game, then, when the time came to pull all the code together, I planned to lift all the code from each of the modules and combine them to create my engine / game. Needless to say, I never got round to creating my engine, or my game...

At work, I write tools in C#. Suddenly, I have lots and lots of scope for re-use. I'm not 100% sure of the reason for this, but I feel that the C# language itself makes itself very amenable to code re-use.

Now I don't write everything with re-use in mind. If I only need to use something once, then the time spent making it more generic is wasted. The first time I need a tool to do something, I'll write a very specific tool for the job. Then if I decide I need it again, only then will I make it generic. This process seems to serve me well enough.

So far, I've written the following:

A generic options dialog that can be plugged into any app I write in future. (Currently can store options that are strings or bools - more types planned for in future).

An Argument Parser. (Pass in the args from your program, and then you can ask it for string values or if a bool option is present).

A Serializer. (Until I wrote this, every time I wanted to load or save a binary object I had to create the file reader / writer and the serializer separately, then pass my data to the serializer - now I just create my generic serializer.)

A Cascading Checkbox Tree. (Out of the box, the treeview doesn't propogate ticks up or down the tree. My cascading checkbox tree does.)

A class to convert absolute to relative paths and vice versa.

A class to handle File Operations. (Typically, things like "Close" go through a process of checking if the file needs saving; asking the user if they want to save it; save the file; if the file doesn't have a name present the user with a save dialog; if the user wants to open a file, check that their current file is saved; and so on. My File Operations class handles all of this for me.

And even an OK-Cancel form. (I always seem to be writing dialog boxes that have OK and Cancel buttons on them. And I always have to change the text on the buttons, change the names of the buttons, set up the accept and cancel properties of the form, tell the form to close when either button is pressed. Now I just re-use my OK-Cancel form.

Re-use rocks!

Wednesday 6 August 2008

UndoManager

Undo is more difficult to implement than it appears at first glance.

A typical implementation of an undo manager will store a list of undo data (the UndoList) and a list of redo data (the RedoList).

Undoing an action will pop the last action from the UndoList and push it onto a RedoList. Redo will perform the reverse - pop from the RedoList, push onto the UndoList.

At its simplest, undo / redo data will contain the 'before' and 'after' states of some object in the application, and the function command that will operate on that data.

So for example, if an action adds the next character 'd' to the Collection "MyCollection" (which currently contains 'a', 'b' and 'c'), the undo data might look like this:

Before: Collection c1 = "a, b, c"
After: Collection c2 = "a, b, c, d"
Command: func(Collection before, Collection after)
{
MyCollection = after;
}


If we ask the undo manager to undo this action, 'func' gets called with 'before = c2', and 'after = c1'. If asked to redo the action, the 'before' and 'after' are switched, so 'before = c1' and 'after = c2'.

Easy, right?

Some questions: How do we create c1 and c2? Are they each a clone of "MyCollection"? What if the collection contains something a bit more complicated than characters, say class objects? What if the objects are collections themselves? Should c1 and c2 be shallow copies or deep copies of MyCollection? How expensive is it to deep copy c1?

In adding 10 items to the collection (say 'a' through 'j'), the first undo action will consist of an empty collection, and a collection containing 'a'. The undo action for adding 'b' to the collection will contain a collection containing an 'a' and a collection containing an 'a' and a 'b'. The next action will contain {'a', 'b'} and {'a', 'b', 'c'}. By the 10th action, there will be 100 items in the undo manager (({}, {a}) + ({a},{a,b}) + ... + ({a..i},{a..j})). Not so bad with characters, but what if you have more complex classes?

And what if those class objects are registered with callbacks elsewhere in the code to have things happen to them in certain situations? Should each instance of the class object in the undo manager remain registered? Should items added to the undo manager have their callbacks revoked and reinstated when the relevant undo / redo command is called?

So instead of storing 'before' and 'after' undo data, an alternative would be to store the data and command required to change the data from the 'before' state to the 'after' state (and the command and data required to change the data back) - 'undo' data and 'redo' data respectively.

So in the character collection example above, the first undo data might look something like this:

UndoData: Item index = 4
RedoData: Character chr = 'd'
UndoCommand: func(UndoData und)
{
MyCollection.Remove(und.index)
}
RedoCommand: func(RedoData red)
{
MyCollection.Add(red.chr)
}


Easy, right?

Some thoughts: The UndoCommand is essentially a "delete function", and the RedoCommand is essentially an "add function".

So when creating the "add action", let's pass the "add function" and the "delete function" as the UndoCommand and the RedoCommand respectively.

When creating a "delete action", let's pass the "delete function" and the "add function" as the UndoCommand and the RedoCommand respectively.

So what was 2 functions before the undo manager (the "add action" and the "delete action") has become 4 functions with the undo manager (the "add action", the "add function", the "delete action" and the "delete function").

Every action has been split into a "put these commands into the undo manager" function, and an "execute the action" function. That's a whole lotta work to retro-fit the undomanager into an existing app.

Final situation to think about. How do you undo continuous changes? I use the mouse to drag a UI object from point A to point Z, but before I release the mouse button I've dragged the UI object through every point in between. Do we store every intermediate point in the undo manager, or just the start and end points?

It's a rhetorical question; of course I'm only going to store the start and end points. How?

Without an undo manager, every mouse-move event could simply set the UI object's x and y co-ordinates.

Mouse::Move(int x, int y)
{
ui_object.SetPosition(x, y);
}

UIObject::SetPosition(int x, int y)
{
this.X = x;
this.Y = y;
}



How do we make moving a UI object undoable? We're going to need to split the action up into distinct parts.

While we're dragging the object, we would like to see it being displayed in its current location, so the X and Y values will still need to be changing continuously. What we'll need to do is remember the start location when we begin dragging, and the end location when we finish dragging, then add those locations to the undo manager, along with appropriate functions for setting them.

We end up with something like this:

Mouse::BeginDrag()
{
Point startPos = ui_object.currentPos;
}

Mouse::Move()
{
ui_object.SetPosition(x, y);
}

Mouse::EndDrag()
{
Point endPos = ui_object.currentPos;

if (startPos != endPos)
{
UndoAction act;

act.UndoData = startPos;
act.RedoData = endPos;
act.UndoCommand = UIObject::SetPosition;
act.RedoCommand = UIObject::SetPosition;
}
}



So what seems like it should be a simple enough mechanism, actually turns out to be pretty darn complicated...