Learning from Data

A new trend has started with the online Artificial Intelligence class taught by Sebastian Thrun and Peter Norvig in partnership with Stanford. Following the success trail blazed by Thrun and Norvig, quite a few courses have followed suit:

Good times, huh ?

Caltech has followed suit with Learning From Data, a course on machine learning taught by the well known Yaser Abu-Mostafa. The course started on April 3rd and will have classes twice a week. You can watch it live or view the recorded video later.

What I miss about C#

It has been a month or so since I started programming in C++. To be frank it is not the monster that I thought it would be and it wasn’t that hard to move to C++ from C#. Granted I haven’t faced any of the notorious and nasty bugs that is difficult to debug in native code but I still think C++ isn’t as hard as I thought it would be (touch wood).

That being said I do miss a few things that I was used to in C# and .NET. Here are the top 3:

  1. Refactoring tools
  2. Garbage collection
  3. A good mocking framework for unit testing

Welcome 2011

I have had quite a few resolutions for 2010. Now I hold my head high and tell you all – I didn’t do even one of them :)

While that speaks volumes about my nature, I wouldn’t want you to think I am quitter. I have more resolutions for this year.

  • I will reduce my weight by 15 lbs. I weigh 185 lbs now, so by Dec 2011 I expect to be 170 lbs. I haven’t been 170 lbs since some time in 2002. Now I expect to be back at that weight by 2012.
  • I will reduce my cholesterol to normal values. Now I am grossly over the normal values (total cholesterol = 300)
  • I will greatly increase my knowledge on algorithms and data-structures. This is a vague one. But that’s OK. Any progress in this direction is good for me.
  • I will study discrete mathematics. This is also quite vague but my intention is to be a little less clueless than I am now.

That is it friends. Just 4 things. Let us see how that goes.

Using TFS (TeamBuild) to build Setup projects in Visual Studio

If you took the shortcut of a Visual Studio Setup project (as opposed to using Wix) then you must have faced the same problem that I did, viz., not being able to create the MSI as part of your TFS nightly builds which hands over the bits to the test team. The problem here is that the vdproj files of the setup projects is in a format that MSBuild (and TeamBuild) does not understand. But we know that Visual Studio can build this project. So I tried to see if I can use devenv.exe to build the project. I tried devenv.exe /? on the command prompt and found that it indeed takes a build switch. So I tried this devenv.exe MySetup.vdproj /build

That did not succeed. The following error message was spit out:

Microsoft (R) Visual Studio Version 9.0.30729.1.
Copyright (C) Microsoft Corp. All rights reserved.
—— Starting pre-build validation for project ‘MySetup’ ——
ERROR: Cannot find outputs of project output group ‘(unable to determine name)’.  Either the group, its configuration, or its project may have been removed from the solution.
ERROR: Cannot find outputs of project output group ‘(unable to determine name)’.  Either the group, its configuration, or its project may have been removed from the solution.
—— Pre-build validation for project ‘MySetup’ completed ——
—— Build started: Project: MySetup, Configuration: Debug ——
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

I then decided to run it against the solution file devenv.exe MySolution.sln /Build

That did the trick. The setup files were created in MySolution/MySetup/Debug/ folder.

So I needed to integrate this into the build script. Using devenv.exe means this build machine needs to have Visual Studio installed on it. We already had it, so I was in luck. In some teams they might not allowed the build machine to have Visual Studio. 

I added the path to devenv.exe to the system path. Screen shot below should show you how to do that.

image

As a first attempt I added the following code to the AfterDropBuild target.

<Target Name="AfterDropBuild">   
    <Exec Command="devenv.exe $(SolutionRoot)/MySolution.sln /Build"/>
    <ItemGroup>
      <SetupFiles Include="$(SolutionRoot)/MySetup/Release/MySetup.msi" />
      <SetupFiles Include="$(SolutionRoot)/MySetup/Release/Setup.exe" />
    </ItemGroup>
    <Copy SourceFiles="@(SetupFiles)" DestinationFolder="C:\Temp\MSI" />
  </Target>

This attempt failed. The error message was not helpful. So I logged into the build machine and tried the same command from command prompt and nothing happened ! So changed the current directory to the location of the sln file and then ran the command again and it worked. So it seems that devenv needs only the name of the sln file (not the full path to it) and the current working directory needs to be the directory when the sln file resides.

So my second attempt:

<Target Name="AfterDropBuild">   
    <Exec Command="devenv.exe MySolution.sln /Build" WorkingDirectory="$(SolutionRoot)"/>
    <ItemGroup>
      <SetupFiles Include="$(SolutionRoot)/MySetup/Release/MySetup.msi" />
      <SetupFiles Include="$(SolutionRoot)/MySetup/Release/Setup.exe" />
    </ItemGroup>
    <Copy SourceFiles="@(SetupFiles)" DestinationFolder="C:\Temp\MSI" />
  </Target>

That worked ! Well not fully, but the Exec task worked but the Copy task failed. I found the reason for that was the files were getting created in the Debug folder and not the Release folder. In order to force a Release build I had to pass additional info to devenv. So I changed the script as shown below and I could see the bits were getting copied correctly.

<Target Name="AfterDropBuild">
    <Exec Command="devenv.exe MySolution.sln /Build &quot;Release|Any CPU&quot;" WorkingDirectory="$(SolutionRoot)"/>
    <ItemGroup>
      <SetupFiles Include="$(SolutionRoot)/MySetup/Release/MySetup.msi" />
      <SetupFiles Include="$(SolutionRoot)/MySetup/Release/Setup.exe" />
    </ItemGroup>
    <Copy SourceFiles="@(SetupFiles)" DestinationFolder="C:\Temp\MSI" />
  </Target>

Here is my final version for copying it to a remote drop location.

<Target Name="AfterDropBuild">   
    <Exec Command="devenv.exe MySolution.sln /Build &quot;Release|Any CPU&quot;" WorkingDirectory="$(SolutionRoot)"/>
    <ItemGroup>
      <SetupFiles Include="$(SolutionRoot)/MySetup/Release/MySetup.msi" />
      <SetupFiles Include="$(SolutionRoot)/MySetup/Release/Setup.exe" />
    </ItemGroup>
    <Copy SourceFiles="@(SetupFiles)" DestinationFolder="\\Build-Machine\Build_Drop_Folders\MyProjectMSI\$(BuildNumber)" />
    <Copy SourceFiles="@(SetupFiles)" DestinationFolder="\\Build-Machine\Build_Drop_Folders\MyProjectMSI\Latest_MSI" />
  </Target>

Note: Here $(SolutionRoot) is the path you have given while creating the build definition. You can see it by editing the build definition.

image

Plans for 2010

I don’t usually make new year resolutions. It is not because I am perfect and doesn’t need to make any changes, but it is because of my lazy nature. I have made up my mind several times in the past about achieving this and achieving that, but usually I don’t ever bring myself to completing my projects.

So why this year ?

I don’t know, but I think it would be a good thing to try. Like a new cuisine or a new hair style,  sometimes a change is nice to have – they add spice to life. So I am going to give new year resolutions a try this year.

So what is different this time ?

This time I am publicly disclosing the things I want to achieve, the projects I want to complete. I remember having read somewhere that it would be good idea to make our aspirations public. This would help motivate us to complete our projects.

As of now, I have 3 things in mind for 2010.

  • I have decided to write a series of blog posts on the common software design patterns made popular by the GoF. Why design patterns? Frankly, I don’t have a very clear reason. I know it is not the hottest topic to blog about, but it is definitely a useful one. Especially for me. I have been reading about design patterns, and occasionally putting to practice, since some time in 2003 when Binil gave me The Design Patterns book. Since then, I have read a few more books on the topic. But I don’t claim to be master on the topic. Actually far from it, my understanding of many of the “advanced” patterns are still vague. Haven’t we all heard the age old adage – “the best way to learn something is to teach it.”. So I am going to write about them, which will help me understand them better and if someone is able to glean something from my posts, it will be a pleasant bonus. This would also be a good exercise in writing and keep the blog rolling.  
  • Read some books. Not the kind of glancing over that I do nowadays. A thorough reading. Understanding the concepts and making it part of myself. This is pretty ambitious. As of now I have two candidates in my mind for this project. The first book is Structure and Interpretation of Computer Programs (I have had this book for 3 years now) and the second one is Domain Driven Design (been in my shelf for a little over 2 years). These are not easy books to read. But they are important books to have read for any computer programmer. As I mentioned before this is quite an ambitious target. 
  • Visit some places. I have been in the US of A for about 3.5 years now. But I haven’t seen many of the good places here. Even in Washington state, there are so many good places to see. Now that I am married I have a travel companion too :-)

I don’t know how much of this I can accomplish (as with all other things in the future). But I think it is worth a try.

Wish me luck.

LocalMessageSender with strongly typed objects

If you need to have two Silverlight apps talking to each other, you would be using the LocalMessageSender and LocalMessageReceiver classes from the System.Windows.Messaging namespace. The LocalMessageSender class will only allow you to send string messages. So if you are looking to send strongly typed objects using the LocalMessageSender you will have to serialize the object and then deserialize it at the other end. I created a class which will do this work for you. I decided to use JSON as the serialization format because it is much more lightweight than Xml.

using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;

namespace Common
{
    public class JsonSerializer<T>
    {
        public static string Serialize(T objectToSerialize)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
                serializer.WriteObject(stream, objectToSerialize);
                stream.Position = 0;

                using (StreamReader reader = new StreamReader(stream))
                {
                    return reader.ReadToEnd();
                }
            }
        }

        public static T Deserialize(string jsonString)
        {
            using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
            {
                DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
                return (T)serializer.ReadObject(stream);
            }
        }
    }
}

You can use this class like this

string serializedMsg = JsonSerializer<SimpleMessage>.Serialize(msg); 
SimpleMessage msg = JsonSerializer<SimpleMessage>.Deserialize(serializedMsg);

To give credit where it is due, I stole most of this code from here – http://www.silverlightshow.net/items/JSON-serialization-and-deserialization-in-Silverlight.aspx

LocalMessageSender with retry capability

If you need to have two Silverlight apps talking to each other, you would be using the LocalMessageSender and LocalMessageReceiver classes from the System.Windows.Messaging namespace. The problem with the LocalMessageSender is that it might not be able to send message at the very first try. So you will have to write code which retries to send the message for an x number of times. Rather than duplicating this code all over the place, I decided to create a class which will do this for you.

using System;
using System.Windows.Messaging;

namespace Common
{
    public class RetryMessageSender
    {
        private readonly int maxRetryCount;
        private LocalMessageSender messageSender;
        private int retryCount = 1;

        public event EventHandler<SendCompletedEventArgs> SendCompleted;

        public RetryMessageSender(LocalMessageSender messageSender)
            : this(messageSender, 100 /*default value of max retries*/)
        {
        }

        public RetryMessageSender(LocalMessageSender messageSender, int maxRetries)
        {
            this.messageSender = messageSender;
            this.maxRetryCount = maxRetries;
            messageSender.SendCompleted += new System.EventHandler<SendCompletedEventArgs>(messageSender_SendCompleted);
        }

        public void SendMessage(string msg)
        {
            messageSender.SendAsync(msg);
        }

        void messageSender_SendCompleted(object sender, SendCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                if (retryCount <= maxRetryCount)
                {
                    retryCount++;
                    SendMessage(e.Message);
                }
                else
                {
                    SendCompleted(sender, e);
                }
            }
            else
            {
                retryCount = 0;
                SendCompleted(sender, e);
            }
        }
    }
}

Now you can use this class like this:

RetryMessageSender msgSender = new RetryMessageSender(messageSender, 10);
msgSender.SendCompleted += new System.EventHandler<SendCompletedEventArgs>(msgSender_SendCompleted);
msgSender.SendMessage("hello");
In the SendCompleted event handler, you can check whether the message was sent successfully within the specified number of retries (10 in this case).
static void msgSender_SendCompleted(object sender, SendCompletedEventArgs e)
{
    if (e.Error != null)
    {
         throw new System.Exception("Unable to send message even after 10 retries");
    }
}

Coders at Work

Coders at Work is a new book from Apress which follows the same format as Founders at Work which I reviewed here earlier. It is collection of interviews by Peter Seibel (yes, the same guy who wrote the excellent Practical Common Lisp) with some of the icons of software programming like Peter Norvig, Ken Thompson, Donald Knuth, Joshua Bloch, Douglas Crockford etc (the initial list consisted of 284 people and was narrowed down to 15).  Not surprisingly there is a lot of excitement around the book and is getting good reviews on Amazon. I hope to read it soon. I almost pre-ordered it from Amazon but since my Amazon Prime had expired I would have had to pay for shipping (since it is under the $25 limit) so I didnt complete the order. Unfortunately the discount has now decreased from 43% to 34%. Now I wonder whether I should buy it or get it from the library. Not that I mind shelling out $20 for a good book but my apartment is now full of books that I am trying to reduce the number of books that I buy. There is also a companion website for the book at codersatwork.com.

Jolt Awards 2007 Finalists

The books:

General Books
  Beautiful Code Edited by Andy Oram and Greg Wilson O’Reilly
Geekonomics: The Real Cost of Insecure Software by David Rice Addison-Wesley Professional
Manage It!: Your Guide to Modern Pragmatic Project Management by Johanna Rothman Pragmatic Bookshelf
Myths of Innovation by Scott Berkun O’Reilly
Outside In Software Development by Carl Kessler and John Sweitzer IBM Press
Release It!: Design and Deploy Production-Ready Software by Michael T. Nygard Pragmatic Bookshelf
Technical Books
  Continuous Integration: Improving Software Quality and Reducing Risk By Paul Duvall, Steve Matyas, Andrew Glover Addison-Wesley Professional
Fuzzing: Brute Force Vulnerability Discovery By Michael Sutton, Adam Greene, Pedram Amini Addison-Wesley Professional
Head First SQL Your Brain on SQL—A Learner’s Guide by Lynn Beighley O’Reilly
The Rails Way by Obie Fernandez Addison-Wesley Professional
WPF Unleashed by Adam Nathan Sams Publishing
xUnit Test Patterns: Refactoring Test Code by Gerard Meszaros Addison-Wesley Professional

The complete list is here.

Monster Attack

Well, it is not actually a monster-attack, but an attack on Monster.com by hackers who stole 1.6 Millions records of user data. Several phishing attacks trying to gain more user information, like bank account number and password, were reported. The emails were very realistic because they contained the user’s actual personal information.

Read more of it from BBC website.

Monster’s security notice and advice can be found here.