Thursday, April 30, 2009

Extension Method to Imitate Times() in Ruby

RubyMy friend and co-worker James is gettin' pretty darned good with Ruby. My experience with Ruby is severely limited. So far, the only thing I've done with it was to implement a "business rules engine" to host a DSL in Iron Ruby.

Today, he showed me a pretty cool method that's built into Ruby called int.times() and I was pretty much instantly jealousified! I decided I had to have one . . . and now I do:
public static void Times(this int times, Action action)
{
for (int i = 0; i < times; i++) action();
}
I through together a few test cases to try it out. I had to make a few determinations though. If you call .Times on a negative number, it loops indefinitely (seemingly). I decided that you should never want to say "do something infinity times." If you do want to do that, you should just have your action call itself at the end of its execution. So, here's the test and the output:
[TestCase(4)]
[TestCase(-6)]
public void test_times_iterator(int times)
{
int i = 0;
times.Times(() =>
{
Console.WriteLine("Index: {0}", i);
i++;
});

Assert.AreEqual(Math.Max(times, 0), i);
}

// Index: 0
// Index: 1
// Index: 2
// Index: 3

Wednesday, April 29, 2009

IComparer Extension Methods for Fluent Interface

IComparerI've pretty much been a blogging fiend today! I love it when I find a topic like IComparer or Extension Methods that are entertaining enough to write about.

Today alone, I wrote articles about how IComparer works, using the proxy pattern to sort by multiple IComparers, and converting a Comparison delegate to an IComparer. Bragging aside though, I've found a fun way to combine my current favorite topics: IComparer and Extension Methods.

I wrote 3 extension methods to help me do some pretty neat things with IComparers and Comparisons. You'll see references to two of my prior articles in this post. The ComparerProxy sorts by multiple comparers and the ComparisonComparer converts a Comparison to an IComparer.

I'll show you the extension methods first, then I'll explain the reasoning behind them, and then I'll show you some usage.
public static class IComparerExtensions
{
public static IComparer<T> Then<T>(this IComparer<T> priority, IComparer<T> then)
{
return new ComparerProxy<T>(priority, then);
}

public static IComparer<T> Invert<T>(this IComparer<T> comparer)
{
return new ComparisonComparer<T>((x, y) => comparer.Compare(x, y) * -1);
}

public static IComparer<T> ToComparer<T>(this Comparison<T> comparison)
{
return new ComparisonComparer<T>(comparison);
}
}
So, lately I've been pretty big on fluent interfaces. I haven't written one yet, but I do use extension methods to make my implementations look a little more fluent. That's why, when I wrote the ComparerProxy, I thought, "Hey, wouldn't be cool if I could just take an IComparer and tack another comparer onto it? And then another? And another?" That's why I wrote the IComparer.Then() extension method.

Next, I realized that if you have a Comparison delegate, it'd be nice to be able to add that to a list of IComparers so I added the ToComparer method.

Finally, another thing that I often want to do is write an IComparer once but to be able to use it in reverse. Id est, I want to invert the logic. Obviously, I could List.Sort() and List.Reverse(), but that's much less efficient than having a CaseInsensitiveComparer and a ReverseCaseInsensitiveComparer.

The problem is, I don't really want to have to write both of those comparers. Instead, now I can call IComparer.Invert() and I get an IComparer that performs exactly like the original, but with inverted logic.

So, without further ado, here are some usage examples. I'm using the same test setup as I did with the ComparerProxy. I've also created several more IComparers to try out:
Comparison<Person> length = (x, y) => x.ToString().Length - y.ToString().Length;
IComparer<Person> lengthLast = new ComparerProxy<Person>(length.ToComparer(), last);

IComparer<Person> lastFirstComposed = last.Then(first);
I executed the following lines which produced the commented results:
_folks.Sort(length);
PrintList(_folks);

// Woody, Pete
// Woody, Lauren
// Caldwell, Cory
// Caldwell, Colin
// Brechtel, Jamus
// Woody, Royce Ann
// Brechtel, Ashley
// Caldwell, Jennifer


_folks.Sort(lengthLast);
PrintList(_folks);

// Woody, Pete
// Woody, Lauren
// Caldwell, Cory
// Brechtel, Jamus
// Caldwell, Colin
// Brechtel, Ashley
// Woody, Royce Ann
// Caldwell, Jennifer


_folks.Sort(lastFirstComposed);
PrintList(_folks);

// Brechtel, Ashley
// Brechtel, Jamus
// Caldwell, Colin
// Caldwell, Cory
// Caldwell, Jennifer
// Woody, Lauren
// Woody, Pete
// Woody, Royce Ann


_folks.Sort(last.Invert().Then(first));
PrintList(_folks);

// Woody, Lauren
// Woody, Pete
// Woody, Royce Ann
// Caldwell, Colin
// Caldwell, Cory
// Caldwell, Jennifer
// Brechtel, Ashley
// Brechtel, Jamus

Converting Comparison<T> to IComparer<T>

IComparerToday, I was working with IComparers (mostly for my Demystifying IComparers blog post). I realized that there's a lot of use for IComparers when working with C# and Linq. I decided that I should dedicate an entire IComparer section to C# Icomparers.

I was working on fodder for several articles when I came across a little annoyance. There's not a Comparer class that takes a Comparison delegate as a constructor argument. Thus, I can call List.Sort() and pass a Comparison delegate or a lambda expression but I cannot create an IComparer that executes that delegate or lambda.

Dissatisfied with this state of affairs, I throw together this little class:
public class ComparisonComparer<T> : IComparer<T>
{
private readonly Comparison<T> _comparison;

public ComparisonComparer(Comparison<T> comparison)
{
_comparison = comparison;
}

public int Compare(T x, T y)
{
return _comparison(x, y);
}
}

IComparer Proxy to Sort by Multiple Conditions

IComparerI thought of another cool use for implementing IComparer.

If you've ever wanted to sort a list of objects using more than one comparer (i.e., you want to sort a list of people by last name and then by first name), then you probably had to compose your own IComparer object to do so. If you wanted to be able to dynamically change sort orders, then your task was more difficult.

To address this problem, I wrote a class called ComparerProxy which implements IComparer and proxies comparisons through a list of IComparers. First, I'll show you the class and then I'll explain a few nuances.
public class ComparerProxy<T> : IComparer<T>
{
private readonly IComparer<T>[] _comparers;

public ComparerProxy(params IComparer<T>[] comparers)
{
_comparers = comparers;
}

public int Compare(T x, T y)
{
int retVal = 0, i = 0;

while (retVal == 0 && i < _comparers.Length)
retVal = _comparers[i++].Compare(x, y);

return retVal;
}
}
So, what's happening here is that when ComparerProxy.Compare() is called, it loops through the collection of comparers until it either runs out of comparers and deems the two objects equal or it identifies a difference and returns the value of that difference.

That sounds confusing even to me and I wrote the class so I'll break it down. Basically, imagine you have a Person object (and soon we will). The person has a FirstName property and a LastName property. If you want to sort by LastName and then by FirstName, it would go something like this:
  1. Sort the two objects by LastName
  2. If the two objects have the same LastName, then sort by FirstName
  3. If the two objects have the same FirstName, then the two objects are equal
If that doesn't make sense, please comment and I'll elaborate.

So, shall we see what it does? I created a Person class (very similar do the one described above) just to do some testing. I overrode the ToString method to print "Last, First" and I added two IComparers. Here's what that class looks like:
private class Person
{
public string First, Last;

public class FirstNameComparer : IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x.First.CompareTo(y.First);
}
}

public class LastNameComparer : IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x.Last.CompareTo(y.Last);
}
}

public override string ToString()
{
return string.Format("{0}, {1}", Last, First);
}
}
I created a test list of Persons and a set of IComparers to test with including two complex IComparers using the ComparerProxy:
List<Person> _folks = new List<Person>();
_folks.Add(new Person { First = "Jennifer", Last = "Caldwell" });
_folks.Add(new Person { First = "Cory", Last = "Caldwell" });
_folks.Add(new Person { First = "Lauren", Last = "Woody" });
_folks.Add(new Person { First = "Colin", Last = "Caldwell" });
_folks.Add(new Person { First = "Jamus", Last = "Brechtel" });
_folks.Add(new Person { First = "Pete", Last = "Woody" });
_folks.Add(new Person { First = "Royce Ann", Last = "Woody" });
_folks.Add(new Person { First = "Ashley", Last = "Brechtel" });

IComparer<Person> first = new Person.FirstNameComparer();
IComparer<Person> last = new Person.LastNameComparer();

IComparer<Person> firstLast = new ComparerProxy<Person>(first, last);
IComparer<Person> lastFirst = new ComparerProxy<Person>(last, first);
I executed the following lines and, lo and behold, achieved the expected results:
_folks.Sort(last);
PrintList(_folks);

// Brechtel, Jamus
// Brechtel, Ashley
// Caldwell, Jennifer
// Caldwell, Colin
// Caldwell, Cory
// Woody, Lauren
// Woody, Royce Ann
// Woody, Pete


_folks.Sort(first);
PrintList(_folks);

// Brechtel, Ashley
// Caldwell, Colin
// Caldwell, Cory
// Brechtel, Jamus
// Caldwell, Jennifer
// Woody, Lauren
// Woody, Pete
// Woody, Royce Ann


_folks.Sort(firstLast);
PrintList(_folks);

// this one is the same as just sorting by first name
// in retrospect, I should've added some folks with the same first name
// c'est la vie
//
// Brechtel, Ashley
// Caldwell, Colin
// Caldwell, Cory
// Brechtel, Jamus
// Caldwell, Jennifer
// Woody, Lauren
// Woody, Pete
// Woody, Royce Ann


_folks.Sort(lastFirst);
PrintList(_folks);

// Brechtel, Ashley
// Brechtel, Jamus
// Caldwell, Colin
// Caldwell, Cory
// Caldwell, Jennifer
// Woody, Lauren
// Woody, Pete
// Woody, Royce Ann

Demystifying IComparer in C#

IComparerI was looking through the analytics on my blog and I noticed a trend. I get a ton of searches for things related to the IComparer in C# article I wrote a few months back. I can only imagine that the reason people are searching for information on the IComparer so frequently is because the IComparer is a little mysterious to most people. It's pretty uncommon that you need to use one (let alone write it).

In truth, the IComparer Documentation isn't really all that helpful. Most examples of an IComparer that I found when I was working on my best fit select and my quickselect articles simply use x.CompareTo(y) or a built in IComparer.

Sure, that works, but I think people are hitting my blog trying to uncover the inner workings of the actual comparison.

Well, here it is. IComparer has one member method called Compare(object x, object y) (the generic version is strongly typed) which returns an integer. If the value of x is less than y, the result is less than 0. If the value of x is greater than y, the result is greater than zero. If the two values are equal, the result is 0.

Now, in most implementations I've seen, the results are nominal data (i.e., one trit valued -1, 0, or 1); however, I don't really see any reason you can't return ordinal, interval, or ratio data as well (although, returning ordinal or interval data would be relatively difficult as it requires knowledge of the rest of the collection). If that didn't make sense, take a look at levels of measurement. If you'd like me to elaborate on levels of measurement, leave a comment and I'll write an entire post about it.

Using my fictional class Person with the Age property, a common AgeComparer class would look something like this:
public class AgeComparer : IComparer<Person>
{
public virtual int Compare(Person x, Person y)
{
if (x.Age == y.Age) return 0;
return (x.Age > y.Age) ? 1 : -1;
}
}
While that's useful for sorting, it doesn't really give you any information about the magnitude of the difference between the two objects and may as well just be called WhichOneIsGreater(object x, object y). If you were using the comparer to graph items in a list, this would be relatively useless. Also, it's an entire line of code more than you need, so I'm proposing a solution like the following:
public class AgeComparer : IComparer<Person>
{
public virtual int Compare(Person x, Person y)
{
return x.Age - y.Age;
}
}
One caveat is that some people use IComparers expecting 1, 0, or -1 (i.e., if (IComparer.Compare(x, y) == 1) {...}). Certainly, using a non-nominal result would break their code, but IMO had they read the documentation on IComparer, they'd have seen nothing about 1, 0, and -1 as the return value.

I challenge you to think of other comparisons you could make between objects and post them in the comments of this blog post. In the meantime, I'm going to start an entire blog section on IComparer and we'll see what we can come up with.

Thursday, April 23, 2009

Required iPhone Knowledge for International Travel

iPhone Abroad

PDA Mode

You can disable the cellphone antenna on the iPhone by putting it in airplane mode. By default, airplane mode also disables the wifi antenna. You can re-enable the wifi antenna independently of the cellphone antenna by clicking Wi-Fi and flipping the switch to on. This will allow you to access the internet without incurring roaming charges.

Textual Intercourse

One thing you'll miss is text messaging. Do not fret Littlefoot; in the days between snail mail and text messages, people sent emails. iPhone works great with emails. Set up your gmail account on your iPhone and check it whenever you get internet access.

If you need more immediate response times, get a multi-protocol iPhone IM client. There are several great IM clients for the iPhone that you can get for free. My favorites are Fring and Palringo. I like the Palringo interface a lot for IMing, but I like Fring for IM and Skype support.

Phone Home

Calling home is a lot of fun when you're on an international adventure so you can make all of your friends and family jealous. I'm a big fan of the Skype unlimited U.S. land line calling plan for $2.95 so that's what I use. Also, Skype-to-Skype calls are free. There may be better VoIP services out there, but I haven't found one yet.

So, how do you Skype on the iPhone? Like I said before, Fring supports Skype and multiple IM clients and has a decent interface. As a note, when you use Fring to make a Skype call, you have to put +1 before the area code and phone number (i.e., +17705551212). Skype recently came out with its own iPhone application but it's spotty at best for me; you may have better luck.

Social Networking

Facebook has a great free iPhone application to keep you in touch with your friends and family back home. If you tweet, I really like TwitterFon. TwitterFon conveniently supports twitpic too.

Finances

When you're traveling internationally, it's nice to be able to check on your bank accounts back home; however, it'd be pretty tough to get to every page you're interested in within the 1 hour of internet access you get for 5 billion euro. If you use Mint.com (and you should), then you can get the free Mint.com iPhone application and check every balance at once and get a detailed transaction list.

Literature

Search the iTunes App Store for literature you may want. You can find travel guides, maps, and translators. Also, search the internet for images relevant to your trip. For example, find a large image of the subway system and break it into sections so you can view it on your iPhone.

Tuesday, April 7, 2009

Extension Method to Join Strings with a Delimiter

String ArrayI was talking with my coworker James Brechtel today about writing an extension method to join an array of strings together with a delimiter like string.Join() does. I'd prefer string[].Join() because it seems more fluent.

After I put the IList<T>.ToArray<T>() extension method together, implementing the fluent style join was a simple task.

Here's what that looks like:
public static string Join(this IList<string> list, string separator)
{
return string.Join(separator, list.ToArray());
}
That's it! :)