MinimalVS.NET: How to make Visual Studio 2010 a little more TextMate-y

If, like me, you use TextMate at home and Visual Studio at work, then you might find this handy. I like the short cuts used in TextMate (and almost all applications on Linux/OsX) to close windows and navigate open tabs.

  • Grab the “Monaco” font here and install that mofo.
  • Then, grab my Ultimate TextMate settings file here (right click, save as). This Theme is a variant of Rob Conery’s Vibrant Theme. I added JS and CSS settings and tweaked the C# settings a bit.
  • Find and remove all bindings to “CTRL+W” and re-assign it to “File.Close”
  • Install the “Windows Productivity Tools” here
  • Next, find the “Window.NextDocumentWellTab” short cut (added by Productivity Tools) and unmap it from all commands. Add “ALT+SHIFT+]” for next tab
  • Then, find the “Window.PreviousDocumentWellTab” short cut (added by Productivity Tools) and unmap it from all commands. Add “ALT+SHIFT+[“ for previous tab
  • Find the “View.SolutionExplorer” shortcut and map it to “ALT+D”
  • Find the “Window.CloseToolWindow” and map it to “ALT+X”

Note: I have cheated a bit on the last two as we don’t have a Command key, but hopefully I made it a bit simpler.

The last thing to do, is to move SolutionExplorer to the left side and remove all toolbars and tool windows. Now you should have a very clean Visual Studio and can use Resharper’s GoTo commands to navigate your solution and only use “ALT+D” and “ALT+X” to show/hide the SolutionExplorer when needed.

A challenge for you: Try to go a whole day without using the mouse. In fact, put that bugger far out of reach behind your computer.


PS: I didn’t include the Keyboard shortcuts in the settings file, as I thought you might like to mix an match those to your preference.

Quick Autotest for NodeUnit and Node.Js on Mac OSX


Very simple way to get Autotesting in Node.js.

What is Autotesting? Simply put, it runs your unit tests automatically whenever you save a relevant file within your project.

  • First, install GROWL and GROWLNotify for Mac (http://growl.info/)
  • Next we want to install the ‘watchr’ gem…
    gem install watchr
    
  • Next create a file called autotest.watchr in the root of your Node.js project with the following ruby script…
    def run_all_tests
      print 'clear'
      puts "Tests run #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
      result_text = `nodeunit [TESTFOLDER]`
      result = result_text.include? 'failed'
      if result
    	`growlnotify -m 'Unit Tests Failed' Node Unit`
      else
    	`growlnotify -m 'All Unit Tests Passed' Node Unit`
      end
    end
    
    run_all_tests
    watch("(test|lib)(/.*)+.js") { |m| run_all_tests }
    
    @interrupted = false
    
    # Ctrl-C
    Signal.trap "INT" do
      if @interrupted
        abort("\n")
      else
        puts "Interrupt a second time to quit"
        @interrupted = true
        Kernel.sleep 1.5
    
        run_all_tests
        @interrupted = false
      end
    end
    

    Do not change the ` chars. This actually tells Ruby to output the text directly to the console (for those that didn’t know)

  • Replace [TESTFOLDER] in file above with your test folder
  • Run watchr..
    watchr autotest.watchr
    

Thats it! Now simply edit a .js file in your solution and the tests will run automatically and inform you of failures.

Feel free to add your favourite icons for failures and passes to GROWL. If you do, please send us an updated script ;)

Smart Search with Norvig Spelling Correction and Levenshtein Distance Algorithm in C#

Before I write anything, I would like to thank the sources for their code snippets from which I compiled my version. (Norvig Spelling Correction, Lorenzo Stokes, Website: http://www.codegrunt.co.uk/2010/11/02/C-Sharp-Norvig-Spelling-Corrector.html, Accessed: September 2011) and (Levenshtein Distance Algorithm, Lasse Johansson, Website: http://www.merriampark.com/ldcsharp.htm, Accessed: September 2011)

This search will first correct any spelling mistakes in your search query, then it will try to get a list of exact matches, partial matches and finally a distance query. The distance query will use the Levenshtein Distance Algorithm to find words that you may have meant.

Firstly, you need the big.txt file http://norvig.com/big.txt
The Dictionary that it creates from this file takes about 1.5s to load, so I would inject this at the start of your application via a container. In this case I am using Autofac

var bigDictionary = Regex.Matches(Resources.big.ToLower(), "[a-z]+")
    .Cast<Match>()
    .GroupBy(m => m.Value, m => m.Value)
    .ToDictionary(gr => gr.Key, gr => gr.Count());

builder.RegisterInstance(bigDictionary)
    .Named<IDictionary<string, int>>("BigTxt")
    .AsSelf()
    .SingleInstance();

builder.Register(c => new SearchService(c.ResolveNamed<IDictionary<string, int>>("BigTxt"))).As(typeof(ISearchService))
                .InstancePerHttpRequest();

Second we need the Search Service
UPDATE: I have refactored this into a Self Contained Service

using StrEnum = System.Collections.Generic.IEnumerable<string>;

public class SearchService
{
    private readonly IDictionary<string, int> bigDictionary;
    private const string ALPHABET = "abcdefghijklmnopqrstuvwxyz";

    public SearchService(IDictionary<string, int> bigDictionary)
    {
        this.bigDictionary = bigDictionary;
    }

    public StrEnum SearchThroughList(string searchTerm, StrEnum itemList)
    {
        var matches = new List<string>();
        string[] words = searchTerm.Split(' ');
        string term = string.Join(" ", words.Select(GetPossibleMisspelledWord));
        matches.AddRange(GetClosestMatch(term, itemList));

        if (matches.Count() == 0)
        {
            matches.AddRange(GetDistanceMatch(itemList, term));
        }
        return matches.Distinct();
    }

    private static StrEnum GetClosestMatch(string word, StrEnum titles)
    {
        var matches = new List<string>();

        string exactMatch = titles.SingleOrDefault(x => x.ToLowerInvariant() == word.ToLowerInvariant());
        if (exactMatch != null)
           matches.Add(exactMatch);

        StrEnum partialMatches =
                titles.Where(x => x.ToLowerInvariant().Contains(word.ToLowerInvariant()));

        matches.AddRange(partialMatches);

        return matches;
    }

    private static StrEnum GetDistanceMatch(StrEnum titles, string word)
    {
        var distanceDictionary = new Dictionary<string, int>();
        titles.ToList().ForEach(x => distanceDictionary.Add(x, Distance(x, word)));
        return distanceDictionary
           .Where(y => y.Value == distanceDictionary.Values.Min()).Select(x => x.Key).Take(2);
    }

    private string GetPossibleMisspelledWord(string word)
    {
        var nWords = bigDictionary;
        Func<StrEnum, StrEnum> nullIfEmpty = c => c.Any() ? c : null;

        StrEnum candidates = nullIfEmpty(new[] { word }.Where(nWords.ContainsKey))
            ?? nullIfEmpty(Edits(word).Where(nWords.ContainsKey))
            ?? nullIfEmpty((Edits(word).SelectMany(Edits, (e1, e2) => new { e1, e2 })
                .Where(match => nWords.ContainsKey(match.e2))
                .Select(match => match.e2))
                .Distinct());

        return candidates == null ? word : candidates
            .OrderByDescending(cand => (nWords.ContainsKey(cand) ? nWords[cand] : 1)).First();
    }

    private static int Distance(string s, string t)
    {
        var n = s.Length;
        int m = t.Length;
        var d = new int[n + 1, m + 1];
        if (n == 0) return m;
        if (m == 0) return n;
        for (int i = 0; i <= n; d[i, 0] = i++) {}
        for (int j = 0; j <= m; d[0, j] = j++) {}
        for (int i = 1; i <= n; i++)
        {
            for (int j = 1; j <= m; j++)
            {
                int cost = (t.Substring(j - 1, 1) == s.Substring(i - 1, 1) ? 0 : 1);
                d[i, j] = Math.Min(Math.Min(d[i - 1, j] + 1, d[i, j - 1] + 1),
                                  d[i - 1, j - 1] + cost);
            }
        }
        return d[n, m];
    }

    private static StrEnum Edits(string w)
    {
        // Deletion
        return (from i in Enumerable.Range(0, w.Length)
                select w.Substring(0, i) + w.Substring(i + 1))
        // Transposition
        .Union(from i in Enumerable.Range(0, w.Length - 1)
               select w.Substring(0, i) + w.Substring(i + 1, 1) +
                      w.Substring(i, 1) + w.Substring(i + 2))
        // Alteration
        .Union(from i in Enumerable.Range(0, w.Length)
               from c in ALPHABET
               select w.Substring(0, i) + c + w.Substring(i + 1))
        // Insertion
        .Union(from i in Enumerable.Range(0, w.Length + 1)
               from c in ALPHABET
               select w.Substring(0, i) + c + w.Substring(i));
    }
}

This would produce the following results:

search for afterlfe

will match:

Afterlife
The Afterlife
An Afterlife with Jane

a search for Tip Gaer

will match:

Top Gear
Top Gear Series 2
Top Gear Polar Special

a search for Tip Gaer Poler spfoul

will match:

Top Gear Polar Special

The Super Top 10 Quality Code Guidelines

A few months ago we asked a couple of developers to answer a simple question. “What constitutes ‘Good Code’?”. The answer had to be in the form of a checklist with 10 guidelines.

So here it is! The number after the item is the amount of times we encountered it (or similar).

1. High test coverage at all levels is essential 10
2. Follow the Solid Principles 10
3. Reading the code should substitute reading documentation – It should make sense 8
4. Always do the simplest thing possible, have small methods and classes – remember YAGNI 8
5. Organise and format your code in a logical way and stick to it 6
6. Use names that reflect the business domain and have real meaning 6
7. Implement GoF patterns where applicable but nowhere else 5
8. Code should be resillient to errors but error handling should not invade the design 3
9. Reuse code where possible 3
10. Don’t reimplement the wheel 3

A little about the participants…

Al Priest. Al describes himself as, “an architect working at BBC Worldwide. I’ve been developing ever since the BBC Micro was popular and since 2002 I’ve been developing in C#”. Catch him at http://www.socialanimal.com

Maarten Balliaaw is currently employed as .NET Technical Consultant at RealDolmen. He describes his interests as mainly web applications developed in ASP.NET (C#) or PHP and the Windows Azure cloud platform. Catch him at http://blog.maartenballiauw.be

Pete Camfield runs a weekly meeting at BBC Worldwide primarily aimed at engaging the development community in a number of ways such as organising dojo’s, presentations, study groups and the like. Catch him at http://leftshift.wordpress.com

Marcel du Preez who I am not going to introduce in the third person as it is me typing this. I currently work for BBC Worldwide and have worked on projects such as BBC Listener, Top Gear, RadioTimes and also created http://www.boxjs.com. Catch me… well… here or @marceldupreez

Julian Everett is software architect at BBC.com and has more than 13 years experience designing and building distributed enterprise applications on Microsoft and Java technology stacks. Catch him at http://julianeverett.wordpress.com

Andreas Håkansson (aka TheCodeJunkie), creator of Nancy, Open-source ninjah, software craftsman, believer of agile practices, blogger, twitter addict, swede… Catch him at http://thecodejunkie.com

Josh Chisholm has worked on high caliber projects around BBC and usually leads Dojo sessions on all kinds of technologies. Catch him at @joshski

Derek Ekins currently works on BBC.com and his passion is open source development in Ruby on Linux. He is also co-owner of this blog and you can catch his articles by browsing the archives.

Andrew Revell describes himself as a “Wanderer, developer, New Zealander, moderately ambitious dreamer, occasional accidental philosphiser”, he has worked on projects including Top Gear, Love Earth, BBC Listener and many more. Catch him at http://llevera.wordpress.com

Duane Strikwerda has years of experience in mainly high profile websites built, most recently using ASP.NET’s MVC framework.

We would love to hear your feedback and if there is anything you think we missed, please leave your additions in the comments below.

Creating ruby gui applications – an introduction to ruby shoes

As part of my effort to detect objects using opencv I have found myself performing a mind numbing task and as every lazy programmer knows this is the time to build a tool.

After a bit of investigation into the various gui libraries for ruby I have found one that seems pretty good called Ruby Shoes. There seem to be a few variants of this particular library. Strangely the classic Red Ruby Shoes version does not act like a regular ruby library. It seems to be a runtime that uses ruby. The Green Shoes variant however is a straightforward ruby library. You can gem install green_shoes and get up and running straight away.

A gui application in Ruby Shoes is called a shoe app and is started by calling:

Shoes.app do
  # application code goes here
  title "Hello World!"
end

As I want to create an image selection tool I need to be able to track mouse clicks, movements and releases and then draw a rectangle as this is going on.

After playing around for a while I came up with this:

require 'green_shoes'
Shoes.app  do
  title "Selection tool"
  image("your_image.jpg").click do |button, click_left, click_top|
    mouse_down = true
    release do
      mouse_down = false
    end

    nofill
    @selection = rect :left => mouse[1], :top => mouse[2], :width => 1, :height => 1

    motion do |move_left, move_top|
      if mouse_down
        width =  move_left - click_left
        height =  move_top - click_top

        width = 1 if width < 1
        height = 1 if height < 1

        @selection.style(:width => width, :height => height)
      end
    end
  end
end

There are probably more efficient ways to handle the release but this was the best I could come up with in half an hour.

I found the manual quite helpful to figure all this out.

User authorisation with Sinatra

Today I needed to add authorisation of specific routes to my sinatra application. After having a look around I couldn’t find anything I really liked. So I sat down and did the same thing any self respecting developer would – and wrote one myself.

I was actually surprised how easy it was and the result is simple-authorisation (gem install simple-authorisation).

To include this in your app simply:

require 'simple-authorisation'

And then in your sinatra config:

configure do
Simple::Authorisation.route '/', :deny => ['?'], :allow => ['*']
Simple::Authorisation.route '/login', :allow => ['?']
Simple::Authorisation.route '/logout', :allow => ['?']
Simple::Authorisation.route '/admin', :allow => ['*'], :deny => ['?']
end

Adding configuration for a route / will actually apply it to all its child routes. Adding additional routes will overwrite that setting. ‘?’ means anonymous users and ‘*’ means any logged in user.

The last thing you need to do is add a current_user method to your application:

class Application < Sinatra::Application
def current_user
session[:user]
end
end

Now simple-authorisation knows how to get the current user it can do its thing!

I know this is very basic but so far it is all I need. The next thing to add will be specific user groups.

If you like the look of this and have something to add then please fork this on github.

Detecting objects in a photograph with opencv part 2

Eyes being detected using opencv

As I found out last time it is quite easy to detect objects in a photgraph. The difficult part is to create a classifier that will do this for the particular object you are looking for.

I am still working on building a simple object classifier and I will share how I have done this soon. In the mean time you may like to whet your appettite with some of the classifiers that ship as part of opencv.

You can find classifiers that can detect faces, eyes and whole bodies in opencvs source control. For the purpose of demonstration I will use the eye detector. I am also using ruby-opencv from this repository.

In your ruby file (eyes.rb for example) include opencv:

require "opencv"

Load the classifier into opencv:

classifier = 'haarcascade_eye.xml'
detector = OpenCV::CvHaarClassifierCascade::load(classifier)

Load the image you want to run the classifier against:

image = OpenCV::IplImage.load('sample_image.jpg')

We can now detect objects by:

detector.detect_objects(image) do |region|
color = OpenCV::CvColor::Blue
image.rectangle! region.top_left, region.bottom_right, :color => color
end

This will draw blue rectangles over around the eyes. We can then save that image:

image.save_image('eyes_detected.jpg')

The result? Yours truly with square blue glasses!

Robotium 2.4 Released (automated android testing)

As someone who currently spends a lot of time doing testing I always appreciate the effort people put into building automated testing frameworks. There is nothing as boring as clicking on things and then checking the results…

Robotium is an automated test framework for Android. It allows you to write JUnit tests that start your application click on items on screen and from the menu and verify results. I have used it to test an application we are developing and it works quite well.

This release is mainly a maintenance release fixing bugs and so forth:

Hello Robotium Developers,

Robotium 2.4 is now released! Most of the work in this release has
gone into correcting defects and improving Robotium. The assert
methods have been re-designed in order to improve stability. I want to
thank everyone that have reported issues. They have all been corrected
and Robotium is now better then ever!

The only new functionality in this release is: waitForActivity(String
name) which includes a default timeout of 20 seconds (similar to the
other waitFor methods).

I hope you will enjoy this release!

http://code.google.com/p/robotium/downloads/list

Sincerely,
Renas

(exert from the Robotium mailing list)

The one big gap in Robotium is remote control support. Being able to drive Robotium remotely would work quite nicely from situations where you want to write your tests using another language (like ruby). I have had a go at bringing remote control support to robotium by taking a similar approach as the webdriver implementation for android. However there are many security concerns that prevent this being done in a generic way. If someone can find a way around these problems then Robotium would become an even more exciting proposition.

You can download Robotium from here

Detecting objects in a photograph with opencv

Two faces being detected using OpenCV

For a project I am working I need to detect simple rectangular objects in a photograph. After some investigation I have settled on using the Open Computer Vision (opencv) libraries to do this. I have played around with opencv a little in the past but still consider myself a newbie. Having said that it has not been too hard to get up and running.

My programming language of choice is ruby so I am making use of the ruby-opencv gem. Unfortunately this gem doesn’t seem to be very well supported and didn’t install using good old gem install opencv. What I found was that this repository seemed to be the most up to date fork of code. So I cloned it and went about getting it installed.

ruby-opencv is a native gem that wraps the opencv libraries so there is not much ruby going on in there and plenty of c++. After muddling my way through a few different messages about dependencies I did not have and some confusing error messages – which again where simply unmet dependencies I finally managed to get the gem built.

The repository has a sample that shows how to do face detection. It is one of those pieces of code that make you go what the heck! it can’t be that simple! And while you can do face detection in about 8 lines of code it is not really the code that is the magic part here.

The face detection algorithm is actually a set of Haar-like features. This is basically a description of what sort of object we are looking for – but go read the wikipedia article for a more comprehensive description. In order to detect a specific type of object we are going to have to write our own classifier that describes what we are looking for.

The next step is to write a classifier for our objects which we will do in the next post.

 

BoxJs – A simple package management service that compiles CoffeeScript

There are lots of script loaders out there in the wild; require.js, ControlJS, $scriptJs to name a few. So why do people still create them and why would we care if someone created another one? Well, there are a few problems with script loaders.

  • They load scripts asynchronously, which means your larger scripts will load slower then small scripts and there is no guarantee if a piece of code will be ready and loaded. If you are dealing with lots of files, ie 20 (like most large sites) this is simply a nightmare.
  • Script Order. As mentioned before, the asynchronous way the scripts are loaded cannot guarantee load order. There are plugins that helps with this, but only to some extent.
  • Lots of HTTP requests. When you inspect the network traffic on your page loads, you will see as many HTTP requests as you have js files. Like I mentioned before, for most large sites this will end up being close to 30 or 40 requests!
  • You have to jump through hoops to get minification and most have no Coffeescript support.

So what makes BoxJs different? And why would I even need script loaders in the first place?

To answer the latter question, with libraries such as Coffeescript and Class extensions, developers are now ending up with lots of .js files. Rather than working on one .js file with 100s of methods, we want to follow a more structured and Object-Oriented approach. The problem is lots of files = lots of HTTP request = making site painfully slow. No amount of minification is going to solve this issue. Your files could be 2 bytes, but it will still need a HTTP GET request to fetch. To make matters worse, if you host your .js files in the same web application (which is about 99% of the cases) then the synchronous nature of how web servers work (other than Node.js) means all the files will wait in a queue and get processed one by one. That means your site is waiting even if you are loading in the files with an asynchronous client library such as require.js.

BoxJs, a script loader with a difference!

  • BoxJS has a client and a server side to it. The client gathers all the information it needs and sends 1 request to the server. The server will fetch all the JS files from your site, package them and minify the whole lot. So even if you have 50 JS files, it will end up with 1 request and 1 minified file.
  • Scripts are combined in the order you give them. Period. The synchronous way we fetch the files means guaranteed load order.
  • Isn’t it slow to fetch the scripts asynchronously and minify them on the fly? If you would need to do this every time a request is made, then absolutely. It is considerably slower, but that’s where the caching comes in. BoxJS will only ever fetch these files once. All subsequent requests will return the final boxed version which is lightning fast. But what if I make lots of changes to my JS files and don’t want to use the cached version? Simply ad a version=1.0 or version=1.1 in the BoxJs call and it will produce a new version. It will also cache the older versions till the next refresh, would is usually a few days.
  • Minification out of the box! BoxJS supports CoffeeScript too. It will automatically compile any .coffee files into .js files before it passes it to the packager to be minified and cached too!

This sounds cool, but how can I rely on the CDN?
BoxJS uses Amazon and Heroku which are very reliable. It scales depending on the amount of traffic. For some, this may still not be enough. They suggest grabbing the output of the BoxJs HTTP request and save that locally as one file for your production server. This would get rid of any worries.

There is no way this will stay free!
If usage of BoxJS becomes more popular, it will be difficult to stay free. But its almost certain that there will be a free version for sites with lower traffic. For now we will have to wait and see!