Monday, October 06, 2008

Submit a Form with Multiple Buttons in Monorail

Here's how to submit a form with multiple buttons via MonoRail. The javascript will control which action is called in the controller. This example uses prototype to setup the event handlers:

$Form.FormTag("%{id='myform'}")
$Form.TextField("email")
<button id="addbutton">Add</button>
<button id="removebutton">Remove</button>
$Form.EndFormTag()

<script>

Event.observe(window, 'load', function() {

Event.observe('addbutton', 'click', function() {
$('myform').action = '$Url.For("%{action='addemail'}")';
$('myform').submit();
return false;
});

Event.observe('removebutton', 'click', function() {
$('myform').action = '$Url.For("%{action='removeemail'}")';
$('myform').submit();
return false;
});

});
</script>


I used http://www.manoli.net/csharpformat/ to format the code.

Thursday, June 12, 2008

Generalizing the ELO Rating System for Multiple Players

The original ELO rating system was designed for two player games. I've had a need to generalize the ELO rating system for games where there are more than two players. I've come with with some modifications to the system to allow for multiple players.

The ELO system assigns a pool of players various ranks based on their abilities. These ranks can be used to estimate the likelihood for a player to win a given game.

For a given game, each player is assigned an estimated score which is roughly equivalent to the chance that the player has of winning the game. After the game, each player's actual score is compared to his estimated score and his rating will be updated.

There are a series of math equations that govern the system.

Let's start with a two player game, and then generalize from there.

For two players with rankings R1 and R2, the estimated scores E1 and E2 are computed:




Note that:



Once the game is finished, a scoring function determines each player's actual score Sx. A common scoring function for games such as chess where a player x may win, lose, or tie against another opponent is:



Note that:



Player x's new rating Rx is then calculated:



Now we would like to generalize this system for N number of players with ratings R1, R2, ..., RN-1, RN.

We can make the observation that a game with greater than two players is nearly approximated by a set of games where every player is participating in a two-player game with every other opponent.

The number of games this represents is expressed by:



The estimated score for a player x Ex can then be computed:


Note that:



Now we would like a scoring function for the result of a game with more than two players. In a game where each player is assigned a place p (e.g. first, second, third) we might choose the following function:



Note that:



Finally, every player's actual score is compared to his estimated score and the ratings updated using equation described earlier.

There are two terms D and K that are in the equations above but they have not been explained yet.

The D term is a number that roughly represents the weight given to a player's rating when determining their estimated score. The superiority of a player over another represented by his superior rating will mean less for higher values for D. That is to say that for higher values of D, the fact that one player has a much higher rating an another is less significant in estimating the outcome of a game. In games where luck more influences the outcome of a game than does skill, a higher value of K is more appropriate.

The K term is a factor that scales the magnitude of the change to a player's rating after a given game. A player's rating after a game will change more for higher values of K. Generally, the value of K should be higher when a player's rating is less certain. This may be because the player has not participated in many games. As players play more games and their rating becomes more representative of their skill level, the value of K should be reduced.

Tuesday, May 13, 2008

Registering MonoRail Extensions Programatically

Hammett inspired me to switch from XML configuration to programmatic configuration of MonoRail with this blog post. But he didn't discuss how to configure MonoRail extensions. I searched around through the source and came up with this solution:

        public void Configure(IMonoRailConfiguration configuration)

        {

            configuration.ViewEngineConfig.ViewPathRoot = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views");

            configuration.ViewEngineConfig.ViewEngines.Add(new ViewEngineInfo(typeof(NVelocityViewEngine), false));

 

            configuration.ConfigurationSection = new MutableConfiguration("monorail");

            configuration.ConfigurationSection.Children.Add(

                new MutableConfiguration("exception")

                    .CreateChild("exceptionHandler")

                    .Attribute("type", typeof(EmailHandler).AssemblyQualifiedName)

                    .Attribute("mailTo", "to@email.com")

                    .Attribute("mailFrom", "from@email.com"));

 

            configuration.ExtensionEntries.Add(

                new ExtensionEntry(typeof(ExceptionChainingExtension), new MutableConfiguration("")));

        }



This code sets up the EmailHandler that comes with MonoRail.

Monday, November 19, 2007

Comparing Production and Development Schemas

A common task I that I perform is updating a staging or production SQL server with the changes I've made to my local development database. The way I do it is fairly basic but it works quite well in practice.

I know this works with SQL Server 2005, but I think it should also work with SQL Server 2000. The idea should work on almost any database system that allows you to query for table and column metadata.

Here's the query I run on the databases:

SELECT table_name, column_name

FROM information_schema.columns

WHERE table_name IN

(

    SELECT table_name

    FROM information_schema.tables

    WHERE table_type = 'BASE TABLE'

)

ORDER BY table_name, column_name


Then, I just take both outputs of this query and stick them into WinMerge to get a schema comparison. I then proceed to update the staging or production database by hand, as is often necessary.

Take note that this query will only return columns that are in base tables, as you probably noticed by taking a look at the where clause. If you want to include the columns of views, just take out the where clause like so:

SELECT table_name, column_name

FROM information_schema.columns

ORDER BY table_name, column_name

Thursday, October 18, 2007

MonoRail Routing Upgrade Coming

I just did an update from the Castle repository, and look what I found:


Looks like we may be seeing improved routing capabilities in MonoRail soon. Isn't open source grand?

Wednesday, October 17, 2007

Castle MonoRail vs Microsoft MVC

Everyone seems to be chiming in on the newly announced MVC framework from Microsoft. A lot of the posts seem to be very positive.

The most talked about features seem to be:

  • Routing

  • Mockable IHttpRequest/IHttpResponse

  • Type-checked views


The routing feature seems pretty nice, but how far is MonoRail from having this feature? I think that MonoRail is missing this feature mainly because it wasn't developed in the era of IIS6.

IIS7 as I understand it gives the web application access to the web request earlier than IIS6, which gives it more control over the routing capabilities. Currently, IIS6 is not really well suited to be able to handle routing requests when there's no file extension on the URL. I imagine that this feature could be added fairly quickly once there's more motivation and more adoption of IIS7.

The mockability of IHttpRequest and IHttpResponse is a pretty nice feature as well, but couldn't MonoRail do this? Scott Guthrie said that they didn't change ASP.NET at all to get this feature.

Couldn't MonoRail wrap the standard HttpResonse and HttpRequest objects with adapters that implement a similar interface? The major hurdle with this seems to be that this wasn't done in the first place, and there's a lot of code out there that would have to change to use the new interfaces.

I have to admit that type-checked views sound enticing. It would be pretty cool to have refactoring operations automatically change things in the views.

But I've lived in a compiled view world and I really don't want to go back. If I have to recompile my project because I changed something in the view I would be pretty annoyed. It's already a huge annoyance to have to wait for the AppDomain to reload when I change something in a controller. I really don't want to wait for it to reload when I change a view as well.

I remember back in my Java/Struts days, I welcomed a switch in our project to Velocity over JSP files. There was a huge increase in productivity and I really didn't miss the type checking at all.

I love being able to submit a patch or jump on the Castle mailinglist to discuss a quick change that would help my own project and have the change implemented within hours or days. Wouldn't you lose that ability if you switched to Microsoft's MVC?

I guess that's a standard issue when deciding between open source and commercial frameworks. I'm really not ready to give that up, and I think that's one of the main reasons I'll be sticking with MonoRail as long as the project remains as active as it is.

Overall, I am pleased with the announcement. It seems that Microsoft is watching what is going on the community and trying to deliver a better platform for developing web applications.

My main point is that MonoRail is already a great platform that's in use by many, it's actively developed, and I'd be surprised if this new platform from Microsoft doesn't push it to greater heights. As always though, I'll be keeping an open mind as things unfold.

Monday, October 08, 2007

Unexceptional Dictionary Accesses in C#

Take a look at this:

            Dictionary<string, string> dictionary = new Dictionary<string, string>();

            dictionary["Hello"] = "World!";

            Console.WriteLine(dictionary["Hello"]);

            Console.WriteLine(dictionary["Goodbye"]);


What's the output of this code? You might think that you'd get the word "World!" followed by a blank line, but that's wrong. You get this big hairy exception:

System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.ThrowHelper.ThrowKeyNotFoundException()
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)

I don't really like that exception at all. I find that it's usually quite unexceptional for something to be missing from a dictionary. You might think it would be nice to get a null back instead of getting an exception. I might agree with you. OK, but maybe they had a reason for making the dictionary behave this way. Think about this situation:

            Dictionary<int, int> dictionary = new Dictionary<int, int>();

            dictionary[1] = 2;

            Console.WriteLine(dictionary[1]);

            Console.WriteLine(dictionary[2]);


Now, what do you think? Still want a null back? Integers aren't reference types, and you should never be getting null when something is supposed to return an integer. You might think that could just return default(T) but in this case the return value would be zero. But, zero is a perfectly valid number so it probably would have been a bad design decision to have the dictionary return default(T). So we're left with this exception.

You might attempt to fix this by guarding all your dictionary accesses with ContainsKey() checks like so:

            Dictionary<string, string> dictionary = new Dictionary<string, string>();

            dictionary["Hello"] = "World!";

            if (dictionary.ContainsKey("Hello"))

                Console.WriteLine(dictionary["Hello"]);

            if (dictionary.ContainsKey("Goodbye"))

                Console.WriteLine(dictionary["Goodbye"]);


There's a few of problems with this approach, however. First of all, it looks ugly, and it's really verbose. What if you're retrieving a large number of values from this dictionary? All those ifs get really tedious, and there's more potential for error when you're providing the key twice to the dictionary. Also, there's a potential race condition here. What if another thread removes the key from the dictionary the instant after you confirm that it is in fact in the dictionary, and then try to retrieve the value for the key? You're going to get an exception. And yet another problem is that this solution is inefficent. The dictionary has having to perform the work to lookup the key twice instead of just once.

So if you can't guard the dictionary access with an if, how can you safely determine if a key is in a dictionary and retrieve its value while avoiding a race condition? Well, they thought of that. That's why they created TryGetValue(), which basically works like this:

            Dictionary<string, string> dictionary = new Dictionary<string, string>();

            dictionary["Hello"] = "World!";

            string value;

            if (dictionary.TryGetValue("Hello", out value))

            {

                Console.WriteLine("Dictionary has the key!");

                Console.WriteLine("The value is " + value);

            }

            else

            {

                Console.WriteLine("Dictionary doesn't have the key!");

            }


So this solves that latter two problems of the three problems I mentioned above about the guard clauses, but it really exacerbates the first problem of verbosity. So how can we fix this? What if you really just want to get an null back if the key was missing from the dictionary? As mentioned before, you'd only want to do this if your value type was a reference type. How would you get about it? You could create a helper function like this:

        public string GetValueSafelyFromDictionary(Dictionary<string, string> dictionary, string key)

        {

            string value;

            if (dictionary.TryGetValue(key, out value))

                return value;

            return null;

        }


Or more generally:

        public TValue GetValueSafelyFromDictionary<TKey, TValue>(Dictionary<TKey, TValue> dictionary, TKey key) where TValue : class

        {

            TValue value;

            if (dictionary.TryGetValue(key, out value))

                return value;

            return null;

        }


So this could definitely helps cut down on the verbosity, especially if the value from dictionary is supposed to go into the property of another reference type instead of some variable on the stack. But it's quite annoying to have to keep passing the dictionary, so let's make this better:

    public class DictionaryValueGetter<TKey, TValue> where TValue : class

    {

        private readonly IDictionary<TKey, TValue> _dictonary;

 

        public DictionaryValueGetter(IDictionary<TKey, TValue> dictonary)

        {

            _dictonary = dictonary;

        }

 

        public TValue this[TKey key]

        {

            get

            {

                TValue value;

                if (!_dictonary.TryGetValue(key, out value))

                    return null;

                return value;

            }

        }

    }


OK, this is a lot better. Take a look:

            Dictionary<string, string> dictionary = new Dictionary<string, string>();

            dictionary["Hello"] = "World!";

            DictionaryValueGetter<string, string> valueGetter = new DictionaryValueGetter<string, string>(dictionary);

            Console.WriteLine(valueGetter["Hello"]);

            Console.WriteLine(valueGetter["Goodbye"]);


And this will work with any dictionary where your "value" type is a reference type, which is perfect because that's the only time this solution makes any sense. We could have gone further than this solution and provided a full implementation of IDictionary that provided all of this behavior, but I think that was a bit too much work for my simple use case.