Code responsibly or your work can haunt you

Have you ever written code that was below your average quality? I have, and sometimes I wish I could have write it better then.

There had been times when I came across some of my older work, and I’ll be tempted to rewrite or refactor or rework the code or logic. Then I told myself that I did the best I could then, and I should let it go. Focusing my energy on future projects is a better use.

That said, sometimes your creations can come back and haunt you. Like in this animator versus animation video.

A void in humanity

With the advent of more powerful communication tools enabled by technology, will the congregation of social groups suddenly create voids in our humanity? Let’s time travel to the past for a while.

I remember a time when connecting with family and friends was done either face to face or using the phone (the landed one). Then people around me started carrying these things called mobile phones, and it was considered hip to actually own one. I was oblivious to this accessory, since I haven’t found a need to be constantly contactable.

Then I started studying in a university, and through force of pressure, I was strongly persuaded to get a mobile phone. It was a flip phone, one of the earlier models that I got from a friend.

I also found out about the Internet. The hip thing then was ICQ and MSN Messenger, two instant messaging software available. Through peer pressure, I was again strongly persuaded to sign up, so I could go home and chat with my friends online. The conversation usually degenerated into near-monosyllabic words and arcane short forms like gtg (got to go) and lol (laugh out loud).

When we’re free in between attending lessons or doing homework and research, my friends (and I, you got it, strongly persuaded) logged on to Neopets, and practically bashed on the refresh button on the web browser so we could get our virtual hands on the store items when the Neopets server restocked.

Then people found the Internet to be a fantastic communication medium. Community web sites sprung forth, empowering people to reach beyond to the world. Forums and other online groups became connecting points.

Technology advanced. Better features. Faster upload/download speeds. And Web 2.0 came. Digg, Reddit, Technorati, StumbleUpon, Facebook, MySpace, Flickr, YouTube and other social media sites appeared. And people flocked to them in droves.

We seem to have this innate need to connect with other people. Like this elderly gentlemen whom Darren met while shopping for inspiration. Text and images on web sites aren’t enough anymore. We want to see and hear people through the Internet too. Audio and video are becoming more important. My blogging mentor, Yaro Starak, is also experimenting with more video posts, along with Darren and other bloggers.

Then I read about this article on a hole in the universe. Astronomers found a void in space, and their explanation was that gravity from high density masses are attracting nearby matter. When enough of these attractors came together, a void was formed because of the absence of matter between the attractors.

Will this happen to us? Will our new generation social media groups unwittingly create voids in our humanity, by pulling in masses of people to them?

Beginning C# – Reading Input Writing Output

There’s a saying in programming that goes something like this

Be liberal with what you receive. Be strict with what you produce.

What it means is that your program should be lenient with the input it receives, to assume that all sorts of rubbish data can (and will be) fed to your program, and it’s your duty to make sure your program can handle it.

BUT, your program must adhere strictly to the output format it’s supposed to produce. If your program’s supposed to write out integers, it better write out only integers.

It’s not fair, I know. It also makes it easier for programs to talk to each other, since input and output of programs are what they communicate with. The most common communication methods is through file input/output or file IO as they’re usually referred to.

I personally find the StreamReader and StreamWriter classes to be easy to use for file IO. The .NET framework views file IO as a form of data stream. Other classes dealing with data streams include NetworkStream (working with data across networks) and MemoryStream (working with data within computer memory).

So how do we read input and write output? Let’s look at some source code first. [code formatting looks better from web site]

StreamWriter sw;
sw = new StreamWriter("greetings.txt");
sw.WriteLine("Good morning!");
sw.WriteLine("Splendid day isn't it?");

string[] flowerlist = new string[] { "daffodil", "lily", "orchid", "rose" };
sw = new StreamWriter("flowers.txt");
foreach (string s in flowerlist)

// the second parameter indicates if file should be appended or not.
// If the second parameter is false, it would have overwritten the
// contents from above, and flowers.txt would only have 2 flowers.
sw = new StreamWriter("flowers.txt", true);

File.WriteAllLines("greetings2.txt", new string[] { "Hello!", "How are you doing?" });

// we start reading the files and writing their content here
sw = new StreamWriter("result.txt");
StreamReader sr;

sw.WriteLine("{0}Reading from greetings.txt", "=".PadRight(20, '='));
sr = new StreamReader("greetings.txt");
while (sr.Peek() > -1)
   // we read one line and write one line
sw.WriteLine("{0}End of greetings.txt", "=".PadRight(20, '='));

sw.WriteLine("{0}Reading from flowers.txt", "=".PadRight(20, '='));
sr = new StreamReader("flowers.txt");
// we use sw.Write() instead of sw.WriteLine() because
// flowers.txt already contained a newline character at the end.
sw.WriteLine("{0}End of flowers.txt", "=".PadRight(20, '='));

sw.WriteLine("{0}Reading from greetings2.txt", "=".PadRight(20, '='));
sw.WriteLine("{0}End of greetings2.txt", "=".PadRight(20, '='));


Console.WriteLine("End of program");

The code’s quite straight forward. I want to highlight a small code section

"=".PadRight(20, '=')

This is a shortcut to generate 20 equal signs. It beats writing a for loop or manually typing in 20 equal signs.

The StreamReader.Peek() function returns the next character but doesn’t read it into memory. If there’s nothing left to read, like End Of File (EOF), then a -1 is returned. This makes the function a suitable termination condition for a while loop reading in file content.

The StreamReader.ReadLine() function reads in input until it hits a newline character, and returns all input read thus far in a string. The StreamReader.ReadToEnd() function basically dumps the entire file content into a string.

With .NET framework 2.0 comes another way to rapidly and easily read data from files. The File class has been beefed up with some nifty new functions. The following functions allow reading in input from a file with just one line of code

  • File.ReadAllBytes() – returns file content in a byte array
  • File.ReadAllLines() – returns file content in a string array
  • File.ReadAllText() – returns file content in just one string (newlines and all)

Then there’s the corresponding one-liners for writing output

  • File.WriteAllBytes()
  • File.WriteAllLines()
  • File.WriteAllText()

These one-liners read/write content to/from a file and closes the file, all in that one line. It’s basically a shortcut compressing one line to open a file, one line to read/write file content, and one line to close the file.

As always, you are encouraged to explore the (online) MSDN documentation for more details. Study how to instantiate a class and what are the public properties and functions available.

You don’t have to memorise and learn how to use every single function. Just remember what kinds of functions are available. Then when the time comes where you need a particular feature, you’ll know where to look.

Download the source code.

Paint.NET Review

I remember a time when I didn’t have any image editing software available on my computer, and I needed to create some images for my web site. The image editing software I knew then were Adobe Photoshop and Corel Paint Shop Pro (formerly from Jasc). I was a student then, and cash was tight, and the money saved could be used on something more important. Like feeding myself.

So I used the only available free software I had: Windows Paint. Oh it was terrible! I wanted to draw some circles with antialiasing, and I painstakingly drew each differently shaded pixel in. I moved close to the screen to see the pixels and moved away to see the general effect. Have I mentioned it was terrible?

If only I had Paint.NET then! Well, the .NET framework wasn’t out then, so Paint.NET won’t be too. But YOU! You now have the power to edit images to your heart’s content. Now go download the FREE Paint.NET software and come back here so I can tell you more.

Done downloading and installing?

Ok, so Paint.NET has the basic features provided by Windows Paint, such as colour picker/dropper, pixel pencil and line/curve drawing. I miss the spray can in Windows Paint though… it gave me tons of fun, and if it could be combined with the Gaussian blurs… *sigh*

Anyway, now that I’m a full-blown programmer slash web developer slash designer slash tech documenter, I need to work with images more often. Windows Paint wasn’t cutting it anymore… So what does a polymath programmer who has to juggle many different roles need in an image editing software?

  • Layers
  • Colour selection
  • Nifty effects out-of-the-box
  • Colour swapping
  • Text and arrows

Layer upon layer
Once a secret hoarded by the corporate image editing software companies, and heralded as a distinctive advantage, Paint.NET also grants you this special and mysterious power.

Paint.NET layer panel

Frankly speaking, I don’t know what the big fuss is about. I’ve only maybe used up to 3 layers at any one go. Then again, I’m just trying to create an image that looks good enough in a web application so my work isn’t totally disgraceful.

Perhaps there will come a time where I need to blend transparency, match gradients and create colour swatches with several images to create a final masterpiece. … Just thinking about it makes my head hurl…

Ooohh, look at the purty colours
In my work, I need to rapidly select colours and see how they affect the image I have in my head. Paint.NET does this beautifully, where I can choose from a colour wheel, a standard colour block, or enter the exact RGB or HSV values.

Paint.NET colour panel

I also bring your attention to the hexadecimal input/output box. Very useful for CSS colour values. It was so inconvenient for me to translate red, green and blue values into #rrggbb format at one point in time, that I wrote a program to help me do the translation. This is an awesome feature for me.

Cool effects to liven up your images
There’s a whole range of image effects to give your drab image an extreme makeover. There are blurs and distortions, red eye removal and portrait softening plus edge detection and embossing. Two of my favourite effects are frosting and oil painting, taking this
Clock photograph
To frosted glass
Frosted glass clock photo
Or turn it into an oil painting like this
Oil painting of clock photo

Colour swapping
I have code to write, emails to reply, phone calls to answer, web pages to develop, bugs to squash and documents to create. The last thing I want is to spend half an hour trying to get the colour of a background image for a web application just right.

Sometimes I just need to see how a different colour looks and feels. Paint.NET gives me an easy way, using a slider to shift say a blue gradient
Colour swapping - from blue
To maybe a pink one
Colour swapping - to pink

It’s a quick, easy and painless test for that elusive perfect colour shade.

Words and pointy things
Despite my distaste for writing documents that no one will ever read again (but have to be created to satisfy business requirements), I have found that screenshots alleviate most of the drudgery of presenting information.

Why give your users a screenshot
Choosing an option
And then tell them to click [Effects], then click [Distort] and then choose [Twist]? You can simply provide in-image instructions like this
Choosing options - with inline help

The pointy arrows are a lifesaver. You have no idea how hard it is to draw a line pointing to an area in the image, and then try to draw two short lines to form the arrow head. And it is a simple effective way to communicate to your users the instructions you need them to follow.

Paint.NET is easy to use, and you can quickly learn to apply simple steps to create jaw-droppingly-gorgeous images. For programmers like me, whose companies have uh, limited budgets, Paint.NET is a must-have.

From creating simple icons and backdrops for web pages to creating descriptive screenshots for documentation, Paint.NET takes away your imaging tasks and lets you focus on coding.

I’ve been a follower of Paint.NET since its version 1 point somethings. At my work place, I actually felt sad when Paint.NET moved to .NET framework 2.0. I only had Visual Studio 2003 installed then, which runs on version 1.1, and I couldn’t risk installing version 2.0 in case something happened to my computer. A lot of people depended on my computer in working condition, even if they don’t know it.

So I breathed a sigh of relief when I got the approval from the powers that be, to buy Visual Studio 2005, and hence I can upgrade to .NET framework 2.0 and hence upgrade to the latest version of Paint.NET with all its new and nifty features! I doubt the powers that be read my 15 page proposal, but hey, I got the result I wanted.

So go download Paint.NET now! And did I mention it’s free?

Path of a Polymath Programmer Part 1

What is a polymath programmer? First, you need to know Merriam-Webster’s definition of a polymath, who is

a person of encyclopedic learning

Wikipedia says a polymath

may be a person who knows a great deal about several fields of study, a person who has proficiency and competence in multiple fields, or even a person who has excelled in multiple fields.

And to answer the very first question:

A polymath programmer is a person who has proficiency and competence in many programming related activities or tasks. More importantly, a polymath programmer can apply knowledge and expertise from non-programming fields to programming.

After reading the above definitions, your first thought might be, “Oh, a jack of all trades”, followed by “and a master of none”. There’s actually a third line to the phrase, and is particularly important to programming.

A jack of all trades
And a master of none
Though ofttimes better than master of one

In fact, being a master of only one programming skill will get you fired faster than you can say “Sacrebleu“. Technology moves fast, and by the time you understand a new language or technique or concept, another one is invented. If you can’t keep up, you’ll be left behind. Doing one thing well isn’t enough anymore. And this is particularly true in our programming field.

What you need is a broad and stable base of knowledge and skills to support you when you travel the shifting sands of the IT landscape. This base of knowledge must be relatively impervious to change, so you need minimal learning time when a new change is invented. And this is why a polymath programmer will thrive, while the average programmer strives to survive.

So how do you become a polymath programmer? I don’t believe there’s one true path to becoming one, but I can guess. Let me start by asking a question. Have you noticed how some physicists and mathematicians make better programmers? They aren’t any better at programming than regular programmers. In fact, some mathematicians write code that’s an abomination to even look at.

So what’s the secret? They can think. And they have an insatiable curiosity about the world around them, whether it’s related to their field of study or not.

Now let me tell you my journey of becoming a polymath programmer. I have to tell you that it didn’t happen overnight. In fact, it took years. And I didn’t even realise I was slowly becoming one.

It started when I was maybe 9 years old. I remember learning and memorising the multiplication tables. I also learned to play chess, Chinese chess and checkers.

I read voraciously. I adventured with Tin Tin, met characters of Enid Blyton, sleuthed with the Hardy Boys and solved mysteries with Encyclopedia Brown. My parents bought me an encyclopedia set, and hours passed by as I browsed through the books, particularly the ones on science and mathematics. The Norse and Greek gods also provided me with tons of legends about heroes and villains.

I also remember this fascinating story explaining why the earth was bountiful for about 6 months only, because Persephone ate 6 pomegranate seeds given by Hades, so she’s forced to stay in the underworld for 6 months. Persephone’s mother, Demeter, the goddess controlling seasons, wept whenever her daughter went underground, and thus the unfruitful and harsh seasons of fall and winter.

Great, but what does all this mean for you? It fires up the imagination, and as Albert Einstein says, “Imagination is more important than knowledge“. You’ve got to be able to imagine and visualise a problem before you could solve it. Then you’ve got to imagine and visualise a solution before you could distill it into programming logic, and subsequently into code.

Then came the part that might interest you more. I got a toy computer. Yes, it was a toy, because my parents bought it from Toys R Us. The other programmer geniuses I read about usually had some ancient artifact of a computer like an XT86 or something. I still got an XT86, but that was later on.

Oh yes, back to my toy computer. It had the standard keyboard. No mouse. And a one line output screen. No graphics. Its play functions included

  • questions and answers about general knowledge, math and science (amongst others)
  • games like hangman
  • typing practice

And the most significant one of all? It included a BASIC compiler! Not that I knew what a compiler was then. I was just ecstatic that I could print a “Hello World!“. I pored over the instruction manual, learning all the BASIC commands listed. I learned the concept of commenting by starting a line of code with REM. I learned that numbering the lines of code makes the code run in sequential order. I questioned the practice of numbering in multiples of ten, even though BASIC code ran perfectly fine so long as the numbers were in increasing order.

Then something happened that jump-started my learning process. There was a book fair in my school, and as I browsed through the offerings, I found and bought two distinct sets of books. The first set included 3 (I think) books called Dragon Warriors, a series of role playing games (RPG) with instructions on playing and game mastering. The second set included a few books from the micro adventure series, where you play Orion, an adolescent secret spy whose area of expertise was programming!

How did those two sets of books propel me towards being a polymath programmer? I’ll tell you more in the next part of this series of posts. … Alright, fine, I’ll give you a preview. Both sets of books wove story plots, game problem mechanics and code tuning/tinkering together.

See you on our path to becoming polymath programmers!

Continue to part 2

Never question the age of a woman

I’ve always had the impression that no one should ask about the age of a woman. In fact, no gentleman would be caught dead contemplating the very act itself. Anyway, a childhood song rose out of my submerged memories recently and it goes like this:

How old is she, Billy Boy, Billy Boy?
How old is she, charming Billy?
Three times six and four times seven,
Twenty eight and eleven.
She’s a young thing and cannot leave her mother.

The issue isn’t with how the song is sung. I was in primary school then (about 11 years old), and one of my more expressive classmates pointed out to the music teacher the improbability of the truthfulness of the lyrics. He proceeded to prove his point:

Three times six and four times seven,
Twenty eight and eleven.

(3 * 6) + (4 * 7) + (28) + (11)

Which comes up to a grand total of *drum roll* 85!!

Being 11 years old then, 85 years old was like, ancient. Still, 85 years old wasn’t unusual. My cheeky classmate then asked, “How can 85 years be a young thing?”

My music teacher was speechless.

Tackling problems with indefinite answers

In your programming career, have you ever faced a problem where there’s more than one answer? Or that you don’t even know if there is a right answer? Let me tell you one of mine.

Recently, one of my colleagues came to me for advice on a validation condition he faced. It turned out to be mathematical in nature. Wow! Anyway, in his database he stored number_of_days, month and prorated_fee. The stored data contains records of the results of prorating calculations.

What is prorating? Say a customer was charged a monthly fee for a service, and the customer had just signed up for the monthly service near the end of June. And he had the service for only 5 days, June has 30 days, and the monthly fee is $20. Prorating means he’d be charged 5 / 30 * $20 = $3.33. You will have noticed that prorating often has inexact results because the calculated values are rounded to 2 decimal places.

Back to my colleague’s problem. Suppose that the records from the database looked like this

days  month  prorated
5     30     3.33
8     30     5.33

I’ve translated the month into the number of days in that month for easier visualisation.

The problem was, given those records, could he prove that the prorated fee was calculated from the same monthly fee?

For this example, the monthly fee used was $20, so the results match. What he needed from me was, was there a way to programatically determine if there was a correct original monthly fee?

My initial instinctive answer was no, because all precision of the calculation was lost when the final value was rounded. Then he said, he’s not looking for precision. He just wanted to know if there was a possibility that the records were calculated using the same monthly fee. Aaahhhh, now we’re talking. So I told him to give me some time to work out an equation or something. Then I went to work.

Mathematically formulating the problem, I got:
Given d, m and p, where
d is the number of days in service
m is the number of days of that month in service
p is the calculated prorated value
find f, the original monthly fee, such that abs(fd/m - p) < 0.005

The equation is fd/m = p', where p' is the exact calculated value. Then p' is rounded to p.

The abs(fd/m - p) < 0.005 condition was because of the rounding. The difference between the calculated value and the stored value must be less than 0.005 for the rounding to be correct. And the error margin is 0.005 because 2 decimal place rounding means the value to be rounded is less than half of 0.01.

Rewriting the condition, we get
-0.005 < fd/m - p < 0.005
=> -0.005m < fd - pm < 0.005m
=> -0.005m + pm < fd < 0.005m + pm
=> (p - 0.005)m/d < f < (p + 0.005)m/d [d is always positive, so division is fine]

Substituting our first record's values into the inequality, we get
(3.33 - 0.005)(30)/(5) < f < (3.33 + 0.005)(30)/(5) => 19.95 < f < 20.01 Substituting our second record's values into the inequality, we get (5.33 - 0.005)(30)/(8) < f < (5.33 + 0.005)(30)/(8) => 19.96875 < f < 20.00625 Now if there were more records, we'd continue substituting, and we'll end up with a lot of inequality ranges. So what's the solution to the problem? If there was an f such that it satisfies all the inequalities, then the prorated values could have been calculated from the same monthly fee.

I went back to my colleague and told him that even if the inequalities could be solved, he might still have a range of values that could have contained the original monthly fee. So there's still no exact answer. He said that was fine. He rephrased his objective, that he wanted to know if the records from the database could have been calculated from the same monthly fee within reasonable limits.

Ohhh. Ok. I told him if he could find a range of values of f satisfying the set of inequalities from above, and that there was a value in that range with at most 2 decimal places, then he's done.

Example, a range of (19.956, 20.00) would be valid, because the original value could be 19.96 or 19.97.
But a range of (19.956, 19.959) would be invalid, because there were no values that had at most 2 decimal places. The reason for this was that the original monthly fee was at most 2 decimal places.

So, how do we find that range of values of f satisfying all the inequalities?

Let L be the set of the left hand values of the inequalities. Let R be the set of right hand values of the inequalities. Then there's a range of values of f satisfying the inequalities if and only if the maximum value in L is less than or equal to the minimum value in R. Stated mathematically,

max(L) <= min(R)

I gave him the piece of paper where I scribbled my notes, and he copied some of the important formulae. What about determining the solution programmatically? What, are you kidding? I wracked my brain for a mathematical solution, distilled it into understandable logic steps. How to implement this was up to him... *grin*

Have you proven a hunch before?

It was one of those morning math lectures. The lecture theatre was unusually quiet, and the only sounds I heard were those of my fellow students’ pens, scratching feverishly across the surface of their note pads. The professor happened to mention that no one’s ever proven the existence of infinite twin primes.

A prime number is a positive integer which is divisible by only 1 and itself. Examples are 2, 3, 5, 7 and 11.

Twin primes are prime numbers that differ by 2. Examples are (3, 5) and (11, 13).

Anyway, after that lesson, I was wracking my brain to find the proof (I felt challenged by the impossibility), and I started making up lists of numbers and adding them up. I’ve already convinced myself that all primes are odd, except for 2, so I focused on odd numbers. To my surprise, I found an interesting relationship in sums of odd integers.

I was adding the odd numbers starting from 1. So I got
1 + 3 = 4
1 + 3 + 5 = 9
1 + 3 + 5 + 7 = 16
1 + 3 + 5 + 7 + 9 = 25

As I got further into the sums, I realised that the sums are square numbers! Ok, so it’s not Nobel Prize material, but hey, I was in freshman year then, so this was pretty cool. Then I got swamped by homework, and I didn’t give this any more thought.

Some time later, my mind was freer and the idea came back with a vengeance. So I thought, “Can I prove it?”. My math lessons included a lot of proving problems, and I was naive then, so I hadn’t yet developed a healthy fear of the Terrifying Triple: show, prove and justify.

So I finally put some effort into it. The sequence looks like an arithmetic series, so I applied the formula for sums of arithmetic series.
S(n) = n[2a + (n – 1)d] / 2
where n is the number of terms, a is the first term, d is the difference between consecutive terms and S(n) is the sum of the first n terms.

The first term a is 1, d is 2 and I substituted the values into the formula:
S(n) = n[2 + (n – 1)2] / 2
= n[2 + 2n – 2] / 2
= 2n2 / 2
= n2

That wasn’t much of an exercise. The point is, have you ever tried to prove a hunch before?

There was this incident where one of our production programs failed. I tried debugging the program, analysing the code and took the whole morning poring over every line, and still couldn’t pinpoint the error.

My colleague came in, took a look at the program code, got an “Aha!” moment, and gave me this priceless advice, “Increase array size“.

Well, I’m not totally without results, since I figured that it was due to an insufficient array size. I was simply trying to pinpoint the exact place where I should increase the size. My colleague’s next piece of enlightening advice, “It doesn’t matter. Increase ’em all.“.

I was at my wit’s end, and I had backlogs of emails and requests coming in, so I gave in. I simply increased the array sizes of all the affected array variables, compiled it and tested it. It worked! I pursued the proving of a hunch too far and too long.

As a perfectionist programmer, this moment of weakness rankled my principles. I’ve since learned that sometimes, I have to let go of some ideals, and use the extra energy for other more constructive purposes.

Have you ever had to give up some of your ideals too?

MathSpeeder – Firing neurons and nimbling fingers

Alright, it’s been kinda boring lately… so I’ve decided to whip up a picker-upper that will rejuvenate your brain and excite you again. You’ll be churning out flawless code in no time after this.

Enter the MathSpeeder.

MathSpeeder is a console program that fires a series of math questions. Your job is to answer all of them correctly. Oh yeah, you’ll be timed too. Ain’t that cool? Here’s the source code:

const int cnNumberOfQuestions = 10;
string response = string.Empty;
Console.WriteLine("MathSpeeder - Firing neurons and nimbling fingers");
Console.WriteLine("There are {0} math questions", cnNumberOfQuestions);
Console.Write("Ready to play (y/n)? ");
response = Console.ReadLine().ToLower();
if (response.Equals("y"))
    int operand1, operand2, result, answer;
    int score;
    Random rand = new Random();
    score = 0;
    DateTime start, end;
    start = DateTime.Now;
    int i;
    for (i = 0; i < cnNumberOfQuestions; ++i)
        operand1 = rand.Next(1000);
        operand2 = rand.Next(1000);
        result = operand1 + operand2;
        response = string.Format("Q{0}", i + 1).PadLeft(3);
        Console.Write("{0}: {1} + {2} = ", response, operand1, operand2);
        response = Console.ReadLine().Trim();

            answer = Convert.ToInt32(response);
            if (answer == result)
                Console.WriteLine("     Correct!\n");
                Console.WriteLine("     Wrong!\n");
            Console.WriteLine("     Wrong!\n");
    end = DateTime.Now;
    TimeSpan ts = end - start;
    Console.WriteLine("You got {0} correct answers out of {1} questions", score, cnNumberOfQuestions);
    Console.WriteLine("Total time taken: {0,0:f2} seconds", ts.TotalSeconds);
    Console.WriteLine("Average time per question: {0,0:f2} seconds", ts.TotalSeconds / (double)cnNumberOfQuestions);
    Console.WriteLine("Challenge the MathSpeeder next time then!");

Console.WriteLine("End of program");

Download the source code

Get the program if you’re too lazy to compile the source code. Needs .NET Framework 2.0.

Here’s my result
MathSpeeder result
I must be losing my edge… over 5 seconds per question?

So what’s your score?