The Monty Hall Problem, Enumerated

The Monty Hall problem is as follows:

You are a contestant in a game show. There are three doors. Behind one of the doors is a car; the other doors, each, a goat. The host asks you to choose a door. After you do so, the host will open one of the other two doors to reveal a goat, and allow you to stick to your choice, or to switch to the other unopened door. Which gives the higher probability to win the car?

It seems that there are a few ways to arrive at the answer, but none of them makes sense to me. In the end I got it by enumerating the only two winning possibilities:

  • Winning possibility #1 (WP1): I choose the car; the host shows me one of the two goats; I stick to my choice.
  • Winning possibility #2 (WP2): I choose a goat; the host shows me the remaining goat; I switch to the car.

For WP1, it is very clear that I have a 1/3 chance of winning the car by sticking to my first choice.

For WP2, I need to choose a goat, and then switch. The probability of choosing a goat is 2/3. Therefore, it is better for me to switch, because I have a higher chance of initially choosing a goat than the car. In other words, to ensure that switching is the winning move, I need to have initially chosen one of the goats; I have a 2/3 chance of initially choosing a goat; therefore I’m better off assuming that I had chosen a goat—which has a higher chance of being true—and then switch to what could only be the car.

Goat it?

15 July 2013 | Uncategorized | 1 Comment

Invoking a post-build batch file in TFS 2010

The scenario: you are using TFS 2010 as your build server, and you would like to deploy files to a remote server upon successful build by invoking a batch file.

Do note that the following steps work great in conjunction with Visual Studio T4 Templates, whereby multiple .config files (e.g. Web.Dev.config, Web.Test.config) can be generated from a master template to reflect different connection strings, etc. Oleg Sych has a nice write-up on this. Hint: hand-edit your .csproj file and use the DependentUpon element to keep your project view clean in Visual Studio—multiple .tt files can be nested under the main .tt file.

  1. Make a copy of DefaultTemplate.xaml and check it in. Let’s call it BatchFilePostBuild.xaml.
  2. Open BatchFilePostBuild.xaml in the designer and add 2 new Arguments:
    • BatchFile (Direction = In, Argument type = String, Default value = [blank])
    • BatchFileArguments (Direction = In, Argument type = String, Default value = [blank])
  3. Expand “Run On Agent”. Drag “InvokeProcess” from the Toolbox and place it after “Try Compile, Test, and Associate …”
  4. In the Properties pane for InvokeProcess:
    Property Value
    Arguments BatchFileArguments
    EnvironmentVariables New Dictionary(Of String, String) From {{"SourcesDirectory", SourcesDirectory}, {"BinariesDirectory", BinariesDirectory}}
    FileName BatchFile.Replace("$(SourceDir)", SourcesDirectory)
  5. Double-click InvokeProcess:
    • Drag “WriteBuildMessage” from the Toolbox and place it under stdOutput. Set Importance = High, Message = stdOutput.
    • Drag “WriteBuildWarning” from the Toolbox and place it under stdError. Set Message = stdError.
  6. Save and check in BatchFilePostBuild.xaml.
  7. In Team Explorer, create a new build definition, with its process template being BatchFilePostBuild.xaml.
  8. In the Process tab, there will be 2 properties under Misc:
    Property Value
    BatchFile Here you can specify the path and file name to your batch file relative to $(SourceDir). Refer to the folder structures in the Workspace tab.
    BatchFileArguments A list of arguments separated by spaces. In your batch file, they will be %1, %2, %3, and so on.
  9. Create and check in your batch file. In this batch file you will be able to refer to %SourcesDirectory% and %BinariesDirectory%, in addition to %1, %2, %3, etc. above. Assuming %1 is the environment type (e.g. “Test”) and %2 is the server name, here are some useful commands:
    Clean target folder del /s /q "\\%2\path\to\remote\folder\*"
    Copy directory structure xcopy "%BinariesDirectory%\path\to\folder\*" "\\%2\path\to\remote\folder" /s /y
    Copy Web.Test.config to the Test server copy /y "%BinariesDirectory%\_PublishedWebsites\MyProject\Web.%1.config" "\\%2\path\to\remote\folder\Web.config"
    Start remote Windows service sc \\%2 start "My Windows Service"
    Stop remote Windows service sc \\%2 stop "My Windows Service"
    Dirty wait for around 30 seconds ping 127.0.0.1 -n 30 > NUL

4 June 2012 | .NET | 6 Comments

Exception-handling wrappers for Task.ContinueWith()

The .NET 4 Task Parallel Library is great because you can specify continuations for new threads:

private Task<WebResponse> GetWebResponseAsync(string url)
{
    var webRequest = WebRequest.Create(url);
    return Task.Factory.FromAsync<WebResponse>(
        webRequest.BeginGetResponse,
        webRequest.EndGetResponse,
        null);
}

public void Run(string url)
{
    Task.Factory.StartNew(StartBusyIndicator)
        .ContinueWith(task => GetWebResponseAsync(url)).Unwrap()
        .ContinueWith(task => Console.WriteLine(task.Result.Headers))
        .ContinueWith(task => StopBusyIndicator());
}

Otherwise we’d have to handle the result of the async call either in callbacks or in event handlers—messy.

There are two caveats, though, when using Task.ContinueWith(). The first is that we have to sometimes use .Unwrap(). The second is that we have to handle exceptions in the next .ContinueWith(). Otherwise, our exceptions will just get swallowed.

So now:

public void Run(string url)
{
    Task.Factory.StartNew(StartBusyIndicator)
        .ContinueWith(task => GetWebResponseAsync(url)).Unwrap()
        .ContinueWith(task =>
        {
            if (task.IsFaulted) // handle errors
            else Console.WriteLine(task.Result.Headers);
        })
        .ContinueWith(task => StopBusyIndicator());
}

There goes our pretty code. Also, imagine the duplication if we do this for every .ContinueWith().

And so, inspired by Stephen Toub’s Processing Sequences of Asynchronous Operations with Tasks, I’ve written drop-in replacements for .ContinueWith() and .Unwrap() that will bubble up exceptions to a .Finally() extension method. Now our code can be clean again:

public void Run(string url)
{
    Task.Factory.StartNew(StartBusyIndicator)
        .Then(task => GetWebResponseAsync(url))
        .Then(task => Console.WriteLine(task.Result.Headers))
        .Finally(ExceptionHandler, StopBusyIndicator);
}

Do help yourself to the full source and example usage at github:gist.

28 May 2012 | .NET, C# | 2 Comments

Calling an Oracle function using NHibernate

  1. Tested with NHibernate 2.1.2 and Oracle 11g.
  2. Needs Oracle.DataAccess (not System.Data.OracleClient). Tested with Oracle.DataAccess 2.111.6.0 AMD64.
  3. If your Oracle function returns a scalar value of datatype number, the .NET object will be a Decimal.

NHibernate config:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.driver_class">
      NHibernate.Driver.OracleDataClientDriver
    </property>
  </session-factory>
</hibernate-configuration>

C# code:

var result = nhibernateSession
    .CreateSQLQuery("select GetSomeValue(:p_parameter1) from dual")
    .SetParameter("p_parameter1", parameter1)
    .UniqueResult();

// GetSomeValue returns a scalar of datatype number; result will be object of type Decimal

var someValue = Convert.ToInt32(result);

17 January 2012 | Uncategorized | No Comments

Calling an Oracle stored procedure using NHibernate

  1. The stored procedure must have an out sys_refcursor parameter as the first argument.
  2. Tested with NHibernate 2.1.2 and Oracle 11g.
  3. Needs Oracle.DataAccess (not System.Data.OracleClient). Tested with Oracle.DataAccess 2.111.6.0 AMD64.

NHibernate config:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.driver_class">
      NHibernate.Driver.OracleDataClientDriver
    </property>
  </session-factory>
</hibernate-configuration>

NHibernate mapping:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SampleProject" namespace="SampleProject">
  <sql-query name="GetEmployeesByDepartmentId">
    <return class="Employee" />
    { call GetEmployeesByDepartmentId(:p_departmentid) }
  </sql-query>
</hibernate-mapping>

C# code:

var employees = nhibernateSession
    .GetNamedQuery("GetEmployeesByDepartmentId")
    .SetParameter("p_departmentid", departmentId)
    .List<Employee>();

To execute a stored procedure that has no out parameters:

nhibernateSession
    .CreateSQLQuery("call DoSomething(:p_parameter1)")
    .SetParameter("p_parameter1", parameter1)
    .ExecuteUpdate();

17 January 2012 | .NET, C# | 1 Comment