Thursday, March 15, 2007

Using Anonymous methods

In a previous post about guidelines for programming in C#2.0, I had written about how I did not understand one of the guidelines of using "ForEach via an Anonymous method predicate". Well now I know. And I illustrate with some examples below. These examples show the use of the ForEach as well as the use of Anonymous methods.
using System;
using System.Collections.Generic;
//A test class to insert into a List

public class TestClass
{
    string _string;
    int _number;
    public TestClass(int num, string s)
    { _string = s; _number = num;}
    public int Number { get{ return _number;}}
    public string String{ get {return _string;}}
}
public class MyClass
{
    public static void Main()
    {
        //Finding Even Integers in List;
        List<int> integers = new List<int>();
        for(int i=1; i<=10; i++) integers.Add(i);
        //find even numbers using anonymous methods
   List<int> even = integers.FindAll(delegate(int i)
            {
                return i%2==0;
            });
        WL("Even Numbers");
  //Here is an example of using ForEach - and the Anonymous methods
  //The one thing i still dont understand is why this is more
  //efficient than using foreach directly.
        even.ForEach(delegate(int i){Console.Write(i + " ");});

        //Computing Sum of Integers in List<T>
        int sum=0;
        integers.ForEach(delegate(int i){ sum+=i; });
        WL("");
        WL("Sum " + sum);
       
        //Sort TestClasss in List<T>
        List<TestClass> testClass = new List<TestClass>();
        testClass.Add(new TestClass(10,"Milk"));
        testClass.Add(new TestClass(5,"Cheese"));
        testClass.Sort(delegate(TestClass x, TestClass y){
                   return Comparer<int>Default.Compare(x.Number,y.Number);
            });
        WL("Sorted TestClass");
        testClass.ForEach(delegate(TestClass o){WL(o.Number + " " + o.String);});

        RL();
    }
    #region Helper methods
    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }
    private static void RL()
    {
        Console.ReadLine();   
    }
    #endregion
}

Basic C# coding guidelines

Basic C# coding guidelines (from http://blogs.msdn.com/samar/archive/2007/03/15/basic-c-coding-guidelines.aspx) All of the following are good recommendations. The one thing that I dont understand is the one about looping through generic collections using a "anonymous method predicate" - thats one I havent found any information about on the internet. So if you do, please leave a comment.
  • Please do NOT use + sign to concatenate strings, because it creates three instances of string (try doing that in a long or infinite loop, your program will die with OutOfMemory exception in no time), Rather use string.Concat it keeps one instance (and hey no OOM). If concatenating many strings in a loop etc, then use StringBuilder. Alternative to string.Concat is string.Format (which uses StringBuilder inside)
  • Use generic collections instead of Hashtables and ArrayList types
  • If using Generic types, then refrain from using foreach loop on the collection. Rather use ForEach method to loop through via an anonymous method predicate (much faster because doesn’t create the Iterator). For non generic types try to use for loop instead of foreach if the data being traversed is huge
  • Nullify unused objects (doesn’t collect, but marks for collection and ceases from getting promoted into next generation)
  • IF conditions having just one item in if and else, should be used as ternary operator (? Sign)
  • Use ‘as’ operator instead of direct typecast using parenthesis with the exception of overloaded explicit cast operator, it saves from NullReferenceException and InvalidCastException
  • Refrain from XmlDocument usage for navigational purpose, please either use XmlTextReader for sequential access or XPathDocument for XPath based data retrieval
  • For server side XSL transformation, Use XslCompiledTransform instead of XslTransform (Please check http://blogs.msdn.com/antosha/archive/2006/07/24/677560.aspx ). For client side transformation, try to load Xsl file asynchronously whenever possible via XMLDOM or XsltProcessor (Geckos)
  • Always join your threads in a web page, if used (otherwise the page will be rendered and workers will continue operating at the server cost, and ofcourse the results will be unpredictable)
  • Always do NULL checking before operating on an object, NullReferenceException is widely occurring exception in most applications and only a preventive programming can help us get the real error
  • Handle most specific (expected) exceptions in the catch blocks before deciding towards general Exception, and please don’t use catch without an exception object if you’re not really writing P/Invoke in C#

C# - Counting the number of primes

Recently I had to figure the number of primes below a given number n. One way to start at 2, go all the way till n, and check if any of the numbers are a multiple of any of the numbers upto n. This is not the most efficent solution though. The sieve of Eratosthenes is an elegant solution to this problem. http://mathworld.wolfram.com/SieveofEratosthenes.html Basically, it says that you need to check if every number from 2 to n, is a multiple of every number from 2 to the floor of the square of n. One can skip all those numbers that have already been set as not a prime, and the test of multiples can be started at 2*currentNumber being checked - as that will be the first multiple of the number currentNumber. (The code is self explanatory and Wolfarm has a sieve example). Though this code makes fewer checks and hence is faster (it is inefficent for larger values of n, as it needs to allocate an array of size n) In addition there is a function to output n primes - which uses the traditional check for primes. Which can also used to count the number of primes below n. Here is the solution in C#:
using System;
using System.Collections.Generic;

public class SieveofEratosthenes
{
    //based on Sieve of Eratosthenes http://mathworld.wolfram.com/SieveofEratosthenes.html
    static int CountPrimes(int countTill)
    {
        bool []primes = new bool[countTill+1];//we are counting upto this number
        int checkTill = (int)Math.Floor(Math.Sqrt((double)countTill));//according to Eratosthenes -
        //we need to check only till the floor of the square
        for (int index = 1; index <= countTill; index++)
            primes[index] = true;
       
        for (int i = 2; i <= checkTill; i++)
        {
            if (!primes[i])
                continue;//can continue - as its not a prime and hence would have crossed out numbers
           
            for (int j = i*2; j <= countTill; j++)
            {
                if ((j % i) == 0)
                {
                    //is a multiple of i - there fore not a prime!
                    primes[j] = false;
                }
               
            }
        }
       
        int count = 0;
        for (int i = 2; i <= countTill; i++)
        {
            if (primes[i])
                count++;
        }
        return count;
    }
   
    public static bool IsPrime(int currentNumberToCheck)
    {
        int currentDivisor = 2;
        int checkTill = currentNumberToCheck/2;
        while(currentDivisor <= checkTill)
        {
            if (currentNumberToCheck % currentDivisor == 0)
            {
                return false;
            }
            currentDivisor++;   
        }
        return true;
    }
    public static void PrintNPrimes(int n)
    {
        int count = 0;
        int currentNumberToCheck = 2;
        while (count < n)
        {
            if (IsPrime(currentNumberToCheck))
            {
                WL(currentNumberToCheck);
                count++;
            }
            currentNumberToCheck++;
        }
    }
   
    public static void Main()
    {
        WL(CountPrimes(100));
        PrintNPrimes(25);
        RL();
    }
   
    #region Helper methods

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }

    private static void RL()
    {
        Console.ReadLine();   
    }

    #endregion
}

Whats new in .NET 2.0 and C# 2.0

Here are two links to MSDN pages that talk about all the new features in .NET 2.0 and C# 2.0 Whats new in .NET 2.0 http://msdn2.microsoft.com/en-us/library/t357fb32.aspx Whats new in C# 2.0 http://msdn2.microsoft.com/en-us/library/7cz8t42e.aspx

Version Tolerant Serialization in .NET

I recently wanted to revist the issue of serialization in .NET and the new features added in version 2.0 of .NET. (For those of you who have worked with earlier versions, you know the problems caused by added properties, changes in version numbers and the extra code needed to fix these issues). Here is a MSDN article that discusses the new features. In brief these new features are:

  • Tolerance of extraneous or unexpected data. This enables newer versions of the type to send data to older versions.
  • Tolerance of missing optional data. This enables older versions to send data to newer versions.
  • Serialization callbacks. This enables intelligent default value setting in cases where data is missing.
  • In addition, there is a feature for declaring when a new optional field has been added. This is the VersionAdded property of the OptionalFieldAttribute attribute.

MSDN link: http://msdn2.microsoft.com/en-us/library/ms229752.aspx

And the article summarizes with these best practices: To ensure proper versioning behavior, follow these rules when modifying a type from version to version:
  • Never remove a serialized field.
  • Never apply the NonSerializedAttribute attribute to a field if the attribute was not applied to the field in the previous version.
  • Never change the name or the type of a serialized field.
  • When adding a new serialized field, apply the OptionalFieldAttribute attribute.
  • When removing a NonSerializedAttribute attribute from a field (that was not serializable in a previous version), apply the OptionalFieldAttribute attribute.
  • For all optional fields, set meaningful defaults using the serialization callbacks unless 0 or null as defaults are acceptable.

To ensure that a type will be compatible with future serialization engines, follow these guidelines:

  • Always set the VersionAdded property on the OptionalFieldAttribute attribute correctly.
  • Avoid branched versioning.

STANFORD Magazine: March/April 2007 > Features > Mind-set Research

STANFORD Magazine: March/April 2007 > Features > Mind-set Research: "According to a Stanford psychologist, you’ll reach new heights if you learn to embrace the occasional tumble." I came across this article through Guy Kawasaki's blog. The article is a review on psychology professor Carol Dweck's book Mindset: The New Psychology of Success.

Here is a funny one: what is HijklmnO?

I read this one on someone else's blog: What is HijklmnO? Answer: H2O (get it?)

Wednesday, March 14, 2007

Nine number puzzle

One of my collegues at work asked me a 9 number puzzle question that he heard on the radio show "Car Talk" The puzzle is given the numbers 1 to 9, how do you insert 2 minuses and 1 addition so that they add up to 100. So I wrote up a programming solution for this problem: (This is not the best way to do it - one could use memoization for speed up, as well as implement it as a recursive solution. I would also like to make it so that it can take an arbitary number of operators and see if a solution exists). For now here is the solution in C#. The answer to the problem is : 123 - 45 - 67 + 89 = 100 The valid combination was found in 125 tries.
using System;
using System.Collections;

public class Find9NumberSolution
{
    public const string numbers = "123456789";
    public enum Operator
    {
        Add,
        Sub
    }
   
    public static string OperatorToString(Operator op)
    {
        switch(op)
        {
            case Operator.Add:
                return " + ";
            case Operator.Sub:
                return " - ";
        }
        return "";
    }
   
    public static int Operate(Operator op, int v1, int v2)
    {
        int val = 0;
        switch(op)
        {
            case Operator.Add:
                val = v1 + v2;
                break;
            case Operator.Sub:
                val = v1 - v2;
                break;
        }
        return val;
    }
   
    public static bool Calc(Operator first,int l1,
                                Operator second,int l2,
                                    Operator third, int l3,
                                        int targetValue)
    {
        int num1 = int.Parse(numbers.Substring(0,l1+1));
        int num2 = int.Parse(numbers.Substring(l1+1, (l2-l1)));
        int num3 = int.Parse(numbers.Substring(l2+1, (l3-l2)));
        int num4 = int.Parse(numbers.Substring(l3+1));
       
        int val = Operate(first,num1, num2);
        val = Operate(second, val, num3);
        val = Operate(third, val, num4);
       
        if (val == targetValue)
        {
            WL(num1 + OperatorToString(first) + num2 + OperatorToString(second) + num3 + OperatorToString(third) + num4 + " = " + val);
            return true;
        }
        return false;
    }
   
    public static void Main()
    {
        Operator op1 = Operator.Add;
        Operator op2 = Operator.Sub;
        Operator op3 = Operator.Sub;
       
        bool targetValFnd = false;
        int targetVal = 100;
        int len = numbers.Length;
       
        int i,j,k;
        i=j=k=0;
        int count = 0;
        for (i = 0; i < len - 3; i++)
        {
            for (j = i+1; j < len - 2; j++)
            {
                for (k = j+1;k < len-1; k++)
                {
                    count++;
                    if (targetValFnd = Calc(op1,i,op2,j,op3,k,targetVal))
                        break;
                    count++;
                    if (targetValFnd = Calc(op2,i,op3,j,op1,k,targetVal))
                        break;
                    count++;
                    if (targetValFnd = Calc(op2,i,op1,j,op3,k,targetVal))
                        break;
                }
                if (targetValFnd)
                    break;
            }
            if (targetValFnd)
                break;
        }
        WL("Valid combination was found in " + count + " tries.");
        RL();
    }
   
    #region Helper methods

    private static void WL(object text, params object[] args)
    {
        Console.WriteLine(text.ToString(), args);   
    }
   
    private static void RL()
    {
        Console.ReadLine();   
    }
   
    #endregion
}

Geopegging -- MSDN Magazine, April 2007

Geopegging -- MSDN Magazine, April 2007 Joshua Trippin (editor for MSDN mag) writes about a GeoPegging tool that he wrote in .NET using Virtual Earth for obtaining the geo-tags.

CLR Inside Out: New Library Classes in "Orcas" -- MSDN Magazine, April 2007

CLR Inside Out: New Library Classes in "Orcas" -- MSDN Magazine, April 2007: "New Library Classes in 'Orcas'" Orcas is the next version of Visual Studio. Here are some of the new classes/functionality being added: Suite B Support : New cryptographic algorithm implementations to make VS compliant with some NSA specs. These include Elliptic Curve Cryptography, ECDSA and ECDH Big Integer Support : Very cool, allows users to represent numbers whoose size is no longer determined by the number of address bytes, but by the amount of memory. High-Performance Sets : Useful to the normal programmer - collections that have been implemented with performance in mind and additionally also implement set operators like union. Pipes : Another piece that I am interested in checking out. Useful for interprocess communication.

XmlLite: A Small And Fast XML Parser For Native C++ -- MSDN Magazine, April 2007

XmlLite: A Small And Fast XML Parser For Native C++ -- MSDN Magazine, April 2007: "provides a non-cached, forward-only parser (that delivers a pull programming model) and a non-cached, forward-only XML generator." XmlLite, is a high-performance, low-overhead XML reader and writer geared for applications written in native C++.

Saturday, March 10, 2007

DirectX10: The Next Generation in Gaming

Windows Vista Team Blog : DirectX10: The Next Generation in Gaming The screen shot the closes the deal for me is this pair: DirectX 9.0 DirectX 10.0 Here is another set taken from Gizmodo: DirectX 9.0 DirectX 10.0 Also Check out the video for the CryEngine that is based on DirectX10.o technology - very cool: http://www.techeblog.com/index.php/tech-gadget/gdc-07-crysis-footage

Monday, March 05, 2007

Quick reversing of string in C++

void swap( char *l, char *r ) { char t = *l; *l = *r; *r = t; } void reverse( char *inString, int inStringLen ) { char *front, *end; for( front = inString, end = inString+inStringLen-1; front < end; front++, end-- ) swap( front, end ); } //call as reverse(sampleString, strlen(sampleString));

Sunday, March 04, 2007

FAR 101

FAR 101: "Excerpts from U.S. Federal Aviation Regulations (FAR) Part 101 related to unmanned free balloons." This page lists the rules and regulations that cover the launching of unmanned free ballons.

Saturday, March 03, 2007

10 Rules for a Good User Interface on Managing Automation

10 Rules for a Good User Interface on Managing Automation 1. Visibility of system status The system should always keep users informed about what is going on. 2. Match between system and the real world The system should speak the user's language, with words, phrases, and concepts familiar to the user, rather than system-oriented terms. 3. User control and freedom Users often choose system functions by mistake and will need a clearly marked "emergency exit" to leave the unwanted state without having to go through an extended dialogue. 4. Consistency and standards Users should not have to wonder whether different words, situations, or actions mean the same thing. 5. Error prevention Even better than good error messages is a careful design which prevents a problem from occurring in the first place. (read more at the site : http://www.managingautomation.com/maonline/magazine/read/view/10_Rules_for_a_Good_User_Interface_15564802)