Thursday, July 25, 2019

Is this stock advise worth taking seriously?

 Introduction

Business related TV channels and newspapers are replete with stock advisory from investment firms and certified individual advisors. How seriously should the average viewer and retail investor take these advices? There is the risk of a loss if an advise is acted upon, and the risk of lost opportunity if it is ignored. To heed or not to heed is then the question. What if we had a database of advices from different advisors, for different stocks, to either buy or sell them at a certain price and then wait and close that position when the stock hits a certain target price or a stop loss price, these advices being valid for the day ( meant for Day trade, that is), the short term (3 months) or the long term(1 year)? Surely, a lot could be learnt from this data; in particular, whether or not to take the advise seriously; and act - or not. Interested?

Tools of trade

Apart of course, from your laptop or desktop (preferably Ubuntu - just kidding!), we are going to need Python 3.7.0 or higher (if nothing because I have tried all my code on 3.7.0 and I am cautiously optimistic that they'll run on higher versions) and  Jupyter Notebooks 4.4.0. You could use anaconda as the big-brother package and environment manager for your Python installation as I tend to do, or you might not - up to you. Whether you use anaconda (conda install) or pip install to install the Python modules I am soon going to mention, just ensure that Jupyter notebooks, when you start it, uses the Python kernel from the same Python installation where you installed the modules. So, for example, if you have several Python virtual environments set up using anaconda, and you have installed all your modules into a particular Python 3 environment - let's call it python3env, then ensure that you run jupyter notebook only after you have run conda activate python3env in the shell. The conda activate... command ensures that the correct Python image is run when Jupyter runs it inside of itself. The Python modules I was going to mention are

  • pandas
  • numpy
  • scipy
  • matplotlib
You will also need a dataset of advices collected over a period of time. For the purpose of this blog, let's use a scaled down, representative dataset from my GitHub site. 

Now we have all the data in a pandas DataFrame called data

Staring at the data

The more you stare the better, but let it not be an empty gaze. Here's what I have come up with. First let's look at the data as a table. Just typing and executing data
in a Jupyter notebook cell displays it as follows:


What do we have here? Let's see. The 'buysell' attribute tells you if it's a buy advise (value '1') or a sell advise (value '2'). The 'durationtype' attribute tells us if it's a long term advise (valid for a year and value of the attribute is '3'), a short term advise ( valid for 3 months, value '2') or a day trade advise (valid for the trading day it was created on and value '1'). The advisor attribute identifies the advisor . The symbolname attribute identifies the stock symbol on the exchange (NSE, the Indian National Stock Exchange in this case). The 'otheradvices' attribute tells us if there has been a similar advice (by way of the buysell attribute and symbolname being the same) within 3 days of an advice. The niftysentiment attribute takes values '1' for 'up' and '2' for 'down', meaning that the Nifty 50 stock index opened higher or lower than the previous day's close respectively. Finally, the success attribute which is also the predicted variable tells us whether the advice actually went to make a profit (value '1') or loss (value '2'). 'Profit' in this case means the advice first hit the target price mentioned in the advice, while 'Loss' signifies that the stock price hit the stop loss first, within the advice duration period. If you are wondering why we don't see the target price, entry price and stop loss price for the advices in the table, then yes, you would be right to wonder. But we'll leave incorporating that important information for another day and blog. For now, we are going to focus only on the categorical attributes. Yes, the ones and twos and even the Trues and Falses shown as values in that table are all string values.
 One of the first things I like to see about the data at hand is the correlations between attributes. If only we had numeric attributes, then we could have used 
data.corr() to get correlations between all of them , but that is not to be! Categorical attributes need other means to get an idea of correlations. The following function which implements the Cramer's V test will give us this information. Explaining it is beyond the scope of this blog, since it involves the Chi-Square test. More explanation may be found here.

from scipy import stats as ss
def cramers_v(x, y):
    confusion_matrix = pd.crosstab(x,y)
    chi2 = ss.chi2_contingency(confusion_matrix)[0]
    n = confusion_matrix.sum().sum()
    phi2 = chi2/n
    r,k = confusion_matrix.shape
    phi2corr = max(0, phi2-((k-1)*(r-1))/(n-1))
    rcorr = r-((r-1)**2)/(n-1)
    kcorr = k-((k-1)**2)/(n-1)
    return np.sqrt(phi2corr/min((kcorr-1),(rcorr-1)))

 This function takes two array-like arguments for two attributes whose mutual correlation is being checked and returns a real number between 0 and 1, 0 signifying no correlation and 1 signifying a high correlation, with a continuous gradation in between. The results of using this to find correlations of other attributes with the success attribute are in the first several lines of the following image:

The values above reveal that the advisor attribute has a medium correlation with success. It leads the pack anyway. This is to say that of all the attributes we have considered, the advisor that gave the advice is the strongest indicator of whether the advice will be a success or not. The advisor attribute is followed by durationtype, and then symbolname. There is something strange you will notice about the niftysentiment attribute. By itself it shows a significantly lower correlation (0.11) than if concatenated with the buysell attribute (0.19). This is not as strange as it seems. After all, a niftysentiment value of 1 will tend to make a buy advice succeed ( since Nifty index going up will probably help this  stock to achieve its target price too), but a sell advice fail, since in the latter case the movement may well lead to hitting the stop loss price for the sell advice ! This is why the niftysentiment attribute in combination with the buysell attribute is a better indicator, if at all, of success, than the niftysentiment by itself.

But is there an easier way to figure out that two attributes are correlated - something that gives you more insight? Let's fall back on school level probability for this. We learnt there that two events are correlated if they are not independent. Independence means is that the probability of one event is the same irrespective of the other having occurred or not. Let us check if in our dataset the frequency of a success depends on whether it is, let's say, a buy advice or a sell advice. What we are really talking about here is to check whether the total probability of success and the probability of success for buy advices is the same. One graphical way to check this is as in the image below:


The total probability of success can be estimated to be the total green area divided by the total area of the bars in the left-hand side plot above. This is the same as the area of the first bar (blue as well as green) divided by the total area of both the bars in the right-hand side plot. The value, as you can estimate, is around 0.5. Now the probability of success conditional to an advice being a buy advice, is estimated by dividing the green area in the first bar in the left plot with total area of that bar. It is clear that this value is also around 0.5. Similarly, the probability of success given a sell advice is also around 0.5. So, knowledge that it was a buy or sell advice made little difference to the probability of success. This means attributes buysell and success are almost independent not well-correlated, which vindicates the low value of 0.02 that we obtained earlier for the Cramer's V value.

One more way to check the same thing is revealed in the snippet below

Note how the total probability of success and the probability of success conditional to whether it is a buy or sell advice, are all almost the same value - around 0.5. Again this means that the buysell attribute and success of an advice are almost independent and hence not strongly correlated, corroborated by the low Cramer's V value of 0.02 for this case. The reader is urged to try out correlations of other attributes like symbolname etc. with the success attribute.

In the next blog we look at further preprocessing steps like binarizing the categorical attributes etc.

Friday, October 26, 2018

An example of using the traversible function in Functional Javascript

A slightly more elaborate example of using the traversible function in Functional Javascript


Overview

A fairly common operation on an array of elements may involve first performing asynchronous operations on each element and then doing something on the array as a whole, if the individual operations are all successful. An example adapted from real-life follows. The following code is first presented in vanilla, semi-functional Javascript.

const doSomethingForElementsThatSatisfyCondition = (arr,somefunc)=>{
    const promisesArr=[];
    arr.forEach(el=>{
         promisesArr.push(new Promise(elementSatisfiesCondition(el)))
    }
    return Promise.all(promisesArr).then(result=>{
        console,log(result);
        return result.filter(obj=>obj).forEach(somefunc);
     }).then(null, err=>{
           console.log(err);
     });
}

const elementSatisfiesCondition = el=>{
      return (succ,fail)=>{
              let sql = "select * from employee where id=$1";
              return db.any(sql,[el.id]).then(result=>{
                 if (el.salary > 10000) {
                    succ(el);
                 } else {
                      succ(false);
                 }
              }).then(null,err=>fail(err));
         }
 }

There's nothing wrong with the above code as such. But it lacks a 'compositional' feel. The entire code, including the promise tasks executes immediately, step by step, and there is no sense of first composing functions right till the very end, checking (while testing) that the structure of resulting objects is as expected (i.e. inspecting the result functors and checking that their nesting etc. is as expected) before the action code actually executes. Of course, this has also to do with the fact that we are using Promises, and Promises behave that way. But also notice how we are also saddled with the task of converting an array of Promises to a single Promise, which is what the Promise.all call does in doSomethingForElementsThatSatisfyConditionThis is not something we should have had to do, since it smells like an application independent, generic concept, which as it turns out, it is.

Now look at this. Nothing except composition happens till the 'fork' method call is made. And very neatly an array (List) of Tasks is morphed into a Task of array (List) by the traverse call which is part of the functional Javascript infrastructure library (see here)

const doSomethingForElementsThatSatisfyCondition = curry((list,somefunc)=>{ return traverse(Task.of, elementSatisfiesCondition, list) .map(filter(m=>m)).map(forEach(somefunc)) .fork(err=>{ console.log(err); }, result=>{ console.log("Done .."); }); });

const elementSatisfiesCondition = el=>{
      return new Task((fail, succ)=>{
              let sql = "select * from employee where id=$1";
              db.any(sql,[el.id]).then(result=>{
                 if (el.salary > 10000) {
                    succ(el);
                 } else {
                      succ(false);
                 }
              }).then(null,err=>fail(err));
         });
 }

Saturday, October 6, 2018

Javascript Functional Programming as I understood it

Introduction

In recent times, the functional programming paradigm has attracted a lot of attention. As commonly understood, it is a paradigm that stresses on composing pure functions in order to achieve desired results. This is not to say that one behaves like a purist and completely avoids non-functional code like if blocks and assignments. Rather, and this is an opinion, the attempt is to restrict such non-functional code to the very bottom of the functional hierarchy, the bricks of the mansion, as it were, and reveal the grand design of the program as far as possible via function composition.

Acknowledgements

 All that I know about Functional Programming that I have elaborated in this post, is courtesy "Professor Frisby's Mostly Adequate Guide to Functional Programming". Here is the link to this masterpiece - 

https://github.com/MostlyAdequate/mostly-adequate-guide. 

This post unfortunately might also include what I have misunderstood from my readings, which are all my sole responsibility.

All examples in this post use the infrastructure library that is given in the appendices of the aforementioned book.

Side-effects and purity

We used the term 'pure functions' above. Pure functions are those that do not have any side effects, including ones that change (mutate) input arguments. This means that pure functions are much like mathematical functions. You pass 2 and 3 to an add function, and it will always return 5, no matter when or where. But as you can see, this restricts what can be done to largely CPU processing strictly on input arguments. No printing to files or terminals, no reading from files, no changing global state, no REST calls, no database operations, no DOM manipulation. In short, no doing anything useful ! Then what is it that goes for purity? You can test once and be sure it will work the same always. Since there is no state dependency, these functions can run correctly even in parallel. They are thus highly suited for use in code that is meant to horizontally scale on commodity machines in a cloud. But what use is all this if they don't do anything useful? Yes, this needs to be addressed, and the way that it is done is by tucking away this impure part inside of standard constructs that are part of the code infrastructure libraries (comprising Functors, Monads and the like, that we shall encounter soon), and which the application developer never writes, or, when this is not always possible, the application developer is provided convenient mechanisms to localize, so that 'this necessary evil' is contained and controlled!

Functions as first class objects

A big pillar of functional programming is the 'functions are first class objects' feature of the coding language. You need to be able to do with functions what you can do with objects - assign them to variables, pass them as arguments to other functions , return them as return values from other functions, and
I might add, call methods on function objects themselves. This feature makes possible a whole lot of others, like currying, partial application of functions, function generation, function composition etc. This truly is a core requirement.
 Functions that take or return other functions are also called Higher order functions. So 'map' or 'filter' or 'sort' are higher order functions since they take as an input argument another function. The map takes a transform function, filter takes a filtering function, sort takes a comparator function. Curry and Bind are higher order functions since they take and return a function. Although we can't strictly generalize, these functions are usually part of the 'infrastructure'. They are the base on which our applications will be built. We need to understand how they work. We will rarely need to write them ourselves. Elaborating a little bit before time, the map function is a method of the Functor, that we shall see presently (but do see the point-free style below that expresses the same thing as a non-method). That leads me to a side story. When we say 'Functor', do we mean a class or an object? Remember this is not OOP. But if we are forced talk in terms of OOP, then (and with due apologies to those who disagree) I would compare the structures, like Functors, that we elaborate below, to generics in Java/C++.

Composition

We talked about function composition above. What we mean by that is generating the following  function, fg:
    which is a function such that fg(x) =  f(g(x))

fg is called a composition of f and g.
The input of f is obviously the output of g, and we are talking single input argument functions here.
 Let's look at an example. Suppose we have a sentence of words, that we first want to extract the words out from, then concatenate them back with a comma delimiter, and finally convert the alphabets to uppercase. The composed function that does this is:

 const finalFunction = compose(toUpperCase,toString,split(' '))
 const result = finalFunction("Just as a Bilwa fruit may be fully well known on close examination when it is placed on the palm of hand, so it is possible for man to acquire a thorough knowledge of this world as he is in direct contact with it.")

The value  in result will be 'JUST,AS,A,BILWA,FRUIT,MAY,BE,FULLY,WELL,KNOWN,ON,CLOSE,
EXAMINATION,WHEN,IT,IS,PLACED,ON,THE,PALM,OF,HAND,SO,IT,IS,
POSSIBLE,FOR,MAN,TO,ACQUIRE,A,THOROUGH,KNOWLEDGE,OF,THIS,
WORLD,AS,HE,IS,IN,DIRECT,CONTACT,WITH,IT.'

We use a toString() instead of a join() here since the latter means something else in relation to Monads as we'll see soon, and I don't want to confuse the reader.

Function generation

Suppose we want to define several functions that make a HTTP GET request to different servers. We can define as many functions to do our job, or more sanely, use the concept of function generation as in the rather contrived example that follows:

const httpGetGenerator = (baseurl)=>{
   return (path)=>http(baseurl+path)
}

const callAmazon = httpGetGenerator('https://www.amazon.com')
const callGoogle = httpGetGenerator('https://www.google.com');
callAmazon('/getBook/?name=Abhignyana+Shakuntalam") 
callGoogle('/search/?query=Kalidasa')

callGoogle and callAmazon are functions that we have generated by calling the generator function httpGetGenerator

Currying and Partial Function execution

 Suppose I define a function

const add = (x,y)=>x+y

And call it as follows

add("Kalidasa")

The value returned is "Kalidasaundefined". What has happened is that the function has been invoked with the undefined second variable initialized to undefined, and string addition results in the final value that we see.
 But suppose what we expected out of the invocation

add("Kalidasa")

is simply that it returned another function that we can later invoke with the remaining second argument? This is made possible by currying.

const add = curry((x,y)=>x+y)

Invoking curry with a function passed in as argument, results in a function being returned that can later be invoked with one or more of the arguments. If fewer than all arguments are passed in an invocation, then a function that takes rest of the arguments as input, is returned. So, if I say

add("Kalidasa")

it returns a function that can take one argument, the second one for the original add function. But if I say,

add ("Kalidasa", " from Ujjain")

the original function is completely invoked and the result is not a function but the string

"Kalidasa from Ujjain"

Similarly, if we invoke it like this we get the same result

 add ("Kalidasa")(" from Ujjain")

Currying is at the core of all the higher order functions that we will use. We will see that map, filter etc. that we use from the infrastructure are all curried functions.

Functor

A functor is a data structure, actually a higher data type, that defines a map function. That's it. That's the working definition. A functor can be thought of as a box which wraps the real data. The Javascript array is a common example of a functor. The map method on the functor takes a function that can take this real data as argument and the result of the function call wrapped in the same functor is what is returned by the map method. That is

F.of(x).map(f)    which is the same as F.of(f(x))  


where F is the functor enclosing the data x and f is the function passed to the map method.

Point-free style

 Some people prefer the point-free style. In the point-free notation, the same thing looks like:

map(f, F.of(x))   which is the same as  F.of(f(x)) again

What good are functors anyway? They help us write code that comprise only  function calls, avoiding the clutter caused by other syntactic constructs such as if conditionals to handle errors, async processing etc..

Pointed Functors

They are functors with the 'of' method ( which is pretty much all the functors that we will deal with). This method helps construct functors initialized with minimal default values. So you can construct a pointed functor in the following manner:

var X = F.of(x)

What does it mean to create a box around something?

 When we create a functor F x from a 'value', (actually a Type) x, we are making x part of some concept. A very visual example of a concept is a structure, such as when we put x in a List functor (the structure here is an array)

[x]

or in a Map functor

{"key1": x}

The 'contents' of a functor can be 'values' (actually Types) or functions. In order not to mix them up with infrastructure functions dealing with functors, like 'map', 'of' etc., let us refer to these functions as morphisms (from the book referred to above). Also, it may be mentioned that the generic term for the collection of data types that our morphisms act on and return, is 'Category'. The data types and morphisms that we mentioned before are called 'objects' of the Category. There is a whole branch of Math devoted to this subject which is a grand generalization of several branches. It is called Category Theory. In this scheme of things, the Functor itself can be see as a higher data type, that can be applied to other Types.

The identity morphism

'id' is a special morphism called the identity morphism. It returns whatever we 
pass to it as an argument. It is useful in proving theorems of functional programming. This theorem proving is useful when we have functional code and we want to prove certain things about the code behaviour. For example look at this trivial theorem, where f is a morphism. This is true irrespective of the value of f. It is an identity. This is a very trivial one, granted. But more complicated theorems like this, that hold for any morphism or data type can be used to prove code behaviour and such an exercise naturally gives us confidence about the  correctness of our program.

compose(id,    f)    ===    compose(f,    id)    ===    f;

Monad

Monad is a functor with the join and chain (also called flatmap) method. Examples of Monad are 'Either', 'Maybe', 'Task', 'IO' etc. The join method simply strips off the outermost Functor layer. The chain method is like map and takes an argument,f, which is the morphism that is applied on the Functor-enclosed value. Additionally, the join method is also called on the  resulting functor. For example

Task.of(IO.of(x)).join() = IO.of(x)

Task.of(x).chain(f) = Task.of(f(x)).join() = f(x)

 Functor examples

Maybe

One of the simpler examples of a Functor (Monad) is the Maybe functor. Often times, we need to process values that may be null, and our code then needs to put in additional processing for null value handling. This often leads to the 'forest' of the design intent of your code getting lost amid the 'trees' of conditionals meant for  null and valid value processing. An example follows:

  const getName=(obj)=>{
    if (obj)
     return obj.name;
    else
     throw new Error("undefined obj");
  }

 const uppercase = str=>str.toUpperCase();


 const capitalize = (str)=>{
    if (typeof str =='undefined')
      throw new Error("undefined");
    return str.toUpperCase();
 }

var a={};
console.log(getName(a));

This can quickly get complicated.

 const getProperty=(obj,property)=>{
      if (obj) {
         if (property) {
            return obj[property];
         } else {
            return new Error("undefined property");
          }
      } else {
            return new Error("undefined obj");
      }
 }
 try {
    getProperty(obj, "name");
 } catch(e) {
    console.log(e);
  }

 See how the important task of getting out the property value from an object is being obfuscated by rest of the code which checks for null/undefined etc. Now let us use  the Maybe functor, which leads to a much neater implementation avoiding clutter due to null checks.

const getName =(obj)=>{
    return obj.name;
 }
const uppercase = str=>str.toUpperCase();

const capitalize = (str)=>{
    return str.map(upperCase);
 }

var a = {};
compose(capitalize, map(getName),Maybe.of)(a);

//Alternately, if we define a different function 
// const capitalize1 = str=>{
//    return uppercase(str)
//  }
//Then we can call it like this 
// 
// Maybe.of(a).map(getName).map(capitalize1) 
//   or using the point free way (See the section on Either functor
//   for a definition of the point-free map function)
// map(capitalize1, map(getName, Maybe.of(a)))
//  or even
// compose(map(capitalize1), map(getName), Maybe.of) (a)
//  or even
// compose(map(compose(capitalize1, getName)),Maybe.of) (a)

This returns Maybe(undefined) if a or a.name is undefined or Maybe(<value>) if a is an object with a field 'name' and value <value>. The trick that the Maybe implementation employs is that whenever it contains (it's a 'box' after all) an undefined or null, subsequent processing on it, typically by calling map on it, will do nothing. Otherwise the map function works as expected, applying the morphism that it is passed, to the non-null value. To elaborate, in the last line of the above code, if a or a.name were undefined, then getName would return a Maybe(undefined), and this would go as an argument to function capitalize, whose line str.map(upperCase) would not call upperCase at all, because str is a Maybe containing an undefined.If we were to avoid wrapping 'a' with a Maybe functor, and directly called getName followed by the simpler function capitalize1 (coded in the comment above) on it, then the call to upperCase(str) would throw an exception, since str is undefined, and this condition would need to be handled by cluttering code in function capitalize1.

Either

While the Maybe functor (Monad) is good for handling null/undefined values gracefully, it only obviates the  need for null checks. Many times the need is for returning a 'good' and a 'bad' value, the latter when there is an error condition, so that different things can be done downstream based on what type of value is returned. In these cases it is often better to have separate functors for good and bad (errorneous)  values so that their conditional handling is automatically taken care of outside the main application code and inside the plumbing code that these functors provide out of the box. Here is where the Either functor comes in. It is a functor class with two sub classes - Right (for a good value) and Left (for a bad or error value).

Let's see how it is used. The example code below has a function getData making a REST request to a remote http server using the url passed as a function parameter. The url itself is generated by generateURL() which takes an argument, endpoint, that can potentially be undefined. In case it is undefined, we want getData to behave properly, yet the code should not seem too cluttered either.

//getData::string-> boolean
const makeServerCall = (url)=>{
  //... make http call
}

//generateURL:: string->Either
const generateURL = (endpoint)=>{
   if (validate(endpoint)) {
     return new Right(BASEURL+endpoint);
  } else {
     return new Left("endpoint error");
  }
}

//Based on the third argument which is an Either, the either function call below will call the  function
// passed in the first argument if the Either object is a Left, or the function passed in the second 
// argument if the Either object is a Right   


either(err=>console.log("ERROR", err),  makeServerCall, generateURL("/api/changesomething"))

//Alternately you can use composition and call ...
compose(map(makeServerCall), generateURL)) ("/api/changesomething")

The alternative using compose is interesting. You might wonder what happens if the generateURL call returns a Left object, which then goes as input to the makeServerCall function, but does it really? No. Don't forget the map. It actually goes as the second argument to the map function call ( map(makeServerCall) is a partial function invocation of map, which returns a function that then takes the Either object as input argument). The map function is itself defined as 
 
   const map =    curry((f,F)=>F.map(f))

In our example F is Left. And we know that Left.map() quietly returns the Left object on which it is invoked ( 'this' object), i.e. the same Left object. It's a bad object and map knows it should not do further bad things by applying the input function to it.

Identity

This is the simplest functor there is. It can be thought of as a transparent box around the real value. I have never used this in practice but it is used to state and prove theorems about functors and monads, which in turn can be used to reason about the behaviour of a functional program. Here are some examples of theorems (the accurate word here is identities )
These are some identities for functors

//    identity
map(id)    ===    id;

//    composition
compose(map(f),    map(g))    ===    map(compose(f,    g));

These are some identities for Monads

//    associativity
compose(join,    map(join))    ===    compose(join,    join);

//    identity    for    all    (M    a)
compose(join,    of)    ===    compose(join,    map(of))    ===    id;

List (Array)

  This is the functor equivalent of a Javascript array. It is traversible (sequence and traverse methods are defined) but not monadic (no join and chain methods)

Examples of its use are :

let l = new F.List([ "Jack Sparrow", "Black Pearl"])
l.map(F.Either.of)

result will be the functor
 List([Right('Jack Sparrow'), Right('Black Pearl')])

Map

   This is the functor equivalent of a Javascript Map. It is traversible (sequence and traverse methods are defined) but not monadic (no join and chain methods) and not pointed (no of method). An example of its use follows.

let m = new Map({name: "Jack Sparrow", location: "Black Pearl"})
let  mapOfList = m.map(str=>str.split(' '));

mapOfList will contain 
Map({name: ['Jack', 'Sparrow'], location: ['Black', 'Pearl']})

let result = m.map(F.Either.of)

result will be the functor
 Map({name: Right('Jack Sparrow'), location: Right('Black Pearl')})

 IO

The IO monad is typically employed to enclose synchronous IO tasks, such as accessing or changing an in-memory global cache.

Task

The Task monad is typically used to enclose results from asynchronous function calls such as results from a database query call.An example follows

let task = new Task((reject, resolve)=>{
                 db.any('select * from employee')
                      .then((results)=>resolve(results))
                      .then(null, err=>reject(err))
             });

The argument to a Task constructor is called the fork function. Note how in creating a Task we have only passed its constructor a definition of the fork function. The fork function code gets executed only when the fork method is actually called on the Task functor. This creates possibilities of deferring evaluation until the very end, and till then our functors and morphisms are simply getting composed. This also allows the fork function to be invoked on the same Task several times. The fork method is called like this:

task.fork(err=>console.log("Ouch"), results=>console.log(results));

It is only during the fork call that you are defining the resolve and reject functions. This pattern cleanly separates execution of the task from processing of the results of that execution. This is different from how a Promise behaves.


Promise

The Promise monad,  while very similar to a Task, is different in when the Promise task gets executed.

let promise = new Promise ((resolve, reject) =>{
                      db.any('select * from employee')
                         .then((results)=>resolve(results))
                         .then(null, err=>reject(err));
                      });

Here there is no deferring. The function passed to the Promise constructor executes right away. So it is not convenient for composition and deferred execution.
Note that the then function of a Promise behaves like a chain method in that if the function passed in the then call returns a Promise, 'then' still returns an object couched in only one Promise box.

Stream

Compose

The Compose functor marks its contained value as a Functor composition - that its value is actually a nested functor - a functor within a functor. For example, we can create a Compose functor by passing F.of(G.of(x)) to its constructor. This creates a functor
   Compose F G x
What good is this? The map method on the Compose functor is defined to ensure that the morphism passed to the map function will execute on the value x deep inside. How is this? The map method of Compose is defined as:

  class Compose {
     ...
     map: (f)=>{ return map(map(f), this.$value)}
  }

which ensures that f is finally executed with x as argument.
So if we want to create a Compose out of a functor F G H x, then this would do it

let c = Compose.of(F.of(Compose.of(G.of(H.of(x)))))

See how c.map(f) will actually call f on x?

Applicative Functor

 An applicative functor is a pointed functor with an ap method. Why do we require it when we already have map and chain (the latter for monads)? Let us discuss this with an example. Suppose our requirement is to call a function passing two values one obtained after an (asynchronous) http call, and another obtained after an asynchronous database call. The function (morphism) signatures are:

//getNameFromServer::url->Task Either n
//getDetailsFromDatabase::place->Task Either d
//printPersonInfo::name->details->IO

getNameFromServer(url).map(map(n=>{getDetailsFromDatabase(place).map(map(d=>{printPersonInfo(n,d)}))})

This returns a deeply nested Task Either Task Either IO functor. Moreover all three functions are called sequentially. As against this, if we used the ap method, this is what we could do

Task.of(printPersonInfo)
.ap(getNameFromServer(url).chain(eitherToTask))
.ap(getDetailsFromDatabase(place).chain(eitherToTask))

This returns a Task IO  functor. Moreover, getNameFromServer and getDetailsFromDatabase can run concurrently.

Natural Functor transformation 

A natural transformation is a morphism between functors. It is a function that operates on containers themselves. Only those natural transformations are allowed that do not lose information. So, 

ioToTask  is allowed but not

taskToIO 

since converting a potentially asynhronous task abstraction to a deterministic and synchronous one results in loss of information. Other examples of principled transformations are 

maybeToArray, idToMaybe, eitherToTask etc.

Lenses


Traversible Functor

A traversible functor B is one that has the sequence and traverse methods defined on it.
In the attempt to get rid of complicated control structures and make our code flow with only function calls and function composition, we return functors and monads from functions, which then have to be consumed by other code, leading to deeply nested functors, much like the Russian dolls, one inside another, with the real value of interest couched deep inside the innermost functor. An example will make this clear.

  // f:: x-> A a
  // g::x ->B b
  // h::x ->C c

  let fn = compose(map(map(h)),map(g),f)

  fn(x) // Returns  A B C c, and the value c is now 3 levels deep !

 In case B and C are the same or A and B are the same, then some of the functor layers can be merged if they are Monads and therefore have the chain (also called flatmap) or join methods defined on them. For example if A and B were actually both same, say A then we could say

   let fn = compose(map(h), join, map(g), f) // returns A C c  

   or you could go

   let fn = compose(map(h), chain(g), f) //returns A C c

Another mechanism to curb the nesting hell, which sometimes works, is to use natural transformations from one functor to another. Several such exist like:

    eitherTotask, ioToTask, promiseToTask, maybeToTask, idToIO, idToMaybe

So, in the above example, if there was a natural transformation from C to A (named cToA), then the return value would reduce to just A a, by doing:

let fn = compose(chain(cToA),map(h), chain(g), f)  //returns A a

//Here we are still assuming A and B are the same

But a natural transformation may not exist where we want it. For example there is none from Task to IO (although the reverse transformation is available). So what do we do if we have a 'IO Task a'? It is simple, just use

     ioToTask(Ix).join()  where Ix is the 'IO Task a' object.

This gives 'Task a'

There are other situations that are more tricky. Suppose we have an applicative functor case where the applicative functor is
   A f
and this is to be applied on another nested functor like
  B A a

 We can't use the ap method of A directly, since the argument to ap requires a functor A, not 'B A'. But all is not lost, provided B is what is called a traversible functor.

Suppose  x is a nested functor, B A a , where B is traversible and A is an applicative functor

then
 F.sequence(A.of, x) is a functor A B b  // A and B flip
and
if y is the functor B b, and suppose func is a function that takes b and returns  a functor like A a, then

 F.traverse(A.of, func, y) = A B b

Calling traverse is much like first calling map ( with a function func that returns a functor)

    map(func,y) = B func(b) //which is functor B A a
and then applying sequence to the result
   F.sequence(A.of, B A a)  //which is functor A B b
So, assuming x is functor B b, and func is a function that takes b and returns functor A a,
 F.traverse(A.of, func, x) = x.map(func).sequence(A.of)

Examples of traverse follow:

Assume that fromPredicate is a function that takes a function f as first argument and a functor as second argument. f is a function  that  returns a F.Left or a F.Right functor object based on the argument to it. Finally, arr is an array (functor)

//fromPredicate::(b-> boolean)->( b -> A a)  or
//fromPredicate::(b-> boolean)-> b -> A a  (we use currying after all!)

traverse(Either.of, fromPredicate(f), arr)  = arr.map(fromPredicate(f)).sequence(Either.of) or which is the same thing

sequence(Either.of, map(fromPredicate(f), arr))

Another example shows that we have an all or nothing behaviour with traverse when the .applicative functor is an Either. The traversible functor in this case is a List. Calling traverse returns an Either err [x,x,x,...]

var frompred = curry((f,b)=>{if (f(b)) return new Right(b); else return new Left(b);})
arr = new List([9,10,8,90,76,1,-1])
var f = a=>a>10
var g = a=>a >-2
arr.traverse(Either.of, frompred(g))
//outputs Right(List([9, 10, 8, 90, 76, 1, -1]))
arr.traverse(Either.of, frompred(f))
//outputs Left(-1)

Let's discuss some differences and similarities between chain and traverse. Assuming that the traversible functor is also a monad ( like Identity, Maybe, Either), both chain and traverse called on such a functor, involve applying a function to the contents of the functor. This application returns another functor, so now we have the real value couched in the innermost of two functors, one in another. The chain method can additionally merge the two functors, which need to be the same for this merger to be valid.  The traverse method interchanges the two functors instead, and this is what is required to address the 'nesting hell' in some cases. The following link gives a more elaborate example.





Saturday, April 1, 2017

Configuring your own docker image for Meteor app deployment

This blog assumes a post 1.4 Meteor app, and its cloud deployment using the mup tool (Please see  this for npm download and find the code on https://github.com/zodern/meteor-up). Also see this for deployment on Digital Ocean using mup, although it is a bit dated. For example mup.json file has changed to mup.js and some of the json structure in there also differs.

The way that mup loosely works is that it compiles and tar-zips your application code, uploads it over to/opt/onlinetesting1/tmp on your cloud machine in addition to the docker run script to be run. On the cloud VM, the script (built by mup from mup.js) when run takes as an installation base, the docker image abernix/meteord (settable in mup.js) by pulling it from docker hub (e.g. download using 'docker pull abernix/meteord' command if you have docker installed on your machine, to get a feel), and finally runs the docker image with a volume mapping from /opt/onlinetesting1/tmp on the host machine ( your cloud VM) to /bundle in the docker container, and also passing various docker container environment settings for mongodb MONGO_URL and port, application server port, application name, meteor ROOT_URL etc.. The docker image 'entry point' was itself configured a priori (by the author of abernix/meteord) to run the meteor app server start up script when a container is created and run from the image. The docker run script is uploaded by mup to /opt/onlinetesting1/config/ on the host VM.

mup has a single point method of specifying the above settings as also all settings for the tool to log into the cloud VM using ssh. That single point is the mup.js file. Please see this for details. Please refer to  this to know how ssh login to your cloud VM works using an ssh-keygen authored digital certificate from your machine.

As happens very often, the above procedure didn't work OOTB for me. The docker image abernix/meteord comes with node 4.x and phantomjs 1.9.x preinstalled. But our meteor app for Online testing had problems with phantomjs 1.9.8.
 You may ask why we couldn't take the route of simply installing our version of phantomjs (2.1.1) into our cloud-installed docker container. The issue here is that even if we saved the container locally back to the image, the latter would get overwritten the next time we did a 'mup deploy' to deploy our new changes.

Here is what worked for me finally - create my own base docker image from abernix/meteord with pantomjs 2.1.1 (and vi editor !) installed. Then upload it to docker hub. Here are the steps :-

Create a folder called anything - 'dockerstuff' may be - somewhere. Then create a file called 'Dockerfile' in that folder. Also create a 'script.sh' file with the following code, in that folder.
#!/bin/bash

while true; do
    read -p "Give a y/n input"  yn

done

Don't forget to change its permissions to 777. Why a script that stops by expecting input ? Because we are going to keep the container alive by tying it with a process that potentially doesn't end. This is because we want to do something useful by opening a bash shell on the container, next, and we can't do that if the container has already finished with its start up script and stopped. There are probably other, even easier ways to do this, but this way works too. For other options see for example, this. Now put the following lines to execute the startup script, 'script.sh' in Dockerfile

FROM abernix/meteord:base
ADD script.sh / 
ENTRYPOINT /script.sh 
The ADD command adds the script.sh from the host into the / (root) folder of the container. The ENTRYPOINT command changes the startup process from the one for which the parent image (abernix/meteord) is configured to our simple one from script.sh.

Now build your image. At the shell prompt type

docker build -t test:base .
This creates a new image with the above entry point, but based otherwise on abernix/meteord.
To see a listing of all docker images, type
docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
test                         base               b30086a9e634        23 seconds ago        645 MB

abernix/meteord              base                edaae2ab7250        2 weeks ago         514 MB
Run the image b30086a9e634  to start a new docker container.
docker run -d  b30086a9e634
Here -d is for starting the container in the background. To see the container id type
docker ps -s
You get a listing like this
CONTAINER ID        IMAGE             COMMAND                  CREATED             STATUS              PORTS                        NAMES               SIZE
fecae970f27b        test:base   "/bin/sh -c /scrip..."   21 seconds ago        Up 21 seconds         0.0.0.0:80->80/tcp           quirky_allen      824 B (virtual 514 MB)

Create an interactive shell in this container

docker exec -it fecae970f27b bash
Now you are in a shell of the container, and as root user !
Remove all old phantomjs links and installations
rm -r /usr/local/bin/phantomjs /usr/bin/phantomjs /usr/local/share/phantomjs /usr/local/share/phantomjs-1.9.8-linux-x86_64
 Install latest phantomjs (it is 2.1.1 as of now)
npm install -g phantomjs-prebuilt
Install whatever else you want. For example, I installed the vi editor.
Exit the shell
exit
 Now you are back to you host machine shell prompt.
First thing, save your changes to the image.
docker commit fecae970f27b test:base
Now create your new image by now specifying test:base as parent in Dockerfile but reverting to the original entry point from abernix/meteord
 FROM test:base 
ENTRYPOINT bash $METEORD_DIR/run_app.sh

Then create the image. Lets call it ssashita/testjha
docker build -t ssashita/testjha:base .
Then check that the ssashita/testjha:base image got created by running
docker images

Now we have an image that has the correct version of phantomjs. We now need to upload this on docker hub so that mup tool can pull it from the cloud VM.
For this I first need to login to my docker account (create one if you don't have one, and follow along on the site and create a public repository. It's easy).
docker login --username=ssashita

Now push the image to your dock hub account
 docker push ssashita/testjha 
 This might take a while to finish.

Next go to your app deploy folder ( mine is .deploy under the app root). Edit the mup.js file.
Change docker.image to "ssashita/testjha:base" (from abernix/meteord:base).

That's it. Follow rest of the instructions in this to complete the cloud deployment. For example you will need a
mup setup
followed by
mup deploy 


Sunday, January 8, 2017

Bayesian Networks - part 1

 Imagine this very common situation. You have to go to the movies after office. There is a 50% chance you will get delayed at work. There are 3 routes A, B and C for you to get to the cinema hall from your office, and you are likely to take them with probabilities 0.4, 0.2 and 0.4 respectively.
Whether you reach the cinema hall on time or not, depends on whether you got delayed at work and which route you took. The probabilities of reaching on time or not vary as in the table



You have different queries to make. For example, given that you left work late but still reached on time, what is the route you are most likely to have taken ? Or, given that you chose route C, what is the likelihood that you reached the cinema hall on time ? Or, given that you started late and took route C what is the likelihood that you reached the hall on time ?
 The answers to these questions can easily be answered by constructing a Bayesian network for the problem. This is how the network looks like.

For every node you specify the probability values. For the 'LeaveOffice' node variable you specify the two probability values for leaving office late and on time (50%). For the 'RouteTaken' node you specify the probability values for routes A, B and C (0.4,0.2  and 0.4). Finally for the 'ReachOnTime' node variable you specify the probability values conditional to joint of the LeaveOffice and RouteTaken events, as in the table above.
 An analysis of this network gives the following answers to our questions.
Q1. Given that you left work late but still reached on time, what is the route you are most likely to have taken ?
The answer is C, which is clear from the output of the analysis


Q2. Given that you chose route C, what is the likelihood that you reached the cinema hall on time ?
The answer is 50%.


Q3. Given that you started late and took route C what is the likelihood that you reached the hall on time ?
The answer is 40%


There are many other questions like these that the Bayesian net can answer.

Output images taken using the  UnBBayes software. ( UnBBayes is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public Licence as published by the Free Software Foundation, either version 3 of the license, or (at your option) any later version. )

Is this stock advise worth taking seriously?

 Introduction Business related TV channels and newspapers are replete with stock advisory from investment firms and certified individua...