Tuesday, May 30, 2006

Is this insulting?

I just noticed the 'icon' that blogger uses for the accessibility feature for the word verification:

I'm sorry, but why would someone in a wheelchair need to use this feature? Surely this is more for partially sighted people?
On top of this, when I click it, Firefox claims it needs the Quicktime plugin, which I think breaks the idea anyway.
A case of the blind leading the blind? [Sorry, couldn't resist it]

Monday, May 29, 2006

Running Diary - Entry 2

Second run. 40 seconds running, 80 walking for 20 minutes. Felt ok afterwards, a bit snotty, but Amy was really suffering from hayfever and stopped after about the 8th repetition. She felt a bit low afterwards, but I think there may be other factors contributing to this too (something cyclic).
Realise I need to change my application for this so that I get a distinct tones for walk and run. Perhaps it needs to make my phone vibrate too, as it's easy to miss the noise and get out of synch with the walking/running part (as I found out after I ran for too long).
Also realise that I'm going to have to get on top of my hayfever this year, as it could hamper my training.

Saturday, May 27, 2006

Running Diary - First Entry

Running what? Eh? I shouldn't be writing a running diary. However, Bill's convinced me to run the Aviemore Highland Half-Marathon in October. I've been to the running shop in Huddersfield, and bought myself some fancy shoes (funny, they were cheaper in the shop than online!).
Went for a short run today, 20 minutes of 30 seconds running, 90 seconds walking. Wasn't too bad, but both Amy + I were feeling it as we walked up the hill home.

Thursday, May 25, 2006

Why do we write computer programs?

Ok, so beyond the core "because it's my job, and I get paid for it", I was thinking about why we write computer programs. (Yeah, ok, so "we" is used in a very loose sense).
The reason I could see was that they did something more efficiently that doing it by hand. Before you shout out "But I can write a letter with a pen and paper faster than I can load up Word and type it in", think about what the end result is. If you wanted the same output as Word produces, you'd have to either spend a long type with some old school type setting equipment, or learn to do caligraphy well. Neither would be faster than loading up Word and typing it in.
So, if programs are time saving devices, this puts them in the "tool" category. Sure, they're more complex than a hammer, but then they do more than a hammer does. (You could always go and look at the guys at 37signals, who think that computer programs should be a lot more focused). I digress...
Surely, then, we should be writing more computer programs, either to help us write computer programs, or to help us do something else that takes a long time.
An example of one of these programs is a SPAM filter - such as SPAMBayes. This has saved me loads of time in the past. Rather than having to spend hours (and I do mean hours - never publish your email address on the internet) trawling through emails, picking out the good ones, I set it up, show it some stuff that I already think is SPAM, and off it goes. Brilliant. Yes, it needs a little bit of help now and then, when my brother sends me a "forward this to 10,000,000 of your friends" email, but I think that's fair enough.
Back to the point - why is it so hard to write programs that automate existing programs? If you try programming any of the Office products using the macros, it gets really hard once you're past the "make this text bold" stage - mind you, getting the text to make bold in the first place is hard enough. Add to that the fact it forces you down the path of writing in a language which you might not be used to (VB sometimes makes me want to rip my own eyes out!), it leaves a bitter taste. Similarly, if you want to program Visual Studio.Net using macros, it's an uphill struggle, and some things that you think should be easy - such as finding out the function you're in, become very hard.
I suppose the problem here is that it's exposing the complexity of the underlying program. Sure, making a simpler wrapping on top of this would only increase the complexity, but when people like JetBrains (who write the amazing ReSharper) have to write their own C# parser, there's something very wrong.
Perhaps it'll get easier. Programming Google Maps is a doodle, once you get past the initial WTF. Similarly, programming Flickr is quite easy (especially if you use one of the already developed language specific libraries). As more and more programs/services expose APIs, perhaps we'll get better at writing them. Perhaps we'll need a common standard for APIs.
Anyway, this was going to be a rant about how, perhaps, we should be developing programs as though we were developing an API, and then write our front end on top of that. Certainly, that's not an original thought. But, perhaps, at the same time, we should be striving to write APIs that other people can use. Sure, there'll be a bit of learning to do for any API, but this should also be an understand of the problem domain, and the code behind the API should handle all the unnecessary detail.
I know I'm not there yet, but I'll keep on trying.

Argh! Hayfever!

These last couple of dayes, I've been feeling like I'm coming down with a horrible cold. Since it's been raining almost constantly for the past two weeks, I really didn't associate this with pollen. This morning I took a hayfever tablet, and suddenly I feel a lot better. Bloody pollen.

Sidenote: Outlook HTML email kills my blog layout.

Tuesday, May 23, 2006

Time Off Request

Time Off Request
Time Off Request,
originally uploaded by b3ardman.

I get round to booking time off today, which is done through the timesheet system.
What a terrible screen this is.

The required fields all have default values in them. This is one of my pet peeves. If something is required, it should either be blank or have a 'special' value in it, such as 'Select From Date'. How else can the computer tell if it's been filled in?

Time Off Code? What? These are all human readable values ('Bereavement', 'Holiday', 'Flexi leave'). I think this should be labelled 'Reason for Request', or something like that.
The default value for the Time Off Code (if there has to be one) is 'Bereavement'. So far, in 6 years of working live, I've taken precisely zero days off for 'Bereavement'. I've taken far more days off for Holiday than anything else, so why not default it to that?

From and To dates - now these really pissed me off. For one thing, they default to today's date. I'm in work, sitting at my desk, and the computer thinks I want to book today off. Also, I'm contractually obliged to give 2 weeks' notice of holiday requests.
Then, I select the From date (I have to click the little calendar to do this). Fine. I click to select the To date, and it show's today's date, rather than the from date I just selected (which it is also showing in the To date field). Argh!

I haven't used the Comments field. I can see, in certain situations, it may be necessary, but for the greater part, it's entirely superfluous. This said, it's still the largest field on the screen, and it's entirely optional. My preference would be to show a full calendar for the From and To date fields, and have a much smaller 'Comments' field.

Finally, the note about 'Partial days' is entirely superfluous as the system only allows you to book partial days on the first and last days of the request.

Sorry, did I say I read Krugg's Don't Make Me Think recently?

Friday, May 19, 2006

How to make your own test runner in NUnit

This isn't my cleanest piece of code, but it shows how you can write your own test runner in NUnit (V2.2.8). This is very dull if you don't do coding.

using System ;
using System.Reflection ;
using NUnit.Core.Builders ;
 
namespace NUnit.Core.Extensions
{
    [ AttributeUsage ( AttributeTargets.Method , AllowMultiple = false ) ]
    public class VagueExpectedExceptionTestAttribute : Attribute
    {
        protected Type _exceptionType ;
        public string _startsWith ;
        public string _endsWith ;
        public string _contains ;
 
        public Type ExceptionType
        {
            get { return _exceptionType ; }
            set
            {
                if ( !( value.IsSubclassOf ( typeof ( Exception ) ) ) )
                    throw new ArgumentException  
( "Type must be derived from Exception" ) ;
 
                this._exceptionType = value ;
            }
        }
 
        public string StartsWith
        {
            get { return _startsWith ; }
            set { _startsWith = value ; }
        }
 
        public string EndsWith
        {
            get { return _endsWith ; }
            set { _endsWith = value ; }
        }
 
        public string Contains
        {
            get { return _contains ; }
            set { _contains = value ; }
        }
    }
 
    [ TestCaseBuilder ]
    public class VagueExpectedExceptionTestBuilder : NUnitTestCaseBuilder
    {
        const string AttributeType =
"NUnit.Core.Extensions.VagueExpectedExceptionTestAttribute" ;
 
        public override bool CanBuildFrom ( MethodInfo method )
        {
            return Reflect.HasAttribute ( method , AttributeType , false ) ;
        }
 
        public TestCase Make ( MethodInfo method )
        {
            VagueExpectedExceptionTestAttribute testAttribute =
                ( VagueExpectedExceptionTestAttribute ) 
Reflect.GetAttribute ( method , AttributeType , false ) ;
            return
                new VagueExpectedExceptionTest (
method ,
testAttribute.ExceptionType ,
testAttribute.StartsWith ,
                                testAttribute.EndsWith ,
testAttribute.Contains
) ;
        }
 
        protected override TestCase MakeTestCase ( MethodInfo method )
        {
            return Make ( method ) ;
        }
    }
 
    public class VagueExpectedExceptionTest : TestMethod
    {
        private Type _exceptionType ;
        private string _startsWith ;
        private string _endsWith ;
        private string _contains ;
        private string _test = string.Empty ;
 
        public VagueExpectedExceptionTest (
MethodInfo method ,
Type exceptionType ,
string startsWith ,
string endsWith ,
                            string contains )
            : base ( method , exceptionType , null )
        {
            _exceptionType = exceptionType ;
            _startsWith = startsWith ;
            _endsWith = endsWith ;
            _contains = contains ;
        }
 
 
        protected override void ProcessException (
Exception exception ,
TestCaseResult testResult )
        {
            if ( exception.GetType ( ) == this._exceptionType )
                if ( TestMessage ( exception.Message ) )
                    testResult.Success ( ) ;
                else
                    testResult.Failure (
                        string.Format (
"Expected message to {0}, but actual message was {1}" ,
this.Test ,
                            exception.Message ) ,
null ) ;
            else
                testResult.Failure (
this._exceptionType + " was expected" ,
null ) ;
        }
 
        private string Test
        {
            get { return _test ; }
        }
 
 
        protected override void ProcessNoException ( TestCaseResult testResult )
        {
            testResult.Failure ( this._exceptionType + " was expected" , null ) ;
        }
 
        private bool TestMessage ( string message )
        {
            if ( !string.IsNullOrEmpty ( this._startsWith ) )
            {
                this._test = string.Format ( "start with '{0}'" , this._startsWith ) ;
                return message.StartsWith ( _startsWith ) ;
            }
            if ( !string.IsNullOrEmpty ( this._endsWith ) )
            {
                this._test = string.Format ( "end with '{0}'" , this._endsWith ) ;
                return message.EndsWith ( _endsWith ) ;
            }
            if ( !string.IsNullOrEmpty ( this._contains ) )
            {
                this._test = string.Format ( "contain '{0}'" , this._contains ) ;
                return message.Contains ( this._contains ) ;
            }
 
            return true ;
        }
    }
}


usage:

[VagueExpectedExceptionTest( ExceptionType=typeof(ArgumentNullException), StartsWith=DatasetResponseProcessor.LOG_DAL_NOT_SET)]
public void shouldThrowErrorWithoutDatasetDal ( )
{
    new DatasetResponseProcessor ( ).Process ( _response );
}

Google 'Quick Contacts'

Google 'Quick Contacts'
Google 'Quick Contacts',
originally uploaded by b3ardman.
In the 'Quick Contacts' area of Google Mail, you can set your own status for Google Chat. Entirely necessary, seeing as 'Away' and 'Busy' are the only two built-in options.
However, as this picture shows, it can be used to add a bit of personnality to an otherwise people-less screen.

Monday, May 15, 2006

null

null is always a perculiar concept.
In c/c++, NULL is #defined as 0, which seems fine, as a zero pointer is always invalid.
However, in object oriented languages, especially those with garbage collection, null no longer has this meaning.
null is a special value; at once both of no type and still of every type.
For example, in C#, you can't write
if  ( null is Object )
or
typeof(null)
and yet, any object can be null (we'll ignore value types).
I fully understand the need for null. It's a special flag that says there's nothing here. It's like a yes/no/unspecified thing.
It's at once an example of a broken abstraction (you can't have a value type that is null), yet at the same time overcomes a serious limitation of a binary system (having null allows a "tri-state" system, where null = unset/unspecified).
I'm loathed to say it, but I think I like the VB concept of Nothing better. Obviously, VB still has null, and it doesn't handle the difference between null, nothing and empty very well, but still, Nothing seems like a better name than null.

Wednesday, May 10, 2006

Ruth Kelly is Stalking me

...and she's getting closer.

First of all she moved into education, so I moved out of it. Then, when I'm working on the Office Of the Deputy Prime Minister (ODPM) website, she comes and takes over, in the process changing it to the Department for Community and Local Government (DCLG).

Politics aside, I'm worried about why she's stalking me. Has she not got anything better to do? She's not even got time to stay at a DCLG stakeholder meeting because she's too busy stalking me, or "joining the Prime Minister on a neighbourhood visit" as she calls it.

I'm going to seek legal advice if she tries to move in next door.