Drowning in things to do

The heart of a good 'Getting Things Done' process is to have a Single trusted system where you capture your tasks.

I guess I'm Doing It Wrong :-(. Here's all the places where I distribute my todo list...

  • In my current moleskine (pronounce it with me -- Moh-leh-skeen-ah) on pages 9, 12, 31, 57 etc.
  • in my phone
  • in outlook (at work)
  • in my code using //TODO: tags (scattered over numerous projects)
  • in my code using NotImplementedExceptions.
  • in timesnapper's hosted fogbugz account
  • in 'nextaction' on my work pc
  • in 'nextaction' on my home pc
  • in 'nextaction' on my laptop
  • in my gmail account (emails labelled 'todo')
  • in my gmail account (emails marked with a star)
  • in my gmail account (any emails from me)
  • in my other moleskine, beside the bed

Still, I think i'm pretty good because I do actually tend to 'get things done'. But also because i resist keeping lists in all these other places:

  • in iGoogle
  • in sharepoint (at work)
  • in my gmail account (using the Gmail Tasks plugin)
  • on pieces of paper on my cubicle wall
  • in my other notebooks
  • in timesnapper using flags/tasks/notes
  • in yet another todo.txt file
  • on sticky notes randomly decorating places I inhabit
  • in twitter
  • in tada list
  • in that surprisingly popular codeproject todo list
  • in remember the milk
  • in a tiddly wiki
  • in the iphone i don't have
  • in the PDA i don't have
  • in chandler
  • at trimpath 'next action' web site
  • on my blog
  • using tattoos (memento style)
  • in google calendar

There's no shortage of places to keep your things to do.

I don't worry about having too many systems. A bigger fear is failing to capture a problem as it arises.

You frequently get just one chance to capture an idea, so I capture it anywhere I can.

 

Small Moments in Software Philosophy

I've been using my tiny slice of computer time to write software lately, and haven't spared any cycles for writing articles. In lieu of that, here's a series of lost notes to accompany some of my recent twitter outburts.

Abstractions should be as high-level as possible, and no higher. #

Einstein of course said,

"Make everything as simple as possible, but no simpler."

... and that's a kind of programming mantra, as so often in our race to simplify we end up over-simplifying. (The famous 'Worse Is Better' philosophy could be phrased as an argument that sometimes you should actually sacrifice correctness for the sake of the simplicity -- i.e. 'Einstein was wrong.')

In a similar vein, I think there there is such a thing as 'too abstract'. And it is a terrible thing.

Pre-emptive Abstraction is at least as bad as Premature Optimization #

  • If your class name contains the word "Abstract" -- you're doing it wrong.
  • If ClassName.Contains("FactoryFactory") -- you're doing it wrong.
  • If Your ClassName Ends With "BaseBase" -- you're doing it wrong.
  • If ClassName.Contains("Factory") && ClassName.Contains("Provider") -- you're doing it wrong.

Economists re-evaluate bird in hand as 1.9 times bird in bush. #

A more appropriate tweet might've been:

'Economists write down bird in bush to 0.45 times bird in hand.'

Or:

'Government provides 8 trillion birds-in-hand to replace 16 trillion birds lost in bush.'

Someone (I think that cockroach poet Archy) once called humanity something like "a strange species of bipeds who cannot run fast enough to collect the money which they owe themselves."

i am *not* homophobic. Infact, some of my best friends have iPhones. #

And I'm still waiting to see them make the millions of dollars from iPhone apps that they promised themselves last year.

If a job's not worth doing, it's not worth doing properly #

The original statement: "If a job's worth doing, it's worth doing properly" has the corollary that any job that is not worth doing properly is therefore not worth doing at all.

This is patently absurb and a kind of shining example of why perfectionism doesn't pay.

The slightly twisted variation:

If a job's not worth doing, it's not worth doing properly

...may seem defeatist and sloppy -- but i think it's the very soul of true productivity.

That's what no one seems to appreciate about being rich: the first 100 bazillion is the hardest. #

After that, you can just sit back and live off the interest of the interest.

And your next code editor is... a browser. #

I still think it's true -- and once i get a bunch of other things out of my todo pile -- i'm going to make it happen. Maybe.

Meanwhile I'm working on TimeSnapper v.Next, and tinkering on something tentatively called MetaNote -- about which you'll be hearing more.

 

Differentiating between environments within SQL Server Management Studio

you are about to execute a DROP statement in production, OK or Cancel?

When you're looking at a query window that's connected to Production, it would be nice if it was visually distinct from a non-production environment.

For example, there could be a red theme applied to the window.

Furthermore, there could be a warning before a potentially destructive query is executed. (Essentially, any query that isn't just a select - for example, a drop, delete, update, insert, create or alter)

This would be an effective way to lower the chance of something being done to production that was intended for another environment (pre-prod say, or development)

I can imagine a straw-man counter-argument to this concept that says:

"The only people who should have access to production are people who know what they're doing"

Or alternatively,

"Developers shouldn't have access to production"

And that's fine by me.

We can limit who accesses production, and we can give minimum privileges to those that do have access.

But even then:

*Someone* will have destructive privileges in production.

And that person will definitely have access to more than one system.

And that person, no matter how smart or conscientious they are, will be fallible.

Hence, it's helpful for that person to be able to differentiate (visually) between the different environments.

Why am I writing this blog entry right now?

Don't worry. I stopped myself in time ;-)

(And like all blog posts everywhere, there is already a stackoverflow question that says the same thing and a whole lot more)

 

My code would suck less if...

My code would suck less if the C# compiler raised an error anytime it detected the following:

  • A button with no click handler.
  • A click handler with no code.
  • A parameter that is not used.
  • Code that throws A 'NotImplementedException'
  • A //TODO: token.
  • An #if DEBUG
  • A phrase that contains more than one dot, e.g. Control.Parent.Parent.Parent.Controls[3].Controls["Accept"]

Q: Why do I want the compiler to be so mean?

A: It takes a tough man to make a tender chicken.

(attributed to Purdue, quoted in 'Worse Is Better')

No, the common thread here is these are pitfalls common to a top-down, (or an outside-in) design approach.

As you move top-down, (or from front to back), you throw off "branches" -- kind of last strands -- that you need to back-track to complete later. I want the compiler to help me find those branches. (Tests are a poor substitute)

In his 2005 classic 'Does Visual Studio Rot the Mind?' Charles Petzold showed how intellisense-and-friends encourage bottom-up programming.

These are some little features that could help out the die hard top-down coders.

Details...

The Really Big Button That Doesn't Do Anything (Don't let this happen to you!)

"A button with no click handler"

Why does a button exist? Is it just to look good?

No! Buttons are for clicking!

A button with no click handler is a fail.

And a click handler with no code is a fail as well.

What does the user expect when you click a button?

Unless this is that Early Internet Phenomenom known as The Really Big Button That Doesn't Do Anything, a user expects *something* from a button.

Why would you check that in? What good can possible come from letting do-nothing buttons end up in the hands of unsuspecting users?

The world of static code analysis has gone very far -- but does it stop and help us avoid this sort of psychological torture?

(This same concept may be true for many other objects that raise events. The object's author might be able to indicate "There's really no point using this thing unless you handle the following event(s).")

A parameter that is not used.

Unused variables raise a warning, but unused parameters don't.

This is a little bit good, but it's a little bit bad as well.

Here's an example where the unused parameter is clearly a bug:

    private void CopyFile(string sourcefileName,
                        string targetFileName,
                        bool overwrite)
    {
        System.IO.File.Copy(sourcefileName, targetFileName);
    }

Oops!

The programmer forgot all about the 'overwrite' parameter!

I consider that a pretty clear error.

But consider our click handler for a moment:

    private void Button1_Click(object sender, EventArgs e)
    {
        MessageBox.Show("Hello");
    }

Neither parameter is used. But if we were to call this an error, a hell of a lot of code that's shipping today would fail.

Some design changes could alleviate the dilemma -- I'll leave the consideration of possible solutions as an exercise for the interested reader. The goal is to avoid busy work, not create it.

Code that throws A 'NotImplementedException', and //TODO: token, #if DEBUG conditions and everyone from System.Diagnostics.Debug

Not Implemented Exceptions are excellent stuff.

But your goal is always to eradicate them, right? They're a kind of hardcoded place holder. A warning ought to suffice. (You treat warnings as errors, most of the time, right?)

I put //TODO: tokens and #if DEBUG conditions in the same category. They're very handy scaffolding or place holders as you crank out your code -- but they're not supposed to remain indefinitely. A warning would be nice. Maybe Debug.WriteLine and its friends should fall into the same category.

A phrase that contains more than one dot, e.g. Control.Parent.Parent.Parent.Controls[3].Controls["Accept"]

Why would a compiler let you get away with this kind of monstrosity?

It would be quicker to just replace that whole line with "throw new NullReferenceException()". The effect would be the same.

My point here is that this kind of implementation of the house of cards anti-pattern is easy for static analysis tools to pick up.


I know that there are existing static analysis and code grepping tools that can be used for some of these cases, but they tend to run 'after the fact', outside the tight code-compile loop. Worse: they tend to produce a lot of noise and take a lot of care and feeding.

StyleCop is the worst 'busy work' generator I've seen. (If only they'd finished the job and had it auto-correct many of the problems it finds... instead, like '100% code coverage' it's a kind of training tool for Coder's OCD.)

Alrighty -- that's all I've got for now, though if I keep my eyes open, I bet I'll spot some more.

 

"Architect" is a swear word.

Ah! that's it!

I've often wondered what people really mean when they said 'Architect' while talking about software.

None of the literal meanings seem to capture the way the word itself is applied in this context. But I think I've hit the thing on the noggin at last.

A 'swear word' is a word whose literal meaning differs wildly from its contextual intent -- and whose intent can be bent to suit a great many contexts.

Take 'F---', for example. The word has a literal meaning, something like 'To copulate vigorously' -- but in actual use, the intent is generally bent to suit the context.

For example, when I hit my thumb with a hammer I say "F---!" and in that context the meaning is: "It hurts a lot when I hit my thumb with a hammer."

Or, when I get a flat tyre I say "F---!" and it means, "This flat tyre is an unexpected interruption to my day that will cause undue expense and wasteful exertion." The quickest way to say all that is simply "F---!".

Now imagine there is a guy in your organisation whose coding skills are terribly out of date, but who is not capable of performing any managerial duties.

If someone asks you, "Who is that guy?" then you probably won't waste your breath by saying, "Him? A guy whose coding skills are terribly out of date, but who is not capable of performing any managerial duties." Instead you'll permit yourself to emit a nasty little swear word and simply say, "Him? Architect." Ouch!

Now, just say you work with an impractical fool with an over-inflated sense of self-importance who destroys whatever thing he touches, never ceasing to bring layers of accidental complexity to even the simplest of contrivances, but who is, thankfully, kept out of harm's way by being assigned the task of writing grandiose-titled corporate documents that no one is ever expected to read. When someone asks you who that guy is, you draw your breath in deep, and prepare to say:

"Him? An impractical fool with an over-inflated sense of self-importance who destroys whatever thing he touches, never ceasing to bring layers of accidental complexity to even the simplest of contrivances, but who is, thankfully, kept out of harm's way by being assigned the task of writing grandiose-titled corporate documents that no one is ever expected to read." So, again, you'd just curse and say "Him? Architect?"

 

Plugins! Plugins! Plugins! It must be TimeSnapper 3.4

TimeSnapper version 3.4 went live a few days ago!

It can now run from a USB key, and is prettier in a few ways.

But the main feature is the new plugin model which lets you extend TimeSnapper with your own features.

TimeSnapperdown to $24.95!

The plugin model has been there for quite some time, but we've never publicised it before, or released any plugins that use it.

We've now released our first official plugin. A simple plugin that lets you create animated gifs from your snapshots. I've written a guide to help anyone who is interested in writing plugins of their own and provided a sample in VB, and a sample in C#. I can provide lots more examples, and information for anyone who is interested.

The animated gif plugin owes a debt of gratitude to Jon Galloway -- we reuse the Gif.Components.dll that he put together for his cropper plugin.

We're hoping to host plugins from other people -- we'll provide a nice page where people can download them. We'll help out with development, debugging and so on, wherever needed. If there's sufficient interest we'll spawn a separate forum for plugin development. (For now, the regular forum is the best place to ask questions).

Creation of an animated gif is in progress...

APIs are funny things -- and I received a hell of a lot of criticism while writing this API. The criticism came from a particular nasty and vocal user who never seems to be happy with any of the work I provide. That user is (of course) (in case you haven't yet guessed it) -- me.

So, if you're looking at the plugin model and you see something you don't like about it. Well, I understand. Constructive critcism and suggestions on how to improve the API are very welcome.

As always there are full details in the release notes, and there are lots more goodies on the way.

 

Test First Development and Making a Cake

blog,

One of the mixed curses of being obsessed with software is that you see reminders of it everywhere, even in things that predate the existence of software.

For example, Cake Making.

When you're making a cake, you need to add eggs to your cake mixture.

My wife told me that you don't break the eggs directly into the mixture. Instead, you break them into a separate bowl, and then add them to the mixture.

"Why not break them directly into the mixture?" I asked.

She picked up her cookbook and turned to Appendix A -- The SOLID Cooking Principles, by Robert C. Martin.

No she didn't.

She explained that if an egg is bad you don't want to ruin the entire bowl of cake mix. And it's easier to spot little bits of egg shell in a bowl of yolks than in a bowl of cake mix.

"Ah, the virtues of independent deployment," I said.

And she looked at me askance. (Askance is not the best way to be looked at, btw).

While we're discussing eggs, I have to repeat my favourite saw:

"You don't have to eat a whole egg to know it's bad."

 

(Side point: this topic fits with the stack overflow question "What real life bad habits has programming given you?" wherein you will find over 425 similar experiences. What a sad lot we is.)

 

A 3 minute guide to embedding IronPython in a C# application

A C# app that hosts iron python to perform calculations

Despite knowing absolutely nothing about Python, I've had a lot of fun and a few lttle victories with it tonight. I've built two small apps that I'll include the code for below.

I've avoided IronPython up until now, but a terrible problem has arisen lately.

I've decided to write my own text editor.

This is a bad thing. Only fools write their own text editor. Soon, hair will start growing on the palms of my hands.

But, since I'm looking for some extensibility in this editor idea (of which I'll show more in a subsequent post) I realised that hosting IronPython is the best way to get the sort of scripting I'm after.

Hosting IronPython in C# is well-trodden turf. Many other have been there and blogged it before. But the fun was really in the doing.

Here's two very short demo apps I wrote tonight, literally in under an hour.

First, by following the example Bernie Almosni provides in Extending your c# application with IronPython I built a little interactive calculator, with a history.

The code is trivial and can be downloaded below.

A C# app that hosts iron python to allow a textbox to be modified programmatically

The next example is also trivial, but I'll step through the code just quickly, since it's a superset of the previous example.

I wrote a little application that lets you write python code to alter the contents of a textbox. This is the heart of the editor I have in mind -- and it's barely 10 lines!

So, in a fresh C# winforms app, I added references to all the dll's in C:\Program Files\IronPython 2.0.1 (I didn't know which dlls i needed exactly -- so i referenced them all ;-) )

I created a new form and dropped two text boxes and a button on it, as you'll see in the screenshot.

I added these using statements:

using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;

I created two module levels variables, one to hold the IronPython engine, and one to tell it the 'scope' of the variables I want to share with it.

private ScriptEngine m_engine = Python.CreateEngine();
private ScriptScope m_scope = null;

Upon form_load, I construct the scope, and add the target text box to it. (This is the text box our Python code will be able to act upon.)

m_scope = m_engine.CreateScope();
m_scope.SetVariable("txt", TargetTextBox);

When the user clicks the button, I compile the code in the first box, and execute it as a statement.

Dead simple. Ridiculously simple.

string code = CommandTextBox.Text.Trim();
ScriptSource source = m_engine.CreateScriptSourceFromString(code, SourceCodeKind.SingleStatement);
source.Execute(m_scope);

With that in place, the python code entered at runtime, such as:

txt.SelectedText = txt.SelectedText.upper()

...has the desired effect of making the selected text uppercase.

I got the same effect in C# once, but it took five assemblies, hundreds of lines of code... it was terribly fragile and I broke it beyond repair before I got it to a source repository. A tragic episode, i still feel like stabbing someone every time I think about it. (LFT much?)/p>

So -- here's the source code:

download dodgy sample integrated C#/python code!  Sample Python Calculator and Programmable Text Box.

And here's a couple of other articles on the same topic:

 

Low Frustration Tolerance: Curse and Blessing

There's a psychicologicalous condition known as 'Low Frustration Tolerance', (LFT for short... abbreviations, btw, are helpful for those with LFT ;-))

Low. Frustration. Tolerance. I am writing slowly. Just to frustrate the Living Hell out of those who have LFT.

Every day you will see examples of people with Low Frustration Tolerance. You know these people.

You're in your car, stopped at the lights. Light turns green, and before you've put your foot on the accelerator, the guy behind you blares on his horn. Hard. He's got LFT. Bet on it.

To be a programmer REQUIRES a ^^high^^ level of frustration tolerance. Most people with LFT, on the other hand (OTOH ;->) end up as drunks, hobos, drop outs, early-deaths, burn-outs.

(But stick around -- there is a twist.)

So, the only way to be a decent programmer, able to produce good output every single day is to have a high-frustration-tolerance.

The amount of frustration we encounter in the computing world, every single day, is just astounding. Many days our job consists of leaping one hurdle after another.

Sometimes, just for fun, I keep a little log of the hurdles I encounter in a day. They are numerous.

I want to get from A to B. Step A: Something goes wrong. I investigate. Dead end. I google it. Dead end. I check logs. Dead end. I increase logging. More evidence. I google that. Dead end. I download a tool that will get more info. Tool fails to install. I google the installation failure. Dead end. I look for another tool, install that, run it: crashes. I investigate the crash. Dead end. I find a different tool, install that. Get more info. Investigate that. Dead end. Google it. Dead end. Stack overflow it: dead end. Drink coffee, consider taking up smoking. Dead end. Wait two weeks, increase bounty at stack overflow. Dead end. Reboot, check patch level, look for random hints from astrological tables, listen to reggae... dread end. Sometime later, randomly: breakthrough. And on step B.

Annnyway, I've established the first point: a good career in programming requires High Frustration Tolerance.

And yet... I am utterly convinced, that the only way to succeed as a programmer is to have really LOW frustration tolerance.

You have to get fired up by tiny little things. You have to care, dammit, and care deeply, about tiny little points.

You have to pour your heart and your soul into accepting nothing but perfection from that damn regular expression, that damn CSS selector, that damn SQL case statement, that bloody mother f***ing a*****e of a *** **** son of a ******* ugly ***** ***** **** of a **** installation package, so the lucky ******* **** of an end user gets all the joy of a working system.

It's a catch 22.

And sometimes we forget that *both* skills are needed. We fall into the trap of being one or the other.

So here's my latest plea:

Stopping being so easily frustrated. And please, stop settling for second best.

And then: tell me how it's done.

 

Handy cheat sheet for Visual Source Safe

After seeing this handy cheat sheet for the git version control system, I had to stop and reflect for a moment.

Despite all the attention that distributed version control systems get, I suspect that Visual Source Safe is still the most used source control system in the world.

And is anyone stopping to help the 'silent majority' learn to use their tool of choice, i.e. VSS, just a little better?

With this thought in mind, I've developed

'a handy cheat sheet for Visual Source Safe'

In all seriousness, your code is immensely valuable, and you need to respect that fact. Please use a reliable system.

If you're having trouble moving a sluggish team away from VSS, them move them onto Sourcegear vault. It re-uses the concepts and the look of VSS, but adds in reliability and a lot more.

If you're new to version control, or have projects that don't use *any* version control, get subversion up and running. It's easy to use on every system and it's free.

Git, etc: If you're a candidate for using a DVCS, then you already know all about it and don't need to take advice from an idiot like me.

One other plea: if you have 'little' projects that are 'too small to bother with source control' -- just re-think it.

Hooking up to a free subversion repository is easy, and beneficial. Hard-drives do crash, you know. And sometimes, you do need to roll back, you know.

Cheers and best of luck.