Monday, April 30, 2007
Getting Started with NHibernate
Saturday, April 28, 2007
Rendering Binary Data with MonoRail
protected void SetupDownload(string filename, string contentType)
{
CancelLayout();
CancelView();
Response.Clear();
Response.ContentType = contentType;
Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
}
By calling this method inside one of your controllers, you will change the default behavior of the controller to not perform the layout (CancelLayout()) and to not try to render a view via the view engine (CancelView()). The contentType should be something like "application/zip". It's the MIME type that is reported to the browser. This method also tells the browser that the data is not inline, and that the user should be prompted to download the file with a default filename provided by the filename argument.
So you have changed the default behavior of MonoRail to render something other than a plain vanilla view. All that's left is to write the binary data into the response's output stream. If you already have a stream, then you would do something like this:
private void CopyStream(Stream from, Stream to)
{
byte[] buffer = new byte[_bufferSize];
int bytes = 0;
while ((bytes = from.Read(buffer, 0, buffer.Length)) > 0)
to.Write(buffer, 0, bytes);
}
CopyStream(System.IO.File.OpenRead(path), Response.OutputStream);
Or, if you have a byte array (buffer in this example) or something similar, you can do something like this.
Response.OutputStream.Write(buffer, 0, buffer.Length);
Notice that if you want to have the brower render something inline (e.g. an image), than you can just remove line that adds the Content-Disposition header that is in my example SetupDownload function.
Friday, April 27, 2007
Remove All Tables and Constraints from a Database Using T-SQL
WARNING: The following script will delete all the tables in your database.
On to the script:
DECLARE @TableName NVARCHAR(MAX)
DECLARE @ConstraintName NVARCHAR(MAX)
DECLARE Constraints CURSOR FOR
SELECT TABLE_NAME, CONSTRAINT_NAME FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
OPEN Constraints
FETCH NEXT FROM Constraints INTO @TableName, @ConstraintName
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC('ALTER TABLE [' + @TableName + '] DROP CONSTRAINT [' + @ConstraintName + ']')
FETCH NEXT FROM Constraints INTO @TableName, @ConstraintName
END
CLOSE Constraints
DEALLOCATE Constraints
DECLARE Tables CURSOR FOR
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
OPEN Tables
FETCH NEXT FROM Tables INTO @TableName
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC('DROP TABLE [' + @TableName + ']')
FETCH NEXT FROM Tables INTO @TableName
END
CLOSE Tables
DEALLOCATE Tables
Enjoy. Let me know if this doesn't work for you.
Thursday, May 12, 2005
Adapting the Elo Rating System for Poker
I decided I'd modify the Elo rating system used in chess for poker. It has to be modified because it was originally designed for games where there are only two players. Ratings for players are calculated based on who won the game and what the respective ratings of the players were before the game completed. The problem is that poker tournaments have many players, not just two, so it had to be modifed.
The Elo rating system tries to predict the probability that a given player will beat another player based on their ratings. It then uses the new data, i.e. the result of the game, to adjust its predictions for the next game. If a player wins, he gets a score of 1. If he loses, he gets a score of 0. And if both players draw, they both get a score of 0.5.
In poker tournaments, you want capture not only who won the game, but who did well in the tournament. Obviously, second place, third place, etc. deserve some recognition. You can't just recognize first place as the only "winner." So, instead of a score of 1 for the winner, and 0 for all the losers, a player attains a score equal to that player's place scaled by the size of the tournament he played in. The equation looks something like:
S = Score
P = Place of a specific player
N = Number of players
S = (P-1)/(N-1)
Using this formula, first place gets a 1, last place gets a 0, and all the players in between get something between 0 and 1.
The Elo system also uses an expression to predict the score of a given player based on his opponent. The original system only takes into account one other player. The new system has to include the ratings of all of the other players in the tournament. Traditionally, the Elo system uses an expression to predict the score that looks something like:
We have more than one opposing player, so I average the ratings of all opposing players. This is the second modification I made. By the way, the 400 is used to fit the ratings along a normal distribution curve desired for chess ratings.
Ea = Estimated score for Player A
Eb = Estimated score for Player B
Ra = Rating of Player A
Rb = Rating of Player B
Ea = 1 / (1 + 10^((Rb-Ra)/400))
Eb = 1 / (1 + 10^((Ra-Rb)/400))
I've tested this model with good results. I plan on implementing it for a large group of poker players and hope that others might test it and try it out on their own.
Update: I've revised my ideas on the modification to the system here.