Wednesday, July 29, 2015

El pitch de Pixar

En el libro "To Sell is Human", Daniel Pink presenta una técnica para contar historias de forma efectiva.

Esta técnica se basa en la narrativa que comparten las películas de Pixar. El hecho de referirse a Pixar no es casualidad. Todas las películas de Pixar son un éxito en taquilla por lo que merece la pena analizar qué es lo que hacen bien. Según Emma Coats, guionista de Pixar, todas las historias siguen la misma estructura:

Érase una vez (Once upon a time there was) ...
Todos los días (Every day), ...
Un día (One day), ...
Debido a eso (Because of that), ...
Debido a eso (Because of that), ...
Hasta que por fin (Until finally), ...

Por ejemplo, podemos ver como el guión de la película Buscando a Nemo sigue esta estructura:

1. Érase una vez... un pez viudo, llamado Marlin, que era muy protector con su único hijo , Nemo.
2. Todos los días... Marlin advertía a Nemo de los peligros del océano y le imploraba que no nadara lejos.
3. Un día... en un acto de desafío, Nemo ignoró las advertencias de su padre y nadó en mar abierto.
4. Debido a eso... es capturado por un buceador y termina en la pecera de un dentista en Sydney.
5. Debido a eso... Marlin se embarca en un viaje para recuperar a Nemo, con la ayuda de otras criaturas del mar por el camino.
6. Hasta que por fin ... Marlin y Nemo se encuentran, vuelven y Nemo aprende que el amor depende de la confianza.

Según Daniel Pink, podemos usar esta misma estructura para contar nuestras propias ideas y proyectos de forma efectiva y diferente.

Thursday, May 21, 2015

Prueba empírica del problema de Monty Hall

El problema de Monty Hall es un problema matemático bien conocido (es.wikipedia.org/wiki/Problema_de_Monty_Hall).

En este post voy a mostrar un simple programa para los incrédulos que aún piensen que la solución no es correcta.

Este tipo de problema consiste en los siguiente:

En un concurso, nos muestran tres cajas, donde en una hay escondido un premio y las dos restantes están vacías.

El presentador pide que seleccionemos una caja. A continuación, de las restantes cajas, el presentador abre una de ellas, la abre y muestra que está vacía.

En ese momento nos pregunta si queremos cambiar de caja.

¿Qué responderías?

En el momento de tomar esta decisión, hay dos cajas cerradas y sabemos que en una de ellas está el premio. La intuición nos dice que la probabilidad de que el premio esté en nuestra caja es del 50%.
Por lo tanto, cambiemos o no de caja, la probabilidad de llevarnos el premio será del 50%.

Pero esto no es correcto. Si cambiamos de caja, la probabilidad de acertar es aproximadamente del 67%

Aparentemente no tiene sentido, ¿no?.

Si en el momento en el que tenemos que tomar la decisión de cambiar o no de caja, viniera una persona que no ha visto lo que ha sucedido y se pusiera en nuestro lugar, la probabilidad de que se llevara el premio en ese caso sí sería del 50%. ¿Cómo puede ser que si cambiamos de caja aumente la probabilidad de ganar el premio?

La respuesta es muy sencilla. Cuando tenemos las tres cajas, la probabilidad de que el premio se encuentre en la caja que hemos seleccionado es del 33% (1/3). Sin embargo, la probabilidad de que el premio se encuentre en alguna de las cajas que no hemos seleccionados es del 67% (2/3).

Cuando el presentador muestra una caja vacía, la probabilidad de que el premio esté en la caja que hemos seleccionado sigue siendo del 33% y la probabilidad de que el premio se encuentre en alguna de las cajas que no hemos seleccionado también sigue siendo del 67%. Pero ahora el resto de cajas que no hemos seleccionado es una, ya que el presentador ha abierto la otra. Por lo tanto, cambiar de caja hace que la probabilidad de llevarnos el premio pase del 33% al 67%.

La persona que viene de fuera no tiene tanta información, no sabe que antes había tres cajas y que el presentador ha abierto una de las cajas que no tenía el premio. Es esta información lo que hace que nuestra probabilidad de llevarnos el tiempo sea del 67% frente al 50% que tiene la persona que viene de fuera.

Una forma sencilla de ver esto, es imaginar que en vez de tres cajas, hay 1000 cajas. En este caso, igual que antes, seleccionamos una caja y el presentador, a continuación, abre 998 cajas mostrando que están vacías. En este momento estamos en el mismo caso que antes, tenemos dos cajas y en una está el premio. ¿Cambiarías ahora de caja?. Seguro que sí, ¿no? La probabilidad de haber seleccionado la caja con el premio a la primera de entre 1000 cajas, es bastante baja.

Para los incrédulos, aquí he hecho un programa en Java que simula este concurso y lo prueba:

import java.util.Random;

public class ChangeVariable {
  private boolean boxes[];
  
  private int boxWithTheBall;
  private int shownEmptyBox;
  private int boxSelectedByPerson;
  
  private Random rnd;
  
  public ChangeVariable(boolean changeBox) {
    rnd = new Random();
    
    start(changeBox);
  }
  
  private void putBallInBox() {
    boxWithTheBall = rnd.nextInt(3);
    boxes=new boolean[3];
    boxes[boxWithTheBall]=true;
  }
  
  private void showEmptyBox() {
    do {
      shownEmptyBox = rnd.nextInt(3);
    } while (
        shownEmptyBox==boxWithTheBall ||
        shownEmptyBox==boxSelectedByPerson);
  }
  
  private void selectBox() {
    boxSelectedByPerson = rnd.nextInt(3);
  }
  
  private void changeBox() {
    for (int i=0;i<3;i++) {
      if (i!=shownEmptyBox && i!=boxSelectedByPerson) {
        boxSelectedByPerson = i;
        break;
      }
    }
  }
  
  private boolean isGuessed() {
    return boxSelectedByPerson==boxWithTheBall;
  }
  
  private void start(boolean changeBox) {
    int iterations = 100000;
    int hits=0; 
    
    for (int i=0;i<iterations;i++) {
      
      // Put a ball in a box
      putBallInBox();
      
      // The person selects a box
      selectBox();
      
      // Show an empty box which
      // is not the selected by the person
      showEmptyBox();
      
      if (changeBox) {
        // The person changes the box
        changeBox();
      } 
      
      if (isGuessed()) hits++;      
      
    }
    
    System.out.println("Hits: "+(hits/(float)iterations));
  }
  
  public static void main(String args[]) {
    boolean changeBox = false;
    
    new ChangeVariable(changeBox);
  }
}

Cuando lo ejecutamos con changeBox=false (no cambiamos de caja), la probabilidad que sale será algo parecido a 0.333 que corresponde al 33% (1/3) que matemáticamente corresponde.

Sin embargo, cuando lo ejecutamos con changeBox=true (siempre cambiamos de caja), la probabilidad que sale será algo parecido a 0.666 que corresponde al 67% (2/3) que acabamos de ver.

Sunday, April 26, 2015

Encontrando gente con el mismo cumpleaños

Hace algunos meses escuché en un programa de Redes que la probabilidad de que en una fiesta haya dos personas que cumplan años el mismo día es bastante alta. A priori, esto choca un poco. Por lo general, de forma intuitiva, diríamos que esa probabilidad es bastante baja. El motivo podría ser que consideramos esa probabilidad similar a la de encontrar en una fiesta alguien que cumpla años el mismo día que nosotros. Sin embargo, ambas probabilidades no tienen nada que ver.

Para calcular la probabilidad de que en una fiesta de N personas existan dos personas que cumplan años el mismo día, podemos pensar en 365 vasos y N bolas colocadas en alguno de esos vasos al azar. La probabilidad es la misma que 1 menos la probabilidad de que en los 365 vasos haya como máximo una bola. Es decir, la probabilidad de que en algún vaso haya más de una bola (al menos dos personas con el mismo cumpleaños).

La probabilidad sería 1 - 365!/exp(365,n)*(365-n)!

En base a esta ecuación, en una fiesta con 20 personas, la probabilidad de que haya dos personas con el mismo cumpleaños es del 41% y en una fiesta con 50 personas, esta probabilidad es del 97%. Es decir, casi con total seguridad, en una fiesta medianamente grande, va a haber al menos dos personas que cumplen años el mismo día.

Por otro lado, la probabilidad de que cuando llegamos a una fiesta con N personas haya al menos una persona que cumpla años el mismo día que nosotros, se puede calcular como la probabilidad de que al colocar N bolas al azar en 365 vasos, no haya ninguna en el vaso donde está nuestra bola.

La probabilidad sería 1 - exp(364/365, n)

Por tanto, que en una fiesta con 20 personas haya alguien que cumpla años el mismo día que nosotros es sólo del 5%, mientras que en una fiesta con 50 personas es del 13%.

Friday, January 23, 2015

Cómo usar el plugin Database Migration de Grails

A continuación describiré una manera de trabajar con el plugin Migration de Grails basado en Liquibase que me resulta especialmente cómoda. La diferencia respecto a la del manual es que podemos seguir trabajando en local con el modo dbCreate=create-drop sin necesidad de tener en cuenta las migraciones hasta el momento del pase a Producción.

Supongamos que tenemos nuestro modelo de datos en local (con dbCreate=create-drop) y es la primera vez que se va a instalar en Producción. Lo primero que hacemos es detener la aplicación en local, y generar el changelog inicial de la siguiente forma:

grails dbm-generate-gorm-changelog changelog.groovy

Esto generará el fichero changelog.groovy en /grails-app/migrations

En este caso, al estar nuestro entorno local en modo create-drop, cuando se ejecuta este script se creará el esquema tal como refleje las clases del dominio en ese momento.

Para instalar por primera vez en Producción, simplemente haremos contra Producción grails prod dbm-update y se creará el mismo esquema de base de datos que tenemos en local.

Obviamente, en Producción dbCreate debe estar comentado porque queremos que el esquema se cree y actualice mediante changelogs y no de forma automática.

En este momento los esquemas en local y en Producción serán iguales.

Seguimos nuestros desarrollos en local, creando y modificando clases de dominio sin preocuparnos de nada, ya que estamos en modo create-drop.

Llegado el momento, decidimos migrar el esquema modificado a Producción. Lo que queremos es aplicar únicamente los cambios, por lo que tenemos que obtener en primer lugar el changelog de los cambios. Para ello, simplemente comentamos el dbCreate para que no se autogenere el esquema a partir del dominio, y borramos el esquema local mediante cualquier cliente de base de datos (el esquema debe quedar vacío, sin ninguna tabla).

Con estas premisas, ejecutamos en local grails dbm-update, asegurándonos que en grails-app/migrations está el changelog.groovy que se ejecutó en Producción. Esto hará que nuestro esquema local sea en ese momento idéntico al de Producción que queremos actualizar.

A continuación hacemos grails dbm-gorm-diff updates.groovy. Esto generará el changelog con las diferencias entre el modelo local (dominio) y el esquema copia de Producción, que será precisamente lo que haya que ejecutar en Producción.

Los cambios contenidos en el fichero que se acaba de generar grails-app/migrations/updates.groovy los copiamos en changelog.groovy y ejecutamos contra Producción grails prod dbm-update. Esto hará que se apliquen los cambios quedando Producción actualizado.

Por último, en local volvemos a descomentar dbCreate dejándolo de nuevo en modo create-drop para seguir trabajando de forma cómoda en local.



Tuesday, September 23, 2014

¿Cómo funciona this en JavaScript?

En JavaScript, comprender el funcionamiento de this en las llamadas a funciones no suele ser sencillo al principio. Sin embargo, si se entiende lo que internamente hace JavaScript en las llamadas a funciones, todo queda más claro:

Cuando se llama a una función:

foo('hola')

internamente es como si se hiciera lo siguiente:

foo.call(undefined/window, 'hola');

Por otro lado, si se llama a una función perteneciente a un objeto:

objeto.foo('hola')

internamente es como si se hiciera lo siguiente:

foo.call(objeto, 'hola');

El primer parámetro de call es el valor de this dentro de la función. En modo estricto (strict mode), el valor pasado como this será undefined, mientras que en modo no estricto, será el objeto global (objeto window en cualquier navegador).

Teniendo esto en cuenta, veamos lo que pasaría con un objeto como el siguiente:

var person = {
    firstName: 'Isidro',
    sayHello: function() {
        console.log("Hello, I'm "+this.firstName);
    }
}

Si hacemos:

    person.sayHello();

Por consola se mostrará "Hello, I'm Isidro". En este caso, internamente se ejecuta algo como:

    person.sayHello.call(person);
   
Por lo que this.firstName "sería" person.firstName

¿Qué pasaría si obtengo una referencia a la función del objeto y la llamo desde fuera en modo no estricto?

var f = person.sayHello;
f();

En este caso, por consola se pintará "Hello, I'm undefined"

Esto es porque internamente se ejecuta algo como:

    person.sayHello.call(window);
   
y por tanto, como en el objeto window no hay ningún objeto llamado firstName, muestra undefined.   

En este caso, si quisiéramos ligar la función con un objeto en particular, usaríamos bind:

    f = person.sayHello.bind(person);
   
Ahora al ejecutar la función devolvería:   

    f(); // Hello, I'm Isidro
   
¿Qué pasa con las funciones anónimas?

Supongamos que la clase person es ahora:

var person = {
    firstName: 'Isidro',
    sayHello: function() {
        function getCapitalizeName() {
            return this.firstName.toUpperCase();
        }
        console.log("Hello, I'm "+getCapitalizeName());
    }
}

y ejecutamos:

    person.sayHello();   
   
En este caso, se muestro por consola de nuevo: "Hello, I'm undefined"
El motivo se entiende claramente si traducimos la llamada a la función getCapitalizeName() por lo que realmente se está ejecutando:

    getCapitalizeName.call(window)

De nuevo, dentro de getCapitalizeName, this apuntará a window y como en el objeto window no existe el objeto firstName, devuelve undefined. No podemos pensar que como la función getCapitalizeName está definida dentro del objeto person, automáticamente this apunta a person.

Para que funcione tal como esperamos, podríamos llamar a la función getCapitalizedName de forma explícita:

    console.log("Hello, I'm "+getCapitalizeName.call(this));  

En este caso, mostraría: Hello, I'm ISIDRO

Saturday, August 9, 2014

Herencia Prototípica y AngularJS

A veces, aquellos que vienen de lenguajes con herencia clásica como Java, se encuentran con serios problemas cuando empiezan a trabajar con otros tipos de herencia como la prototípica de Javascript (Prototypal Inheritance). 

Un ejemplo es cuando se trabaja con AngularJS y se usan directivas que crean scopes que heredan prototípicamente de su scope padre, en concreto, directivas como ng-include, ng-switch, ng-controller o directivas con scope:true. En estos casos, el desarrollo puede generar dolores de cabeza si no se entiende bien este tipo de herencia.

Veamos un ejemplo. Supongamos que tenemos una directiva como la siguiente:

directive('test', [function() {
    return {
     scope: true,
     template: '<input type="checkbox" ng-model="active"></input>'
    };
}])

En este caso, la directiva crea un nuevo scope que hereda prototípicamente del scope padre.

Supongamos que tenemos un sencillo controlador como el siguiente:

controller('TestCtrl', ['$scope', function($scope) {
$scope.active=true;
}]);

Si nuestro template es el siguiente:

<div ng-controller="TestCtrl">
<div test1></div>{{active}}
</div>

Vemos que cuando ejecutamos la aplicación, aparece el checkbox marcado y bajo él la palabra true como era de esperar, ya que en el controlador la variable active se inicia a true.

Hasta aquí todo bien. Pero, ¿qué pasa cuando desmarcamos el checkbox?  ¡Sigue apareciendo true debajo del checkbox!

¿No debería cambiar la vista adaptándose al valor actual? Pues sí, pero aquí entra en juego la herencia prototípica que complica un poco las cosas.

La herencia prototípica tiene la siguiente peculiaridad: para leer siempre se recorre la cadena de prototipos hacia arriba hasta encontrar la variable, mientras que para escribir no se recorre, por el contrario, se escribe en el objeto (scope) actual.

Lo que realmente está pasando es que tenemos dos scopes, uno el del controlador (S1) y otro el de la directiva (S2) que hereda prototípicamente de S1:

S1, que es el scope asociado al controlador (TestCtrl), incluye la variable active=true.
S2, que es el scope asociado a la directiva, no incluye esa variable.

Cuando se ejecuta la aplicación, la directiva enlaza el valor del checkbox con la variable active del scope. Pero, ¿de qué scope? pues del scope de la directiva. En este caso, intenta leer el valor de la variable active en el scope S2. Como en este scope no está definida, siguiendo las reglas de la herencia prototípica, busca en el scope padre S1 donde sí se encuentra y se muestra el checkbox marcado. Por otro lado, en la vista se muestra true porque ésta va enlazada con el scope S1 del controlador.

Cuando desmarcamos el check, lo que se está haciendo es una escritura. De nuevo, se comienza por el scope de la directiva S2. Como antes, en este scope no se encuentra la variable active y, aquí surge la confusión, se crea una nueva variable active con el estado false en S2.

En este momento hay definidas dos variables active, una en S1 con el valor true y otra en S2 con el valor false. La nueva variable active de S2 es la que a partir de ahora estará asociada al checkbox y la S1 seguirá asociada al controlador (vista). Es por ello, que en la vista aparece true ya que realmente la variable que se está leyendo para formar la vista es la de S1.

Si volviéramos a marcar el checkbox, el proceso sería el mismo, quedando en este caso la variable active de S2 con valor true, el checkbox marcado y en la vista la palabra true proveniente de la variable active del scope S1.

Una forma para evitar este tipo de problemas es usar variables accedidas por referencia en vez de por valor. Pero esto lo veremos en otro post otro día.

Wednesday, August 6, 2014

Java implementation of the Travesty algorithm

Some days ago I wrote a Java implementation of the Travesty algorithm using a probability tree structure.

Travesty is a method for generating scrambled text using Markov chains.

This is a free interpretation of the Travesty algorithm by Hugh Kenner and Joseph O'Rourke discussed in BYTE November 1984 (www.scribd.com/doc/99613420/Travesty-in-Byte) based on the paper "Richard A. O’Keefe - An introduction to Hidden Markov Models".

As this paper (www.cs.otago.ac.nz/cosc348/hmm/hmm.pdf) says:

"A kth-order travesty generator keeps a “left context” of k symbols.

Here k = 3, one context is “fro”. At each step, we find all the places in the text that have the same left context, pick one of them at random, emit the character we find there, and shift the context one place to the left. For example, the text contains “(fro)m”, so we emit “m” and shift the context to “rom”. The text contains “p(rom)ise”, so we emit “i” and shift the context to “omi”. The text contains “n(omi)nation”, so we emit “n” and shift the context to “min”. The text contains “(min)e”, so we emit “e” and shift the context to “ine”. And so we end up with “fromine
”.

How is this a Markov chain? The states are (k + 1)-tuples of characters, only those substrings that actually occur in our training text. By looking at the output we can see what each state was. There is a transition from state s to state t if and only if the last k symbols of s are the same as the first k symbols of t, and the probability is proportional to the number of times t occurs in the training text.

A Travesty generator can never generate any (local) combination it has not seen; it cannot generalise"

As an example, using the first paragraph of "El Quijote" (in spanish) and k=3, the outcome are things as curious as the following:

"... de Quijada (que en su hay amigo de asta años, en la conjeturas más velludo parte, carnes, en los cincuentejas cuyo no que vierencia, duelos de caza. El recia, y una sobrina sobrina se de llero, algún para la narraciender que tenía el sobre semana que en la Mancha, y un punto; gran lugador y galga años, era. El rocín flaco y un hidalgún punto; gran mozo de cuyo no hay amigo de verdad ..."

As you can observe, the text is scrambled although it looks like a text with valid spelling and grammar.

You can download the source code from my GitHub: https://github.com/IsidroGH/Travesty