You Don’t Know Java Script- Up and Going Part 1

Comparison Operators

if I ask you what is result of the following ?

var a = [‘a’ ,’b’, ‘c’];
var b = [‘a’ ,’b’,’c’];
a == b

most probably you would say true right ? But that’s not the case here, the answer is false
let us examine why

when you are using == or === operators for comparing non primitive types, i.e functions or objects including arrays, they will simply check whether the references match, not anything about underlying values.

for example in case of arrays , while comparing , all array values are by default coerced in to strings by joining all values with commas( , ) in between.  consider below example now

var a = [1 ,2 ,3];
var b = [1 ,2 , 3];
var c = “1,2,3”;
a == c;  // will return true

Inequality and Coercion

var a = 41;
var b = “42”;
var c = “43”;
a < b;   // true;
a < c;   // true;

In case of above inequality comparison,

  • when comparing two string values , the comparison is made lexicographic-ally i.e the case with a < b
  • where  as, if any one of the both is not a string then both values are coerced with numbers.

So what will be the result of comparing a Number and a String if both are coerced in to numbers?

var a = 42;
var b = “foo”;
a > b;  //false
a < b;  // false
a == b;  //false

So now what do you think coercion of  “foo” will be ?
its “Invalid Number Value” NAN

And the specification says NAN is neither greater nor less than any other value hence the result is false for the above.

 

 

 

 

 

 

 

Advertisements

Sorting c#1 to c#4

Consider if we have list of Products and we want them to be ordered by Product Name, Below is how it might be implemented in c#1

In C# 1

class ProductNameComparer : IComparer
 {
   public int Compare(object x, object y)
   {
     ProductsSortingInCSharp1 first = (ProductsSortingInCSharp1)x;
     ProductsSortingInCSharp1 second = (ProductsSortingInCSharp1)y;

     return first.Name.CompareTo(second.Name);
   }
 }

     ArrayList products = ProductsSortingInCSharp1.GetSampleProducts();
     products.Sort(new ProductNameComparer());
     foreach(ProductsSortingInCSharp1 product in products)
     {
       Console.WriteLine(product.name);
     }

So as you can see to just sort the products we had to create a whole new class altogether, which has to implement IComparer, mention not this is only for one sort order, if we have to sort products both by name and price, then the job become tedious.

Also, we can see following issues with ProductNameComparer Class,

  • There are explicit casts in the code, casts are a way to tell the compiler that you know more information than it does and that means there is a chance that you might be wrong.ex: if ArrayList returning from GetSampleProducts were to return a string then there is a chance of run time error.

C#2 generics will address this issue,

List products = ProductsSortingInCSharp2.GetSampleProducts();
products.Sort(new ProductNameComparer());

class ProductNameComparer : IComparer<ProductsSortingInCSharp2>
 {
   public int Compare(ProductsSortingInCSharp2 first, ProductsSortingInCSharp2 second)
   {
     return first.Name.CompareTo(second.Name);
   }
 }

Still for comparing we have to create a class implementing an IComparable interface,  in C#2 this can be achieved using the delegate.

products.Sort(delegate (ProductsSortingInCSharp2 first, ProductsSortingInCSharp2 second)
{
  return first.Name.CompareTo(second.Name);
});

As you can see using delegates and anonymous methods in C#2 we had eliminated the creation of explicit class for comparison.

Only Problem I see with the above code is, readability is missing and C#3 lambda expression’s would come to our rescue here,

Sorting using Comparison from a lambda expression (C# 3)

List<ProductsSortingInCSharp2> products = ProductsSortingInCSharp2.GetSampleProducts();
 products.Sort((x, y) => x.Name.CompareTo(y.Name));
 foreach (ProductsSortingInCSharp2 product in products)
 {
   Console.WriteLine(product.Name);
 }

Ordering List using an extension method in C#3

    List<Product> products = Product.GetSamplesProducts();
     foreach (Product product in products.OrderBy(p =>p.Name))
     {
       Console.WriteLine(product);
     }

Please note that here we are NOT actually modifying the list in place, i.e if you print Products again you would see that the list has not been changed.

If we note the changes from C#1 to C#3 here it goes

  • C#1, Weakly typed comparator. No delegate sorting option
  • C#2, Strongly typed comparator. Delegate Comparisons and Anonymous methods
  • C#3, Lambda Expressions, Extension Methods and Option of leaving list Unsorted

The Product C Type(c#1)

Below is how typically how a product class might have written in c#1.

class ProductInCSharp1
    {
        string name;
        public string Name { get { return name; } }

        decimal price;
        public decimal Price { get { return price; } }

        public ProductInCSharp1(string name, decimal price)
        {
            this.name = name;
            this.price = price;
        }

        public static ArrayList GetSampleProducts()
        {
            ArrayList list = new ArrayList();
            list.Add(new ProductInCSharp1("fsdfadad", 9.0m));
            list.Add(new ProductInCSharp1("fsdfadad", 9.0m));
            list.Add(new ProductInCSharp1("fsdfadad", 9.0m));
            list.Add(new ProductInCSharp1("fsdfadad", 9.0m));
            return list;
        }

        public override string ToString()
        {
            return string.Format("{0} : {1}", name, price);
        }
    }

Looking through the code, there are three limitations that could be demonstrated.

  • An ArrayList has no compile time information about what is it contains, my mistake we can even add string instead of new ProductClass, since there is no compile time validation.
  • Here we only have public getters, if we were to have setters to Name and Price, they too would have to be public
  • There is soooo much code for simple public getter/setter properties

Strongly Typed Collections in c# 2

C#2 addresses first and second problems mentioned above, most important change is generics

class ProductInCSharp2
 {
   string name;
   public string Name
   {
     get { return name; }
     set { name = value; }
   }

   decimal price;
   public decimal Price
   {
     get { return price; }
     set { price = value; }
   }

   public ProductInCSharp2(string name, decimal price)
   {
     Name = name;
     Price = price;
   }

   public static List<ProductInCSharp2> GetSampleProducts()
   {
     List list = new List<ProductInCSharp2>();
     list.Add(new ProductInCSharp2("West Side Story", 9.99m));
     list.Add(new ProductInCSharp2("Assassins", 14.99m));
     list.Add(new ProductInCSharp2("Frogs", 13.99m));
     list.Add(new ProductInCSharp2("Sweeney Todd", 10.99m));
     return list;
   }

   public override  string ToString()
   {
     return string.Format("{0}: {1}", name, price);
   }
 }

Following are the changes to be noted

  • We have now private setters, which can be set through constructor
  • List would now only accept of type ProductInCSharp2. i.e, now we have compile time validation

Automatically Implemented Properties In C# 3

class ProductInCSharp3
 {
   public string Name { get; private set; }
   public decimal Price { get; private set; }
 
   public ProductInCSharp3(string name, decimal price)
   {
     Name = name;
     Price = price;
   }
 
   public ProductInCSharp3()
   {
       
   }
 
   public static List<ProductInCSharp3> GetSampleProducts()
   {
     return new List
     {
           new ProductInCSharp3 { Name="West Side Story", Price = 9.99m },
           new ProductInCSharp3 { Name="Assassins", Price=14.99m },
           new ProductInCSharp3 { Name="Frogs", Price=13.99m },
           new ProductInCSharp3 { Name="Sweeney Todd", Price=10.99m}
     };
   }
 
   public override string ToString()
   {
     return string.Format("{0}: {1}", Name, Price);
   }
 }

Following are the changes to be noted here

  • Now Properties dont have any code associated with them
  • we are building hardcoded list in a different way.With no name and price variables to access, we are forced to use the properties everywhere in the class, improving consistency.

Named Arguments in c# 4

class ProductInCSharp4
  {
    readonly string name;
    public string Name { get { return name; } }
 
    readonly decimal price;
    public decimal Price { get { return price; } }
 
    public ProductInCSharp4(string name, decimal price)
    {
      this.name = name;
      this.price = price;
    }
 
    public static List<ProductInCSharp4> GetSampleProducts()
    {
 
      return new List<ProductInCSharp4>
      {
          new ProductInCSharp4(name:"Naruto", price:33.33m),
          new ProductInCSharp4name: "Assassins", price: 14.99m),
          new ProductInCSharp4name: "Frogs", price: 13.99m),
          new ProductInCSharp4name: "Sweeney Todd", price: 10.99m)
      };
 
    }
 
  }

though the benefits of specifying named Arguments is minimal here, but if a method or constructor has too many parameters , it can make meaning of the code much clearer.(for example if you were having a nullable parameter type and you are passing null, with out named parameters it would be difficult to know for which parameter you are passing null.)

Summarizing evolution of c#1 to c#4

  • c#1 – Readonly properties, and weakly typed collections
  • c#2 – Private property setters and Strongly typed collections
  • c#3 – Automatically implemented properties, Enhanced object collection and initialization
  • c#4 – Named Arguments for clearer constructor and method calls

Meaningful Names

Names are everywhere in the software. We name our variables, functions, arguments,classes and namespaces. We name our source files and the directories that contain them.So Basically we Name and Name and Name. Because we do so much of it . We’d better do it well. Let is see simple rules for creating good names.

Use Intent Revealing Names

Choosing names takes time but it saves more than it takes. So take care while naming and do change them when you find better ones.Every one who reads your code will be happier(including you) if you do so.This is what you need to think while naming – The name of a variable , function , or a class , should tell you why it exists, what it does, and how it is used.

If a name requires a comment then it does not reveal its content. in the below variable ‘b’ reveals nothing . we should choose a name such that it should specify what is being measured and unit of measurement

int d; //ellapsed time in days
int elapsedTimeInDays;
int daysSinceCreation;
int daysSinceModification;
int fileAgeInDays;

If you follow this your life will become happy. consider if I ask you what the below code does
       public List<int[]> getThem()
        {
            List<int[]> list1 = new List<int[]>();
            foreach(var x in theList)
            {
                if(x[0] == 4)
                {
                    list1.Add(x);
                }
            }
            return list1;
        }
Why do you think its hard to tell what the above code does. 
its not at all complex its just plain 4 lines of code. 
Here the problem is not about the simplicity of the code, but its about the imlicity , meaning, 
the degree to which the context is not explicit in the code itself. with the above code its hard to answer 
the below questions
  1. What kind of things are in theList ?
  2. What is the significance of zeroth subscript of an item in theList?
  3. What is the significance of value 4?
  4. How should I use the list being returned?

I am sure with looking the larger context of the program its very hard to answer the above questions. Now consider the below code after reformatting the above code

public List<int[]> getFlaggedCells()
        {
            List<int[]> flaggedCells = new List<int[]>();
            var STATUS_VALUE = 0;
            var FLAGGED = 4;
            foreach (int[] cell in gameBoard)
            {
                if(cell[STATUS_VALUE] == FLAGGED)
                {
                    flaggedCells.Add(cell);
                }
            }
            return flaggedCells;
        }
Now if you see above code, readability is much better after just applying naming conventions.
And we can go further and create a new class and hide all the magic numbers(4, 0) in that
class as shown below.
 public List<Cell> getFlaggedCells()
        {
            List<Cell> gameBoard = new List<Cell>();
            List<Cell> flaggedCells = new List<Cell>();
            foreach (var cell in gameBoard)
            {
                if (cell.isFlagged())
                {
                    flaggedCells.Add(cell);
                }
            }
            return flaggedCells;
 
        }
As you can see readability is must better now, all the implementation details are abstracted.

The Art of Clean Code

Now lets say you believe that messy code is a significant impediment.and also you accept that only way to go faster is to keep your code clean.Then here comes the question you need to ask your self

“How do I write clean code.?” Its no good trying to write clean code if you do not know what it means for code to be clean!

Writing clean code is a lot like painting a picture. Most of us know when a picture is bad by looking at it self. this doesn’t make us to be a good painter or know how to paint. So too being able to recognize clean code from dirty code doesn’t mean that we know how to write a clean code!

Monalisa Good Painting     MANA LISA
Andrea Schmidt, Vancouver, Canada
12"x16", oil on canvas
Donated by the artist, January, 2002
MOBA #370

A cross-gender interpretation of the daVinci classic. Mana Lisa’s nose strikes nimbly, offsetting the dialogue between the foreground and profoundly varnished background.
Further, by deciphering this work’s title, perhaps we can contribute to the growing body of Leonardo's anagrammatic discourse:
MAN ALIAS
I AM NASAL
A SAIL MAN
AS ANIMAL
AM A SNAIL
MAIL NASA

From—Museum of Bad Art: Masterworks by Michael Frank and Louise Reilly Sacco

 

Writing clean code requires the disciplined use of extremely great number of little techniques applied through painstakingly “acquired” sense of cleanliness.The “code-sense” is the key.

Some of us are luckily born with it. Some of us have to fight to acquire it.Not only it lets us to see whether a code is good or bad, but also shows us the strategy for applying the

discipline to transform bad code in to clean code.

 

A Programmer with out “code-sense”  can look at a messy code and can recognize the mess but will have no idea what to do about it.But a Programmer with Code-Sense will look at a messy module and see options and variations and can choose the best variation to solve that mess

 

“Clean code is simple and direct. Clean code reads like well-written prose. Clean code never obscures the designer’s intent but rather is full of crisp abstractions and straightforward lines
of control.”-Grady Booch,

Attitude

 

Have you ever worked on a code that should have taken hours to compete and you took days to complete it. Have you seen what should have been a one-line change but that change impacts many modules and hundred of lines have to be changed to achieve that.

 

Why do you think that happens ? is this because of bad code? I am sure at first you might of taken care of writing good code and what happened to that good code? what contributed you writing bad code

Many of us might complain its because of change in requirements, or tight schedules to do the things right. But I believe its because of us the developers. developers should take blame for this rotten code, NOT the managers or customers.

 

its our responsibility to tell our managers that “hey this code is shit, we need to refactor it first before we do any changes to it”, when your manager says finish this at any cost.and believe me most of the time your manager would listen to you, even they are obsessing about the schedule.

 

to drive this point, consider what if you are a doctor and had a patient who demanded that you stop all the silly hand washing in the preparation of surgery because its taking too much of his time . would you listen to him? since he is the boss!. it would have been unprofessional(rather a crime!) if you would have listened to him.

So too its unprofessional for programmers to bend  to the will of Managers who don’t understand the risks of making  a mess.

All the developers with more than few years of experience  know that bad code slows you down,and yet we choose to make messes in order to meet deadline.

 

True Professionals do not make a mess of a code in order to meet a deadline. They know that the mess will slow them down eventually and will miss them to miss the deadline. So they know out of their experience that – the only way to go fast – is to keep the code as clean as possible at all times.

Delegates

We can think delegate type as a single method interface , and a delegate instance as an object implementing that interface.

As an example, consider your will, “pay the bills, make a donation to the charity,leave the rest of my estate to my cat” for instance you write it before your death and leave it in an appropiately safe place . After your death, your attorny will act on those instructions.”

A delegate in c# acts like your will in real world- it allows you to specify a sequence of actions to be executed at the appropriate time.

A Recipe for Simple Delegates

In order for a delegate to do anything , four things need to happen

  1. The delegate Type needs to be declared
  2. The code to be executed must be contained in a method
  3. The delegate instance must be created
  4. The delegate instane must be invoked

Example

class Program
 {
   delegate void StringProessor(string input);
   static void Main(string[] args)
   {
     Person jon = new Person("jon");
     Person tom = new Person("Tom");
 
     StringProessor jonsVoice, tomsVoie, background;
 
     jonsVoice = new StringProessor(jon.Say);
     tomsVoie= new StringProessor(tom.Say);
     background = new StringProessor(Background.Note);
 
     jonsVoice("HelloSon");
     tomsVoie.Invoke("Hello, Dady!");
     background("An Airplae files past");
   }
 }
 
 class Person
 {
   string name;
 
   public Person(string name)
   {
     this.name = name;
   }
 
   public void Say(string message)
   {
     Console.WriteLine("{0} says: {1}", name , message);
   }
 }
 
 class Background
 {
   public static void Note(string note)
   {
     Console.WriteLine("{0}",note);
   }
 }