Monday 5 December 2016

Javascript: prototype and construct

Equation 1: Object.prototype.[[prototype]] == null
Equation 2: Function.prototype.[[prototype]] === Object.prototype
Equation 3: Func.[[prototype]] == Function.prototype
Equation 4: Object.create(Obj).[[prototype]] = Obj
Equation 5: obj.[[prototype]] === obj.constructor.prototype
Equation 6: Object.prototype.prototype == undefined
Equation 7: Func.constructor === Function
Equation 8: Func.prototype.constructor === Func
Rule 1: When a property cannot be found on an obj, consult obj.[[prototype]], if still not found, consult obj.[[prototype]].[[prototype]] until reaching the end of chain (null)


I sorted these equations in the hope to explain the 'myths' around the prototype, constructor, and [[prototype]] (aka __proto__)

Let's see.

 

Exercise 1

Prove:
var obj = {};
Console.log(obj.prototype === undefined)

Solution:

obj doesn't have the property prototype on its own, it needs to consult obj.[[prototype]]. //Rule 1

obj.[[prototype]] === obj.constructor.prototype  //Equation 5
obj.constructor === Object //WHY?
obj.[[prototypte]] === Object.prototype

Object.prototype is the end of the chain because Object.prototype.[[prototype]] === null; //Equation 1

obj.prototype === obj.[[prototypte]].prototype === Object.prototype.prototype === undefined //Equation 6

 

Exercise 2

Prove:
var obj = new Object(2);
Console.log(obj.prototype === undefined);

Solution:

obj.[[prototype]] === obj.constructor.prototype  //Equation 5
obj.constructor === Number //WHY?
obj.[[prototype]] === Number.prototype

Number.prototype also doesn't have property prototype on its own, it needs to consult Number.prototype.[[prototype]] //Rule 1

Number.prototype.[[prototype]] === Object.prototype //Equation 2

obj.prototype === Number.prototype.[[prototype]].prototype === Object.prototype.prototype === undefined //Equation 6

Exercise 3

Prove:
var obj = Object.create(Object);
Console.log(obj.prototype === Object.prototype);

Solution:
obj.[[prototype]] === Object; //Equation 4
obj.prototype === obj.[[prototype]].prototype = Object.prototype //Rule 1

 

Exercise 4

Prove:
Console.log (Object.getPrototypeOf(Object) === Function.prototype); //true

Solution:
Object.[[prototype]] ===  Function.prototype; //Equation 3

Exercise 5

Prove:

var obj = new Function();
Console.log(Object.getPrototype(obj) === Function.prototype);

Solution:
typeof 'new Function()' is also a function!

obj.[[prototype]] === Function.prototype; //Equation 3


Note: Those lines with //WHY are the ones that I am unable to account for. Strictly speaking, new Object(2) doesn't even have a constructor property on its own. There are some circular arguments around equation 5. For now, I just tell the object's constructor by looking at its definition --- new Object(2) is a Number, "123" is also a Number, "ABC" is a String, etc. The ones that I cannot tell are Objects.This assumption could be deeply flawed. Will find out..

Friday 25 November 2016

Javascript: every, some, arrow function

Array.every() returns true when all the items meet certain condition

var nums = [5,7,10,17,20];
var nums2 = [11,17,20,23];

var allBig = nums.every(function(element){
    return element > 10;
});

console.log(allBig); //false

//ES6 arrow function
allBig = nums.every(element => element > 10);

console.log(allBig); //false

allBig = nums2.every(function(element){
    return element > 10;
});

console.log(allBig); //true

//ES6 arrow function
allBig = nums2.every(element => element > 10);

console.log(allBig); //true

Array.some() returns true when any item meets certain condition.
var nums = [5,7,10,17,20];
var nums2 = [11,17,20,23];

var allBig = nums.some(function(element){
    return element > 10;
});

console.log(allBig); //true

//ES6 arrow function
allBig = nums.some(element => element > 10);

console.log(allBig); //true

allBig = nums2.some(function(element){
    return element > 30;
});

console.log(allBig); //false

//ES6 arrow function
allBig = nums2.some(element => element > 30);

console.log(allBig); //false

Thursday 24 November 2016

Effective Java Item 35. Write own annotation and reflection

 //Almost always RUNTIME  
 @Retention(RetentionPolicy.RUNTIME)  
 @Target({ElementType.TYPE, ElementType.METHOD})  
 @interface MyTest {}  
 class Sample{  
   @MyTest  
   public static void m1(){}  
 }  
 public class MyAnnotation{  
   public static void main(String[] args){  
     Class testClass = Sample.class;  
     //Get all methods including private, protected  
     //as opposed to testClass.getMethods() only returning public methods  
     for (Method m : testClass.getDeclaredMethods()){  
       if (m.isAnnotationPresent(MyTest.class)){  
         try{  
           m.invoke(null); //Call static method  
         } catch (InvocationTargetException e) {  
           e.printStackTrace();  
         } catch (Exception e) {  
           e.printStackTrace();  
         }  
       }  
     }  
   }  
 }  

Javascript: check undefined/null

If you are sure the variable has been declared (i.e var a;), simply use
if (a != null){
    ...
}
If a can be undeclared, then use


if (typeof a != 'undefined' && a != null){
    ...
}

Javascript: softbind

Excerpted from You Don't Know JS: this & Object Prototypes

I couldn't fully understand the code below.
  
if (!Function.prototype.softBind) {
    Function.prototype.softBind = function(obj) {
        var fn = this,
            curried = [].slice.call( arguments, 1 ),
            bound = function bound() {
                return fn.apply(
                    (!this ||
                        (typeof window !== "undefined" &&
                            this === window) ||
                        (typeof global !== "undefined" &&
                            this === global)
                    ) ? obj : this,
                    curried.concat.apply( curried, arguments )
                );
            };
        bound.prototype = Object.create( fn.prototype );
        return bound;
    };
}

function foo() {
   console.log("name: " + this.name);
}

var obj = { name: "obj" },
    obj2 = { name: "obj2" },
    obj3 = { name: "obj3" };

var fooOBJ = foo.softBind( obj );

fooOBJ(); // name: obj

obj2.foo = foo.softBind(obj);
obj2.foo(); // name: obj2   <---- look!!!

fooOBJ.call( obj3 ); // name: obj3   <---- look!

setTimeout( obj2.foo, 10 ); // name: obj   <---- falls back to soft-binding
  1. What does [].slice.call(...) do? 
  2. Are the two 'this' referring to the same thing? 
  3. What does bound.prototype = Object.create(fn.prototype) do?
Let's go through the code step by step by inserting some console output code. And for the sake of demonstrating the purpose of curried, I also rewrote the foo() function.
if (!Function.prototype.softBind) {
    Function.prototype.softBind = function(obj) {
        var fn = this;
        console.log("Outer this = "+ fn);
        var curried = [].slice.call( arguments, 1 );
        console.log("Outer curry = "+curried);
        var bound = function bound() {
            console.log("Inner this = " + this);
            console.log("Inner curry = "+curried.concat.apply( curried, arguments ));
            return fn.apply(
                (!this ||
                    (typeof window !== "undefined" &&
                        this === window) ||
                    (typeof global !== "undefined" &&
                         this === global)
                ) ? obj : this,
                curried.concat.apply( curried, arguments )
            );
        };
        bound.prototype = Object.create( fn.prototype );
        console.log("return bound");
        return bound;
    };
}

function foo(a1, a2) {
   console.log(a1 + ' ' +a2 + " name: " + this.name);
}

var obj = { name: "obj" },
    obj2 = { name: "obj2" },
    obj3 = { name: "obj3" };

var fooOBJ = foo.softBind( obj, 'A1');
fooOBJ('A2'); // name: obj

//obj2.foo = foo.softBind(obj, 'A1');
//obj2.foo('A2'); // name: obj2   <---- look!!!

//fooOBJ.call( obj3 ); // name: obj3   <---- look!
Here is the output.
Outer this = function foo(a1, a2) {
   console.log(a1 + ' ' +a2 + " name: " + this.name);
}
Outer curry = A
return bound
Inner this = [object Object]
Inner curry = A,A2
A A2 name: obj2

[].slice.call(arguments, 1)
is semantically equal to
arguments.slice(1)
except the latter is syntactically incorrect because the variable arguments is not a real array. It's an 'array-like' object.

The outer this refers to the foo function while the inner this refers to the window (global) variable. It's worth noting that by the time foo.softBind(obj) completes execution, the bound() function hasn't been invoked. It's only invoked when the line fooOBJ('A2') is executed.

bound.prototype = Object.create( fn.prototype );
copies all the properties of foo to bound, essentially ensuring that after softbind the function foo doesn't lose any properties.

Wednesday 23 November 2016

Javascript: dabble in 'new'

The code snippet below demonstates the difference between invoking a function with and without new.
function foo(a) {
    this.a = a;
}

var bar = new foo( 2 );
var bar2 = foo( 2 );

console.log( bar); // foo {a: 2}
console.log( bar.a); // 2
console.log( bar2); // undefined 
console.log( bar2.a); // TypeError
Why bar2 is undefined? Because there is no return statement in foo(). What if there is?
function foo(a) {
    this.a = a;
    return this;
}

var bar = new foo( 2 );
var bar2 = foo( 2 );

console.log( bar); // foo {a: 2}
console.log( bar.a); // 2
console.log( bar2); // Window {top: Window, location: Location, document: document, window: Window, external: Object…}
console.log( bar2.a); // 2
Why bar2.a = 2 while bar2 itself is the Window object? Because this refers to the Window object and this.a essentially creates an 'a' variable in global scope (Window object). Now what if returning something other than this?
function foo(a) {
    this.a = a;
    return 3;
}

var bar = new foo( 2 );
var bar2 = foo( 2 );

console.log( bar); // foo {a: 2}
console.log( bar.a); // 2
console.log( bar2); // 3
console.log( bar2.a); // undefined
Oh, it turns out that having a 'new' precede a function ignores the return statement all together. Although the author of stresses that 'new' in Javascript has nothing to do with the constructor concept in class-oriented languages, I, with a Java background, am still inclined to interpret it as:
class foo{
    var a;
 
    public foo(a){
        this.a = a;
    }
}

var bar = new foo(2);

Tuesday 22 November 2016

Javascript: 'this' and call

In this post, my assertion that

impl.apply(impl, deps) = impl.apply(null, deps);

just shows how naive I was due to the lack of understanding of 'this' mechanism.

From You Don't Know JS: this & Object Prototypes

function foo(num) {
    console.log( "foo: " + num );

    // keep track of how many times `foo` is called
    // Note: `this` IS actually `foo` now, based on
    // how `foo` is called (see below)
    this.count++;
}

foo.count = 0;

var i;

for (i=0; i<10; i++) {
    if (i > 5) {
        // using `call(..)`, we ensure the `this`
        // points at the function object (`foo`) itself
        foo.call( foo, i );
    }
}
// foo: 6
// foo: 7
// foo: 8
// foo: 9

// how many times was `foo` called?
console.log( foo.count ); // 4 
The first parameter foo essentially makes 'this' point to the foo object.
Now replace the line with

foo.call( null, i );

It prints out '0' because this refers to window object now.

I am tempted to boldly make this assertion that the following two pairs of method invocation can always be used interchangeably.

foo.call( foo, i ) = foo.bind(foo)(i)
foo.call( null, i) = foo(i)  

Let's see when I can be proved wrong.


Javascript: dabble in 'this'

It is probably going to take me a while to fully grasp the 'this' concept in Javascript. Today I just dabble in the topic and present my shallow understandings.

It still comes from You Dont Know Js Scope and Closure, Appendix C: Lexical this.

var obj = {
    id: "awesome",
    cool: function coolFn() {
        console.log( this.id );
    }
};

var id = "not awesome";

obj.cool(); // awesome

setTimeout( obj.cool, 100 ); // not awesome

It looks like when invoked from setTimeout(), this refers to the window object. Then the author introduced various solutions, including self, bind(), and a new feature of ES6: arrow function. These are all cool stuff. But how to address the original problem -- that is, to get setTimeout() function to print 'awesome' as well?

The simplest solution is replace this with obj

console.log( obj.id );

Then I attempt to use bind().

cool2: function coolFn2() {
    console.log( this.id );
}.bind(obj)
It doesn't work because obj cannot be referenced within itself, well, unless it is referenced within a function. Therefore the 2nd attempt.

cool3: function coolFn3() {
    (function(){
        console.log(this.id); 
    }.bind(obj))();
} 
Hey it works. I wouldn't have come up with this solution if I hadn't read the previous chapters of 'You Dont Know Js'. So once again, kudos to the author.

Javascript: apply

In You Dont Know JS Chapter 5: Scope Closure, there is following code snippet to illustrate the power of module pattern.

var MyModules = (function Manager() {
    var modules = {};

    function define(name, deps, impl) {
        for (var i=0; i<deps.length; i++) {
            deps[i] = modules[deps[i]];
        }
        modules[name] = impl.apply(impl, deps);
        console.log("module "+modules[name]);
    }

    function get(name) {
        return modules[name];
    }

    return {
        define: define,
        get: get
    };
})();

MyModules.define( "bar", [], function(){
    function hello(who) {
        return "Let me introduce: " + who;
    }

    return {
        hello: hello
    };
} );

MyModules.define( "foo", ["bar"], function(bar){
    var hungry = "hippo";

    function awesome() {
        console.log( bar.hello( hungry ).toUpperCase() );
    }

    return {
        awesome: awesome
    };
} );

var bar = MyModules.get( "bar" );
var foo = MyModules.get( "foo" );

console.log(bar.hello( "hippo" )); // Let me introduce: hippo

foo.awesome(); // LET ME INTRODUCE: HIPPO

What does this line do?
modules[name] = impl.apply(impl, deps);

It is another way of invoking a function, sort of like Java reflection. And we get to pass an array variable in the second argument to replace a list of parameters. What is the first argument for?

According  to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply

fun.apply(thisArg, [argsArray])

Parameters

thisArg
The value of this provided for the call to fun. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.
I don't quite understand this definition. As far as I am concerned,

fun.apply(thisArg, [argsArray]) = thisArg.fun(arg1, arg2....)

In this case, I also don't understand why the first parameter is 'impl'. But I have proved it can be replaced with 'null'.

The next question is why the function needs to be called in such a unconventional way. Could it be called normally?

If we put

modules[name] = impl(deps);

bar.hello() executes OK, but foo.awsome() throws TypeError: bar.hello is not a function.

Then try

modules[name] = impl(deps[0]);

It does work. But obviously it's not a universal solution. Hence the use of apply().

Thursday 17 November 2016

Javascript: Closure + Loop

What does this program print out?
for (var i=1; i<=5; i++) {
    setTimeout( function timer(){
        console.log( i );
    }, i*1000 );
}
At first glance, it seems to print 1,2,3,4,5, at 1 second interval. But in fact, it prints 6,6,6,6,6 at 1 second interval. What is going on?

At second glance, it does make sense. The timer() function is invoked after the waiting period (i*1000). By the time it starts to execute, the for loop has long finished. And at this point of time, i = 6.

So how to fix it? 

By wrapping the setTimeout() with a function makes the variable j local to the enclosing function.

for (var i=1; i<=5; i++) {
    (function(){
        var j = i;
 setTimeout( function timer(){
     console.log(j);
        }, i*1000 );
    })();
}
A neater variation.
for (var i=1; i<=5; i++) {
    (function(j){
 setTimeout( function timer(){
     console.log(j);
        }, i*1000 );
    })(i);
}
Even better is replace var with let (ES6 feature)
for (let i=1; i<=5; i++) {
    setTimeout( function timer(){
 console.log(i);
    }, i*1000 );
}
This is most surprising. It turns out let not only restrain the variable within the for loop but also each iteration!

Wednesday 16 November 2016

Javascript: What is the difference between function foo(){...} and var foo = function(){...}

()This has been puzzling me for a long time.
function bar(){
    console.log("bar");
}

var foo = function (){
    console.log("foo");
}

bar();
foo();

What's the difference between these two formats?

I always use the first format to declare a function and deem the second format as an advanced, fancy one.

Now I learnt that the 'fancy' format is actually the less preferred way to declare the function because the function must be called after its declaration while in first format the function can be called anywhere.


bar(); //Print 'bar'
foo(); //TypeError

function bar(){
    console.log("bar");
}

var foo = function (){
    console.log("foo");
}

It turns out Javascript compiler moves all the declaration (e.g. var a) to the top and leaves the assignment (a = 2) where it is.  (By the way, I wasn't aware Javascript has a compiler until today)

So the above code is interpreted by the compiler as

function bar(){
    console.log("bar");
}

var foo;

bar(); //Print 'bar'
foo(); //TypeError

foo = function (){
    console.log("foo");
}

function bar() is moved to top as a whole but function foo is separated into var foo and foo = ...

Another point worth mentioning is that function declaration (in first format) overrides the same function name.


function bar(){
    console.log("bar");
}

bar(); //Print 'foo'

function bar(){
    console.log("foo");
}




Tuesday 15 November 2016

Javascript: function expression

I often came across this pattern in javascrip code and never understood the advantage of it.

(function(window, document, undefined){
    window.MyObject = {
        methodA: function() { ... },
        methodB: function() { ... }
    };
})(window, document)

After reading You don't know JS (a great book), I finally came to understand this pattern. Here is a summary of my understanding.

This is how we normally define and call a js function:

var a = 2;

function foo(){
    var a = 3;
    console.log("inner a =" + a ); // 3
}; 

console.log("outer a = " + a ); //2

foo();

It is not ideal because we have to explictly call foo() to execute the function. If we just wish to call this method once and done, we have wasted one line of code.

Another issue is that it "pollutes the enclosing scope (quote the book)". I am personally OK with that. It's just one less variable name available for using.

Javascript has a solution to both problems:

var a = 2;

(function foo(){
    var a = 3;
    console.log("inner a =" + a ); // 3
})(); 

console.log("outer a = " + a ); //2

foo(); //ReferenceError

By wrapping the whole function with (), appending another pair of (), we are able to execute the function directly.

More significantly, now the variable foo is not accessible in global scope (Attemping to access it throws a refrenceError). In fact, foo is only accessible within the function scope.

Since it's unlikely to access foo variable within the function scope, anonymous function is preferred here.

(function (){
    var a = 3;
    console.log("inner a =" + a ); // 3
})();

A variation of this form is moving the second pair of () inside the first pair ()

(function (){
    var a = 3;
    console.log("inner a =" + a ); // 3
}());

These two forms are identical in functionality.

Parameter can be passed to the function. Now it looks more and more like the most common seen format in the js library code.


var a = 3;

(function (window){
    var a = 2;
    console.log( "a = "+a);
    console.log( "global a = "+window.a);    
})(window);

The book says another usage of the pattern is to address the issue of the value of undefined identifier being overwritten.

var undefined = true; // setting a land-mine for other code! avoid!

(function (){
    var a;
    if (a === undefined) {
        console.log( "a is undefined"); //still undefined
    }else{
        console.log( "a is defined" );
    }
})();

After experimenting, it turns out you can't overwrite the value of undefined in global scope -- You can only overwrite it within a function sceop. So in order to demonstrate the usage, I wrap the code with a function.

function foo(){

    var undefined = true; // setting a land-mine for other code! avoid!

    (function (){
        var a;
        if (a === undefined) {
            console.log( "a is undefined");
        }else{
            console.log( "a is defined" ); //becomes defined
        }
    })();
}

By defining an undefined paramater and not passing any value for that argument, undefined is guaranteed to be undefined.

function foo(){

    var undefined = true; // setting a land-mine for other code! avoid!

    (function (undefined){
        var a;
        if (a === undefined) {
            console.log( "a is undefined"); //Undefined, yeah!
        }else{
            console.log( "a is defined" );
        }
    })();
}

Sunday 13 November 2016

Javascript: Calculate Inbreeding Coefficient

A little background:

http://cal.vet.upenn.edu/projects/genetic/inbreed/coeff/page1.htm
http://cal.vet.upenn.edu/projects/genetic/inbreed/coeff/page2.htm






Fx = the coefficient of inbreeding of individual x
n = number of generations from the sire (father) of x back to some ancestor common to the sire and dam

n' = number of generations from the dam (mother) of x back to some ancestor common to the sire and dam

Fa = coefficient of inbreeding of the common ancestor when that animal is itself inbred

∑ = summation of the separate contributions of each common ancestor (the summation here refers to all possible pathways by which an allele could be passed from the common ancestor to both parents)














Let's start with an example.

We have two common ancestors here: 1 and 2

First calculate the contribution from common ancestor 1.

n = the number of generations from the sire (in this case 3) to the common ancestor 1, that is 1
n' = the number of generations from the sire (in this case 3) to the common ancestor 1, that is also 1

(1/2)^(1+1+1)*(1+0) = 1/8.

Why Fa = 0? Because the inbreeding coefficient of common ancestor 1 is 0.

Contribution from common ancestor 2 is apparently also 1/8 due to symmetry.

Thus, the inbreeding coefficient of x Fx = 1/8 + 1/8 = 1/4 = 0.25

I decide to use Javascript to implement this equation. 

A crucial task is to find all the common ancestors. In this case it is easy to spot 1 and 2. Things get trickier when father mates daughter. We may end up with some common ancestors which should be excluded from the calculation. Check this complex scenario.












In this case, by definition, F, C, E, D, G are all common ancestors of A and B, since B is A's daughter. In fact, F, C, E, D have no contribution towards inbreeding coefficient. However, G does make contribution because it can reach B through another path that doesn't contain A (GHB).

We break the task down into finding the ancestors of father and mother respectively, then find the common ones.

1. Not ony do we need to know the ancestor, but also we need to know the path. (In my program, I call it 'chain')

So for father A, we have 6 ancestors (including himself) but 7 paths

A
A C
A C F
A C E
A D
A D E
A D G

For mother B, we have 9 ancestors (everyone except x) but 11 paths

B
B A
B A C
B A C F
B A C E
B A D
B A D E
B A D G
B H
B H G
B H M

2. Compare each pair of paths between A and B. The last element of the path is a common ancestor candidate. Needless to say, the last element of the pair needs to match one another to start with. Then we check in addtion to the last element, is there any other common element? If there is, we need to ditch this common ancestor (e.g. E in ACE and BACE) too because it doesn't contribute towards inbreeding coefficient as discussed earlier. Finally we identify two common ancestors: A (A, AB) and G (ADG, BHG). The length of two paths combined minus 1 is actually the n+n'+1 part in the equation.

Technical note. For the first time, I try to use a Javascript unit test framework -- QUnit. It has similar syntax to JUnit, and I found it very pleasant to use.

Highlight of new stuff learnt.
  • QUnit
  • Javascript closure/module
  • slice() method - used to copy array and get the last item of the array
Let's quickly check some results

ScenarioInbreeding coefficient
Full siblings 0.25
Father daughter 0.25
Half siblings0.125
First cousins0.0625
3 generation full siblings0.5

Finally the code (https://github.com/sunmingtao/inbreed)

The Person.inbreedingCoefficient.complex test case corresponds to the 2nd complex scenario above.

inbreeding.js
 'use strict';  
  function Person(name, father, mother){  
      var myFather, myMother;  
      doFather(father);  
      doMother(mother);  
      function doFather(father){  
           if (notNull(father)){  
                myFather = father;       
                return;  
           }  
           return myFather;  
      }  
      function doMother(mother){  
           if (notNull(mother)){  
                myMother = mother;            
                return;  
           }  
           return myMother;  
      }  
      function doHasFather(){  
           return doHasParent(myFather);  
      }  
      function doHasMother(){  
           return doHasParent(myMother);  
      }  
      function doHasParent(parent){  
           return notNull(parent);  
      }  
      function doInbreedingCoefficient(){  
           var fatherChains = doFatherChains();  
           logChains(fatherChains, "Father chains of "+name);  
           var motherChains = doMotherChains();  
           logChains(motherChains, "Mother chains of "+name);  
           var result = 0;  
           for (var i=0; i<fatherChains.length; i++){  
                for (var j=0; j<motherChains.length; j++){  
                     var num = numberGenerationToCommonAncestor(fatherChains[i], motherChains[j]);  
                     if (num) { //is a common ancestor  
                          var commonAncestor = fatherChains[i].fathestAncestor();  
                          console.log("Found common ancestor: "+commonAncestor.name+". Num is "+num);  
                          result += Math.pow(0.5, num)*(1+commonAncestor.inbreedingCoefficient());  
                     }  
                }  
           }  
           return result;  
      }  
      function doFatherChains(){  
           return doParentChains(myFather);  
      }  
      function doMotherChains(){  
           return doParentChains(myMother);  
      }  
      function doParentChains(parent){  
           var chains = [];  
           if (doHasParent(parent)){  
                chains.push(Chain([parent])); //parent itself  
                var ancestors = parent.chains(); //All parents' ancestors  
                for (var i = 0; i < ancestors.length; i++){  
                     var chain = ancestors[i];  
                     chain.prepend(parent);  
                     chains.push(chain);  
                }  
           }  
           return chains;  
      }  
      function doChains(){  
           return doFatherChains().concat(doMotherChains());  
      }  
      var publicAPI = {  
           name: name,  
           father: doFather,  
           mother: doMother,  
           hasFather: doHasFather,  
           hasMother: doHasMother,  
           fatherChains: doFatherChains,  
           motherChains: doMotherChains,  
           chains: doChains,  
           inbreedingCoefficient: doInbreedingCoefficient  
      };  
      return publicAPI;  
  }  
  function Chain(persons){  
       var myChain = persons;  
       function getChain(){  
            return myChain;  
       }  
       function doPrepend(person){  
            myChain.unshift(person);  
       }  
       function getLength(){  
            return myChain.length;  
       }  
       function getFathestAncestor(){  
            return myChain.slice(-1)[0];  
       }  
       function doToString(){  
            var result = '';  
            for (var i=0; i<persons.length; i++){  
                 result += persons[i].name + ' ';  
            }  
            return result;  
       }  
       return {  
           chain : getChain,  
           prepend: doPrepend,  
           length: getLength,  
           fathestAncestor: getFathestAncestor,  
           toString: doToString  
       };  
  }  
 //returns the number of nodes to go from start point of chain 1 (item 0) to common ancestor, then to the start point of chain 2  
 //if two pathways to the common ancestor share a portion of same route, return 0. chain 1 = [a, c, f, g], chain 2 = [b, d, f, g].   
 //In this case, f is deemed 'common ancestor', g is not (because fg is shared by both chains)  
 //e.g.1 chain 1 = [a, c, f], chain 2 = [b, f], then traverse acfb, return 4  
 //e.g.2 the start point itself is a common ancestor. chain 1 = [a], chain 2 = [b, a], then traverse ab, return 2  
 //e.g.3 if no common ancestor, return 0. chain 1 = [a, c], chain 2 = [b, d]  
 function numberGenerationToCommonAncestor(chain1, chain2){  
      if (chain1.fathestAncestor() != chain2.fathestAncestor() || hasCloserCommonAncestor(chain1, chain2)){  
           return 0;  
      }  
      return chain1.length() + chain2.length() - 1;  
 }  
 //Check if other closer common ancestor exists apart from the farthest common ancestor  
  function hasCloserCommonAncestor(chain1, chain2){  
       var persons1 = chain1.chain().slice(); //make a copy  
       var persons2 = chain2.chain().slice();  
       persons1.pop(); //chop off the last item  
       persons2.pop();  
       for (var i=0; i<persons1.length; i++){  
            for (var j=0; j<persons2.length; j++){  
                 if (persons1[i] == persons2[j]){  
                      return true;  
                 }  
            }  
       }  
       return false;  
  }  
  function logChains(chains, message){  
      console.log(message);   
      for (var i=0; i<chains.length; i++) {  
           console.log(chains[i].toString());  
      }        
  }  
  function notNull(v){  
       return typeof v !== 'undefined' && v !== null;  
  }  

tests.js
 QUnit.test( "Person.init", function( assert ) {  
      var a = Person('a');  
      assert.equal( a.name, 'a');  
      var b = Person('b');  
      var c = Person('c', a , b);  
      assert.equal(c.mother().name, b.name);  
      var d = Person('d');  
      d.father(a);  
      d.mother(b);  
      assert.equal(d.mother().name, b.name);  
 });  
 QUnit.test( "Person.hasFatherMother", function( assert ) {  
      var a = Person('a');  
      assert.equal( a.hasFather(), false);  
      var b = Person('b');  
      var c = Person('c', a , b);  
      assert.equal( c.hasFather(), true);  
      var d = Person('d');  
      d.father(a);  
      d.mother(b);  
      assert.equal( d.hasMother(), true);  
 });  
 QUnit.test( "Person.chain", function( assert ) {  
      var a = Person('a');  
      assert.equal( a.fatherChains().length, 0);  
      var b = Person('b');  
      var c = Person('c', a , b);  
      assert.equal( c.fatherChains().length, 1);  
      assert.equal( c.fatherChains()[0].chain()[0].name, 'a');  
 });  
 QUnit.test( "Person.longer.chain", function( assert ) {  
      var a = Person('a');  
      var b = Person('b');  
      var c = Person('c', a , b);  
      var d = Person('d');  
      var e = Person('e', c, d);  
      assert.equal( e.fatherChains().length, 3);  
      assert.equal( e.fatherChains()[0].chain().length, 1);   
      assert.equal( e.fatherChains()[0].chain()[0].name, 'c');  
      assert.equal( e.fatherChains()[1].chain().length, 2);  
      assert.equal( e.fatherChains()[1].chain()[0].name, 'c');  
      assert.equal( e.fatherChains()[1].fathestAncestor().name, 'a');  
      assert.equal( e.fatherChains()[2].chain().length, 2);  
      assert.equal( e.fatherChains()[2].chain()[0].name, 'c');  
      assert.equal( e.fatherChains()[2].fathestAncestor().name, 'b');  
 });  
 QUnit.test( "Chain.prepend", function( assert ) {  
      var a = Person('a');  
      var chain = Chain([a]);  
      assert.equal( chain.length(), 1);  
      var b = Person('b');  
      chain.prepend(b);  
      assert.equal( chain.length(), 2);  
      assert.equal( chain.chain()[0].name, 'b');  
 });  
 QUnit.test("numberGenerationToCommonAncestor", function( assert ) {  
      var a = Person('a');  
      var b = Person('b');  
      var c = Person('c');  
      var d = Person('d');  
      var e = Person('e');  
      var chain1 = Chain([a]);  
      var chain2 = Chain([b]);  
      assert.equal(numberGenerationToCommonAncestor(chain1, chain2), 0);  
      var chain1 = Chain([c, b]);  
      var chain2 = Chain([b]);  
      assert.equal(numberGenerationToCommonAncestor(chain1, chain2), 2);  
      var chain1 = Chain([c, a]);  
      var chain2 = Chain([d, a]);  
      assert.equal(numberGenerationToCommonAncestor(chain1, chain2), 3);  
      var chain1 = Chain([c, a, b]);  
      var chain2 = Chain([d, a, b]);  
      assert.equal(numberGenerationToCommonAncestor(chain1, chain2), 0);  
 });  
 QUnit.test("Person.inbreedingCoefficient.notInbred", function( assert ) {  
      var a = Person('a');  
      var b = Person('b');  
      var x = Person('x', a, b);  
      assert.equal(x.inbreedingCoefficient(), 0);  
 });  
 QUnit.test("Person.inbreedingCoefficient.fullSibling", function( assert ) {  
      var a = Person('a');  
      var b = Person('b');  
      var c = Person('c', a, b);  
      var d = Person('d', a, b);  
      var x = Person('x', c, d);  
      assert.equal(x.inbreedingCoefficient(), 0.25);  
 });  
 QUnit.test("Person.inbreedingCoefficient.halfSibling", function( assert ) {  
      var a = Person('a');  
      var b = Person('b');  
      var c = Person('c');  
      var d = Person('d', a, b);  
      var e = Person('e', b, c);  
      var x = Person('x', d, e);  
      assert.equal(x.inbreedingCoefficient(), 0.125);  
 });  
 QUnit.test("Person.inbreedingCoefficient.fatherDaught", function( assert ) {  
      var a = Person('a');  
      var b = Person('b');  
      var c = Person('c', a, b);  
      var x = Person('x', a, c);  
      assert.equal(x.inbreedingCoefficient(), 0.25);  
 });  
 QUnit.test("Person.inbreedingCoefficient.firstCousin", function( assert ) {  
      var a = Person('a');  
      var b = Person('b');  
      var c = Person('c', a, b);  
      var d = Person('d', a, b);  
      var e = Person('e');  
      var f = Person('f');  
      var g = Person('g', c, e);  
      var h = Person('h', d, f);  
      var x = Person('x', g, h);  
      assert.equal(x.inbreedingCoefficient(), 0.0625);  
 });  
 QUnit.test("Person.inbreedingCoefficient.complex", function( assert ) {  
      var F = Person('F');  
      var E = Person('E');  
      var G = Person('G');  
      var M = Person('M');  
      var C = Person('C', F, E);  
      var D = Person('D', E, G);  
      var H = Person('H', G, M);  
      var A = Person('A', C, D);  
      var B = Person('B', A, H);  
      var X = Person('X', A, B);  
      assert.equal(X.inbreedingCoefficient(), 0.3125);  
 });  
 QUnit.test("Person.inbreedingCoefficient.deepInbred", function( assert ) {  
      var a = Person('a');  
      var b = Person('b');  
      var c = Person('c', a, b);  
      var d = Person('d', a, b);  
      var e = Person('e', c, d);  
      var f = Person('f', c, d);  
      var g = Person('g', e, f);  
      var h = Person('h', e, f);  
      var x = Person('x', g, h);  
      assert.equal(x.inbreedingCoefficient(), 0.5);  
 });  

html
 <!DOCTYPE html>  
 <html>  
 <head>  
  <meta charset="utf-8">  
  <title>QUnit basic example</title>  
  <link rel="stylesheet" href="https://code.jquery.com/qunit/qunit-2.0.1.css">  
 </head>  
 <body>  
  <div id="qunit"></div>  
  <div id="qunit-fixture"></div>  
  <script src="https://code.jquery.com/qunit/qunit-2.0.1.js"></script>  
  <script type="text/javascript" src="inbreeding.js"></script>  
  <script type="text/javascript" src="tests.js"></script>  
 </body>  
 </html>  

Wednesday 9 November 2016

Javascript module

Module is the common usage of closure.

 function User(){  
      var username, password;  
      function doLogin(user,pw) {  
           username = user;  
           password = pw;  
           // do the rest of the login work  
      }  
      var publicAPI = {  
           login: doLogin  
      };  
      return publicAPI;  
 }  

Usage

 var fred = User();  
 fred.login('fred', '123');  

Attempt to access the invisible method doLogin() will generate an error

 fred.doLogin('fred', '123');  

TypeError: fred.doLogin is not a function 

Thursday 27 October 2016

Implement pagination with Spring-data-jpa framework

Today I have learnt a new way of dealing with pagination using Spring-data-jpa framework

 <dependency>  
   <groupId>org.springframework.data</groupId>  
   <artifactId>spring-data-jpa</artifactId>  
   <version>1.10.4.RELEASE</version>  
 </dependency>  

In the repository class

 @Query("Select E from Employee E where E.age >=:age")  
 public Page<Employee> findByAge(@Param("age")int age, Pageable pageable);  

Usage example. Pretty straight forward.

 Page<Employee> page = employeeRepo.findByAge(18, new PageRequest(0, 1, Direction.DESC, "age"));  
 if (page.getNumberOfElements() > 0){  
      return page.getContent().get(0);  
 }  
 return null;  

Thursday 22 September 2016

Spring MVC + jQuery Ajax get post cheat sheet

Get


 $.get( "get", { name: "John", time: "2pm" }, function( data ) {  
      alert( "Data Loaded: " + data );  
 });  

 @RequestMapping(value = "/get", method = RequestMethod.GET)  
 @ResponseBody  
 public String get(@RequestParam String name, @RequestParam time) throws Exception{  
      return "Hello "+name+" "+time;  
 }  

Post

 $.post("post", { name: "John", time: "2pm"}, function(data) {  
      alert( "Data Loaded: " + data );  
 });  

There are two ways to handle the request in controller
1. Use Request parameter
2. Use ModelAttributes

 //1st way  
 @RequestMapping(value = "/post", method = RequestMethod.POST)  
 @ResponseBody  
 public String post(@RequestParam String name, @RequestParam time) throws Exception{  
      return "Hello "+name+" "+time;  
 }  
 
 //2nd way
 public class AjaxRequest {  
      private String name;  
      private String time;  
      //Ingore setters and getters  
 }  
     
 @RequestMapping(value = "/post", method = RequestMethod.POST)  
 @ResponseBody  
 public String post(@ModelAttribute AjaxRequest request) throws Exception{  
      return "Hello "+name+" "+time;  
 }  

What if you want to use @RequestBody?

You cannot use the shorthand form $.post any more. You must use $.ajax method and specify the contentType as 'application/json' and stringify the data using JSON.stringify()

 $.ajax({  
      type : "POST",  
      //must set the contentType for @RequestBody annotation to work, otherwise use @ModelAttribute to replace @RequestBody  
      contentType : "application/json",   
      url : "post",  
      //must use the stringify method to convert to json format  
      data : JSON.stringify({ name: "John", time: "2pm"}),  
      success : function(data) {  
           console.log("SUCCESS: ", data);  
      }  
 });  
   
 @RequestMapping(value = "/post", method = RequestMethod.POST)  
 @ResponseBody  
 public String post(@RequestBody AjaxRequest request) throws Exception{  
      return "Hello "+name+" "+time;  
 }  

JSTL < c:url >

<c:url value='/abc' /> = context root name + "/abc"

In jsp
Context root name = ${pageContext.request.contextPath} (e.g. myApp)

Note c:url doesn't do URL encoding -- it doesn't convert 'a b' to 'a%20b'

Neither HttpServletResponse.encodeURL(Strin url) nor HttpServletResponse.encodeRedirectURL(String url) encodes URL

URLEncoder.encode(String url) does the job

http://www.cnblogs.com/season-huang/p/3439277.html
https://bluxte.net/musings/2006/03/29/servletpath-and-pathinfo-servlet-api-weirdness/

Monday 29 August 2016

Project Euler Problem 26: Reciprocal cycles

Problem


A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:
1/20.5
1/30.(3)
1/40.25
1/50.2
1/60.1(6)
1/70.(142857)
1/80.125
1/90.(1)
1/100.1
Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.
Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.

Solution

Use array to store the index of occurred digits is very efficient. Take 7 as example, each mod is 1,3,2,6,4,5, they are saved as arr[1]=1, arr[3]=2, arr[2]=3, arr[6]=4, arr[4]=5, arr[5]=6. Once you find an arr[i] such that arr[i] != 0, you immediately know the length.


      private static final int LIMIT = 1000;  
      public static void main(String[] args) {  
           int result = 0;  
           int longest = 0;  
           for (int i=2; i<LIMIT; i++){  
                int recurringNum = recurringNum(i);   
                if (recurringNum > longest){  
                     longest = recurringNum;  
                     result = i;  
                }  
           }  
           System.out.println(result);  
      }  
      public static int recurringNum(int num) {  
           int[] arr = new int[num+1];  
           int index = 1;  
           int mod = 1;  
           while(mod != 0 && arr[mod] == 0){  
                arr[mod]=index++;  
                mod = mod * 10 % num;  
           }  
           if (mod == 0){  
                return 0;  
           }  
           return index-arr[mod];  
   }  

Sunday 28 August 2016

Project Euler Problem 23: Non-abundant sums

Problem

A perfect number is a number for which the sum of its proper divisors is exactly equal to the number. For example, the sum of the proper divisors of 28 would be 1 + 2 + 4 + 7 + 14 = 28, which means that 28 is a perfect number.

A number n is called deficient if the sum of its proper divisors is less than n and it is called abundant if this sum exceeds n.

As 12 is the smallest abundant number, 1 + 2 + 3 + 4 + 6 = 16, the smallest number that can be written as the sum of two abundant numbers is 24. By mathematical analysis, it can be shown that all integers greater than 28123 can be written as the sum of two abundant numbers. However, this upper limit cannot be reduced any further by analysis even though it is known that the greatest number that cannot be expressed as the sum of two abundant numbers is less than this limit.

Find the sum of all the positive integers which cannot be written as the sum of two abundant numbers.

Solution

Initially I was using a Set to store all the abundant sum number. The performance was OK. But once I changed Set to List, the performance degraded badly. It prompted me to change the use of collection to a boolean array. I am pretty happy about the performance gain. 

      private static final int LIMIT = 28123;  
      private static final List<Integer> abundant = new ArrayList<>();  
      private static final boolean[] isAbundantSum = new boolean[LIMIT+1];  
      public static void main(String[] args) {  
           for (int i=1; i<=LIMIT; i++){  
                if (isAbundant(i)){  
                     abundant.add(i);  
                     for (int j : abundant){  
                          if (i+j <= LIMIT){  
                               isAbundantSum[i+j] = true;  
                          }  
                     }  
                }  
           }  
           int sum = 0;  
           for (int i = 1; i < isAbundantSum.length; i++){  
                if (!isAbundantSum[i]){  
                     sum += i;  
                }  
           }  
           System.out.println(sum);  
      }  
      private static int d(int number){  
           int sum = 1;  
           int sqrt = (int)Math.sqrt(number);  
           for (int i=2; i<=sqrt; i++){  
                if (number % i == 0){  
                     sum += (i + number / i);  
                }  
           }  
           if (sqrt * sqrt == number){  
                sum -= sqrt;  
           }  
           return sum;  
      }  
      private static boolean isAbundant(int number){  
           return d(number) > number;  
      }