Essential Tools

Insipired by Scott Hanselman’s blog post on the subject, I’ve decided to compile a lit of the tools I’ve added to my new developer machine.  Most of these are producivity enhancements, but some are just for fun.

These are just the Windows apps.  I use a MacBook at home, but haven’t got around to compiling a list of utilities I use there.  Maybe some day…

Productivity tools

  • Paint.Net - .Net based image manipulation package.
  • 7-Zip – Archive management utility
  • NotePad 2 – Fully featured text editor, with (some) syntax highlighting.
  • Windows Grep – I do a lot of work with text files, and missed the Unix Grep command.  Here’s an alternative for Windows.
  • Tail for Windows - Another unix utility port for Windows.
  • CodeRush & Refactor! - Arguably, this should have been top of my list, but since they are paid-for software I’ll leave them languishing down here.  They get used every time I’m in Visual Studio, though.
  • Snippet Compiler - Great for very small proof-of-concept testing.
  • Lutz Roeder’s .Net Reflector – Not going to link to this since it is now full of advertising and other nastiness. The original is out there – check through Google.

Fun Stuff

I’m sure there are many more that I’ve missed, but I’ll add them when I remember about them. :)

Fuzzy-Matching of names

Yesterday at work, I had to try to knock together a quick application to parse a database table and pull out records with a matching name.  Simple at first glance, but more complex when you think about the common mis-spellings and abbreviations of names.  For example, Jonathan Miller may quite rightly be represented as Jon Miller, John Miller, Jo Miller and so on.  What I needed was a way to disambiguate these names for matchin purposes.

Conventional wisdom here would suggest the use of soundex patterns, and I agree that there are compelling arguments for this approach.  However, being the contrary soul that I am I decided soundex wasn’t quite good enough and went looking for alternatives.

I came across this blog post outlining a SourceForge project from the Web Intelligence Group at the University of Sheffield.  I took 20 minutes to implement the pre-requisites to use the patterns, and have to say it seems to give me what I want.

I’m using the Jaro Winkler metric to provide the fuzzy matching I’m looking for, and I am also able to give the users a choice of the confidence level of the match.  A confidence level of 1 will only return data that matches exactly. Confidence level 0 would return everything.  A bit of trial andd error showed me that a confidence level of around 0.85 produced the best result for my purposes.  

An example of the query I used would be something like this…

PROCEDURE [dbo].[GetResultsByFuzzyName]
	@FamilyName varchar(35),
	@GivenName varchar(35),
	@DateOfBirth datetime,
	@certaintyLevel int
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @cert float;
  SET @cert = CAST(@certaintyLevel as float) /10 
    
	select 
    <myFields>
    ,dbo.JaroWinkler(upper(familyname),upper(@FamilyName)) as FamilyNameScore
    ,dbo.JaroWinkler(upper(Givenname),upper(@GivenName)) as GivenNameScore
  from 
    <myTableName> 
  where
    dbo.JaroWinkler(upper(familyname),upper(@FamilyName)) >= @cert
  and
    dbo.JaroWinkler(upper(givenname),uppeR(@GivenName))  >= @cert
  order by 
    dbo.JaroWinkler(upper(familyname),upper(@FamilyName)) desc,
    dbo.JaroWinkler(upper(givenname),upper(@GivenName)) desc
	
END

I could go further with this and do a bit more analysis with a second (or even third) matching algorithm, but for now I’m getting pretty good results.

ASP.NET MVC – Helpers

This is the third in a series of posts about things I found out while learning ASP.NET MVC. Today : Helpers.

Helpers are, as their name suggests, helpful things. If, for example, you want to add the current assembly version information into a page, you are likely to run into a problem or two. ASP.NET MVC doesn’t create code-behind pages for you to do this kind of useful operation in. Instead, you have to fall back to the old Classic ASP technique of coding directly into the view page. That is far from ideal. For one thing, the following code snippet doesn’t produce the correct reult directly from a page.

<%= System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); %>

My experience of that was that it would, if you were very luck, print “0.0.0.0” rather than the current version.

So, how did I achieve it? I created a helper. Basically a helper is a static class, containing static methods (including extension methods)

Here’s an example of my SiteWideHelper.cs file

using stuff;

namespace Helpers
{
    public class SiteWideHelpers
    {
        public static string SiteVersion()
        {
            return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }

        public static string CurrentController(this HtmlHelper helper)
        {
            return (string)helper.ViewContext.RouteData.Values["controller"];
        }
    }
}

The helper class contains one “vanilla” method and one extension method to the HtmlHelper class. The first method, SiteVersion, simply treturns a string of the current assembly version. The second method, CurrentController, returns the name of the current controller by querying the extended HtmlHelper class.

Both of these methods may now be called, and their output rendered directly to the page. (Actually, I use the Currentcontroller method to determine which bits of sub-navigation are displayed on the master page.

<span>Web site version: <%= Html.Encode(SiteWideHelpers.SiteVersion()) %></span>

Don’t forget, instead of haveing to reference the fully qualified name of your method / class, you can import the namespace into your view

<%@ Import Namespace="Helpers" %>

I’m sure I’m missing some concepts here that would make development so much simpler, but for astarting point, this is working for me

ASP.NET MVC – Deploying on Win XP

This is the second in a series of posts about things I found out while learning ASP.NET MVC. Today : Setting up your development XP machine to run your site.

This is actually quite a simple one, but be warned, the overhead of setting up IIS5 to run an MVC site may lead to trouble if you put it under heavy load.

First, you’ll have to add a new Route to your Global.asax.cs file, just for IIS5.  For example :

 

routes.MapRoute(
      "IIS5",  // Route name
      "{controller}.mvc/{action}/{id}",  // URL with parameters</strong>
      new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
);

Note in this example that the only difference (apart from the name) is the addition of a “.mvc” extension after the controller declaration.

Now, you just need to configure your IIS virtual directory.

In inetmgr, navigate to your virtual directory, right click it and select Properties.  On the default tab (“Directory”), click the Configuration button.  You now need to add a new file extension handler, so click on the “Add” button.

In the textbox for the executable, enter the path to aspnet_isapi.dll ([probably C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll), and set the extension to be “.*”.  Before you hit “OK”, make sure you untick the box marked “Check that file exists”.  Now you can hit OK a few times and you’re good to go.

ASP.NET MVC – Preparing for the real world

This is the first in a series of posts about things I found out while learning ASP.NET MVC. Today : adding jQuery support that will work wherever the app is deployed in a directory structure.

In order to reference the jQuery javascript files, I had to figure out how to add a realtive link to the .js files that would work even if the app was deployed to an unknown virtual directory. A quick question on StackOverflow.com led me to the following steps.

1) Create an extension method in the Helpers namespace…

public static string GetBasePath(this HtmlHelper helper)

{

    var urlHelper = new UrlHelper(helper.ViewContext.RequestContext);

    return urlHelper.Content("~/");

}

Next, point the link tags for my js file to the new location…

<script src="<%= Html.GetBasePath() %>Scripts/jquery-1.3.2.js" type="text/javascript"></script>
 

That’s it.  All I had to do.

Of course, since I want to call data back from my MVC site via jQuery, I had to take a couple of extra steps to make the base path available to my scripts.  Back in my master page, I created the following snippet.

<script language="javascript">

  var rootUrl = "<%= Html.GetBasePath() %>"; 

</script>

Now I can call the data back from the site within my custom-defined jQuery script as follows…

$('#preview').click(function() {

    $.get(rootUrl + "jquery/getprovider/" + $(this).attr("name"), function(data) { $('#detailDiv').slideDown(300); $('#detailDiv').html(data); });

    });

My #preview object has an id coded into its ‘name’ attribute so the jQuery controller can reference the correct data., eg.

<a href="#" name="12345">details</a>

Moving to a new PC – Migration checklist

OK, so I have been given a new machine at work (more RAM, faster processor, more disk space) and I’m in the middle of migrating all my old data to the new box.

I’m the kind of person that will forget to move something across before blowing an old PC away, only to remember it about 30 minutes after losing it forever. For this reason, I’m putting together a list of the important things that one should copy over.

So far, I’ve copied the obvious* :

  • My Documents
  • IE, Chrome and FireFox bookmarks
  • Local MSDN image files
  • Drive-level data folders (e.g. c:\ImportantStuffForProcessXYZ)

But I was hoping someone else could suggest anything else I may have missed. Either leave a comment here, or send me a tweet and I’ll update the post for future reference.

* This is not an exhaustive list – nobody really want to hear about an obscure folder that contains my todo list, do they?

Found the first thing in Refactor! that I don’t like

So far, the latest versions of CodeRush and Refactor! have been pretty impressive.  Unfortunately, I’ve just found the first bit of behaviour that I’m not too keen on.  Take the following snippet…

foreach (MyProvider provider in lps)
{
  Console.WriteLine(provider.AccountStatus);
}

  
Fair enough. Old Skool way to write a loop, but nothing too extreme. Refactor! prompted me that I may like to “Introduce ForEach Action”. I decided to take its advice, and it turned the routine into

Array.ForEach(lps,
delegate(MyProvider provider)
{
  Console.WriteLine(provider.AccountStatus);
});

 
OK, still does the same thing, but I hate the way it looks. It’s kind of a half-way house between old-skool and lambda. This was even pointed out by Refactor! – it suggested that I “Compress to Lambda Expression”.

So I did. The result was much more pleasing.

Array.ForEach(lps, provider => Console.WriteLine(provider.AccountStatus));

Lovely.

All I’d like to see in Refactor! is the ability to go from the first snippet the the last without having to take a detour through Uglytown. Is that too much to ask?

System.Linq – Unleash the power!

I’ve been poking about with the System.Linq namespace in C# 3.5 this week.  Like most “new” areas of a language, it can be difficult to find the time or motivation to delve into the capabilities it provides, but I’ve just had it proven to me that I should have taken the plunge months ago.

In one small project, I have to compare two generic lists and pull out the records that are equal across the sets, as well as those that are different from one set to another (additions and deletions).  Luckily, the sets are fairly small, so the implementation I wrote last week is good enough to get the job done.  This week, however, I decided to do a quick benchmark to see how much faster it would be to use the new Linq-y methods.

First up, I created a small test class – MyType.

public class MyType
{
	public int MyId { get; set; }
	public string GivenName { get; set; }
	public string FamilyName { get; set; }
	public DateTime DateOfBirth { get; set; }

	public override bool Equals(object obj)
	{
		if (null == obj) return false;
		MyType compareTo = obj as MyType;
		if (null == compareTo) return false;
		return (FamilyName == compareTo.FamilyName && GivenName == compareTo.GivenName  && DateOfBirth == compareTo.DateOfBirth);
	}
}

Next up, I created a comparer class, inheriting from IEqualityComparer<MyType>

public class MyTypeComparer : IEqualityComparer
{
	public bool Equals(MyType x, MyType y)
	{
		return (x.FamilyName == y.FamilyName  && x.GivenName == y.GivenName  && x.DateOfBirth == y.DateOfBirth);
	}

	public int GetHashCode(MyType obj)
	{
		return obj.GivenName.GetHashCode() ^ obj.FamilyName.GetHashCode() ^ obj.DateOfBirth.GetHashCode();
	}
}

Next we create two collections of 10,000 members each.  I did that using the following snippet.

private void SetupDataForTest(int numberOfRecords)
{
	recordSetOne = new List();
	recordSetTwo = new List();
	matches = new List();
	matches2 = new List();

	for (int i = 0; i < numberOfRecords; i++)
	{
		recordSetOne.Add(new MyType {MyId = i, GivenName="Trevor", FamilyName="Test" + i.ToString(), DateOfBirth = new DateTime(1970,1,1).AddDays(i)});

		if(i % 3 == 0)
		{
			recordSetTwo.Add(new MyType { MyId = i, GivenName = "Trevor", FamilyName = "Test" + i.ToString(), DateOfBirth = new DateTime(1970, 1, 1).AddDays(i) } );
		}
		else
		{
			recordSetTwo.Add(new MyType { MyId = i, GivenName="Ian", FamilyName="Wilson" + (i*2).ToString(), DateOfBirth = new DateTime(1971,1,1).AddDays(i*2) } );
		}
	}
}

So now we can get to the meat of the thing and find all the records that exist in both sets.  The old way of doing this was looping through the first set, and for each member loop through the second until we find a match (I’m not going to provide code – it’s too darned ugly).  Doing it this way took around 8 seconds on my dev machine.

The Linqy way, though is to use the Enumerable.Intersect method :

private void RunLinqTest()
{
	var intersection = recordSetOne.Intersect(recordSetTwo, new MyTypeComparer());
	matches.AddRange(intersection);
}

Guess what?  Adding all the matches to a pre-existing collection returned the expected 3334 results, and took 7 milliseconds.Yes, milliseconds.  That means I could run this method 1142 times in the time it took to run the old way.

I’m not going to go into the specifics of how to pull out the added/deleted records (but I’ll give you a clue -> Enumerable.Except), but the performance gains were enormous there, too.

Windows Azure

I’ve just got back from Devweek at the Barbican in London, and the last session I attended was something of a revelation.  You know what it’s like at a conference – it’s the last day, you’re ready to pack up and go home, but you feel you have to attend at least one more session.  In my case, that session was by Microsoft’s Eric Nelson  on Windows Azure (Developing and Deploying your first Cloud Service).

Like pretty much all windows developers these days, I’d heard of Azure and cloud computing, but my initial opinion was “Meh! Not for me”.  Then I attended this session.  There’s obviously been a lot of thought put into this by the teams at Microsoft and, although there’s still a way to go, there are some very compelling features.  I’m not going to go into any detail here (visit the website above for more details) but the standout feature for me is the fact that if you already have the knowledge to develop a web application, you can develop an Azure service. (Yes, there are a couple of gotchas around storage and so on but nothing that can’t be overcome with a little thought and learning)

I didn’t think I would, but I’ve just signed up for the CTP – if nothing else, I can play with the technology a little.  If you want to get in on the ground floor for this tuff, I’d suggest you do too.

(By the way, big thanks to Eric for a couple of great presentations this week.)