December 2008 - Posts

I've been reading Working Effectively with Legacy Code by Michael C. Feathers. It's a trove of useful information for turning your unreadable and unreliable code into the complete opposite.

  • Here's a useful technique for dealing with dependencies that have problematic methods for testing. Mark the offending method as virtual and inherit from the class. Now you can use this new derivative class in your test methods in place of the original. Here's an example in C#.

    public class MyClass
    {
        public MyClass()
        {
            Console.WriteLine("MyClass has been initialized");
        }

        public virtual void DifficultMethod()
        {
            Console.WriteLine(
                    "Difficult method makes testing difficult.");
        }
    }

    public class MyClassDerived : MyClass
    {
        public MyClassDerived() : base()
        {
        }

        public override void DifficultMethod()
        {
            Console.WriteLine("It's testable!");
        }

    }

    public class ClassToTest
    {
        public ClassToTest(MyClass myclass)
        {
            Console.WriteLine("Initializing ClassToTest");
            myclass.DifficultMethod();
        }
    }


    The ClassToTest has a constructor that takes a MyClass parameter. Unfortunately, MyClass has the DifficultMethod which is a very...well, difficult method. By marking DifficultMethod as virtual we can override it in a derived class which can then be used to pass into the ClassToTest constructor. Handy.

  • Here's the same idea in Python

    class MyClass(object):
        def __init__(self):
            print "MyClass Initialized"
        def difficult_method(self):
            print "this makes things hard"

    class MyClassDerivative(MyClass):
        def __init__(self):
            MyClass.__init__(self)
        def difficult_method(self):
            print "MUCH better"

    class ClassToTest(object):
        def __init__(self, myClass):
            print "ClassToTest has been initialized"
            myClass.difficult_method()

Posted by dhawley | with no comments

Do you have a function in your C# code somewhere that takes a parameter - the type doesn't matter - and then executes another function based on that parameter's value?

public void what_to_do(string param)
{
    if (param == "this")
        DoThis();
    else if (param == "that")
        DoThat();
    else
        DoSomethingElse();
}

Whenever I see "else if", my spider-sense starts tingling. Adding another "else if" is just too easy and the result can be cumbersome. I do use "else if" (and "switch" - it's just as vulnerable to this idea), but I don't always like it. The good news is that there is a fix - if you're willing to think "functionally". The bad news is it took me so long to piece it all together.

When did this epiphany come? At the latest MichiPUG meeting, while Mark Ramm was demonstrating a Python library for implementing generics, he displayed an interesting technique for avoiding the Python version of the above code. Here's my rendition of what he showed us:

whatToDoDictionary = {'this':do_this, 'that':do_that}

 

def what_to_do(param):
    if param in whatToDoDictionary:
        whatToDoDictionary[param]();
    else:
        do_something_else();

The key to this bit of Python is the values in the  whatToDoDictionary. Instead of your standard string or integers, the values are functions. When we call the what_to_do method, we look to see if the parameter is present as a key in the dictionary. If it is, we simple execute the value portion of the key/value pair. VoilĂ ! No more "else if"!

Can we do this in C#? Sure. Let's do it using lambdas.

Dictionary<string, Action> dict =

     new Dictionary<string, Action>();

public Lambda()
{
    dict.Add("this", () => do_this());
    dict.Add("that", () => do_that());
}

public void WhatToDo(string param)
{
    if (dict.ContainsKey(param))
        dict[param]();
    else
        do_something_else();
}

The concept is exactly the same. Build a dictionary of lambdas (functions in Python), see if the parameter passed to the WhatToDo(string) is in the dictionary and then execute the lambda if it is.

Posted by dhawley | with no comments
  • PyScripter has been IDE of choice for Python, but I've run into some problems with it. I would have continued to use it, but I noticed that the latest anyone did any work on it was October of 2006 - or at least that's what I thought. It turns out that early this year PyScripter is now maintained in Google Code and supports Python 2.6. You can download it here.
  • I've started using Notepad++ for editing my Python. Though it's only an editor, it uses syntax highlighting, supports macros and allows me to define hot keys to run external programs. This last point makes it possible for me to launch my code in Python with a simple keypress.
  • Want to know how to use Notepad++ to launch the file you're currently editing in Python? Type "[%Python directory%]\python.exe "$(FULL_CURRENT_PATH)" into the Notepad++ Run dialog and then save it to the keystroke combination of you choice.
  • If you took my previous bullet point to heart, you'll find that Python launches in a command window and then promptly closes after your tests run losing any output you may have had. The only way that I've been able to solve this is by pointing the stdout and stderr to a file. I would prefer to override the these when I launch Python, but instead I have to put some addtional code into my application. Bummer.
  • WinPDB is a debugging tool for Python. The only tool I'd used for debugging in the past is the one embedded into PyScripter. When I started using Notepad++ as my editor, I started trying to debug from the command line using the PDB module. No fun. That's when I came across WinPDB. It's worked well for the past few days that I've been using it, but it still isn't as nice as having your debugger integrated into your environment.
Posted by dhawley | with no comments