viernes, 12 de marzo de 2010

Code Bubbles

A través de Alarming Development he dado con el proyecto Code Bubbles, un soplo de aire fresco para el mundillo de los IDEs del que habla por sí solo el siguiente vídeo.

Su objetivo es proporcionar una forma ágil de trabajar con proyectos (Java en su demo) en los que el número de ficheros y funciones que dependen de otras en múltiples niveles hacen que se consuma mucho tiempo cambiando entre ficheros (¿habéis trabajado en un proyecto con ~100 clases?).

Si estuviese en producción yo querría probarlo. De momento, es posible solicitar participar en sus pruebas de beta.

En cualquier caso, me parece fantástico que se continúe investigando formas de mejorar los entornos de desarrollo como ésta, que derrocha creatividad. Sólo le veo una barrera importante de adopción que no sea fácil de solucionar puliendo los detalles y es que la curva de aprendizaje tiene que ser pronunciada.

Code Kata: cadenas de Márkov

El code kata de esta semana trata sobre las cadenas de markov, una herramienta matemática que acecha oculta en cursos de estadística o investigación operativa y que si visitáis la Wikipedia veréis que se utiliza para infinidad de cosas como la redacción de spam.

¿Qué es una cadena Márkov? No es más que un proceso estocástico en el que el último suceso nos aporta todo lo que podemos saber acerca de los siguientes sucesos o, en castellano llano, un generador aleatorio en el que el último resultado determina las probabilidades para el siguiente. Si además es homogéneo, de primer orden y el resto de cosas para no complicarnos demasiado podemos representar la cadena de Márkov como una matriz de n x n en el que P(i,j) nos marca la probabilidad de que j le siga a i.

Los que sigan leyendo esta entrada se preguntarán para qué puede ser útil todo esto y por qué no están escribiendo las memorias de sus prácticas, TFCs, documentación de su proyecto o alguna otra cosa útil o inevitable. Quizá no estéis perdiendo el tiempo, las cadenas de Márkov pueden utilizarse para generar textos de relleno tan incoherentes como los que deberíais estar escribiendo sin el riesgo de que alguien se de cuenta de que habéis copyshiteado media wikipedia. Para ello basta con tomar las palabras y signos de puntuación como los símbolos de salida de la cadena y entrenarla con un corpus de texto inicial (otros documentos o prácticas anteriores). Los resultados son fascinantes y pondré dos ejemplos.

Garkov es una tira cómica que se autogenera con cada visita. Se basa en un catálogo de tiras de Garfield de las que han borrado los textos y una cadena de Márkov que genera el texto. El resultado varía entre surrealista y plausible, podéis probar todo lo que os apetezca.


Garfield + cadenas de Markov = Garkov

El segundo ejemplo ha sido generado con una cadena de primer orden entrenada a partir de algunos documentos antiguos en los que he participado, es difícil juzgar si la causa del sentimiento de irrealidad es debido a la cadena o al corpus para entrenarla.

In this task is responsible for the planned work packages, Definition R it will also Coordinator will be used technical risk are described in the creation of technology for carrying out, to existing know how will is a common state of the two different concern within level of architecture of Lifecycle other cases.

A veces, el resultado puede dar miedo y/o ser poético:

Mashup platforms, family that involve human Embryos?

Code kata: cadenas de Márkov

Andrey Markov
El bueno de Andrey Markov

Volviendo al code kata, nuestro objetivo consistirá en implementar un generador aleatorio mediante una cadena de Márkov de primer orden (y no volver a tener que escribir relleno a mano).

El primer problema a resolver consistirá en la capacidad de convertir el corpus, en principio uno o varios ficheros de texto plano, en una secuencia de tokens que podrán ser o bien palabras o bien signos de puntuación. El punto y el final de fichero tendrán una función especial, marcarán el fin de la sentencia.

Este primer paso puede ser más o menos elaborado dependiendo del tiempo e interés que se quiera dedicar. En el mejor de los casos se deberían intentar preservar más información del fichero de entrada, como por ejemplo considerar una o varias líneas en blanco como otro fin de sentencia.

El siguiente elemento a resolver será la representación de la cadena, que en teoría sería una matriz cuadrada con todas las palabras de corpus como filas y columnas. Quizás se deba recurrir a alguna técnica para almacenar matrices dispersas...

Opcionalmente se puede considerar la carga y el almacenamiento de cadenas desde ficheros en disco para ahorrarse el proceso de entrenamiento de la cadena.

Finalmente se debe implementar la generación de texto.

Buena suerte y no dudéis en mirar la Wikipedia o rastrear Internet para reunir más información, es parte del ejercicio.

jueves, 11 de marzo de 2010

Actualizado Acerca de...

Hemos actualizado la nota acerca de.... Lectura obligada ;)

miércoles, 10 de marzo de 2010

Neologismo: Copy & Shit

Hoy quiero lanzar un neologismo al mundo: copy & shit. Se puede dudar si esta expresión tiene alguna ventaja sobre el típico y tradicional "copy & paste" aparte de desconcertar a la gente a vuestro alrededor. Mi argumento es claro, esta expresión es preferible cuando se está desarrollando código ya que nos pone automáticamente en guardia sobre los problemas que podemos introducir al copiar unas pocas líneas de una clase a otra. Es posible que esto nos lleve a pensar en extraer el código a una función o clase independiente o reflexionar sobre el diseño para evitar la duplicación de código.

El siguiente poster motivacional puede servir para hacer propaganda sobre este novedoso concepto. También podéis ser fans en Facebook!

Copy & Shit: because one bad programmer can create 2 new jobs a year

Asamblea de la Comunidad Morfeo

Logo aniversario Morfeo
Sí, es hotlinking, pero somos pobres :(

Se está celebrando ahora mismo (wow, live blogging) la tercera asamblea de la Comunidad Morfeo en cuyos proyectos tantos labos y exlabos hemos pasado. Los comentarios en tiempo real se pueden seguir mediante el tag #morfeo2010 en twitter y el mismo tag en flickr.

La jornada está resultado mucho más interesante y abierta a contribuciones externas que otros años, con presentaciones de mucha calidad. Me gustaría destacar un par de presentaciones que todavía estamos digiriendo: TIBI por Sergio Montero y ASOLIF por @Dakal (siento no haber anotado el nombre).

TIBI es una asociación de emprendedores de software e Internet que, como nos cuenta Sergio Montero, es una organización jóven, dinámica y que huye de la institucionalización y permite que sus socios emprendedores curen su soledad y compartan conocimiento. Por ejemplo, su última reunión trató sobre cómo posicionar productos software en España. Nos ha transmitido la visión y la ilusión de las pequeñas empresas tecnológicas y su esfuerzo por salir de salir de la España del 600 y la alpargata.

La presentación de ASOLIF, la asociación de empresas españolas del software libre, ha continuado de cierta forma con el tema de la nueva generación de empresas tecnológicas que está creciendo aún a pesar de la crisis (3%). Y todo esto llevando con honor la etiqueta frikipower como alternativa (y complemento) a las grandes empresas establecidas que quizás tengan más conocimiento sobre negocio que sobre tecnología.

Como muestra de pluralidad de pensamiento, ASOLIF se muestra reacia a creer en las certificaciones (línea de trabajo de Morfación) y apuestan por las guías y libros blancos.

Esto es todo por el momento, seguimos en la brecha

martes, 9 de marzo de 2010

Clone HashMap de HashMap

Si bien el otro día Sebas nos hablo del uso de las dobles llaves para sobrescribir el constructor de una clase anónima en java, no hemos tardado más de 2 días en necesitar usarlo.

El problema ha venido al intentar clonar un objeto del tipo HashMap con otro Map dentro. Esto se debe a que se intenta clonar un objeto que dentro tiene otro objeto, y para clonarlo se debe hacer la clonación por separado de dicho objeto.

Un modo de solucionarlo es declarar el tipo del Map que hay dentro del Map que se quiere clonar como final.Pero esto no siempre es posible.

El otro método que se nos ha ocurrido para solucionarlo ha sido emplear la inicialización de la doble llave, y el resultado ha sido algo de este estilo.

 HashMap cloned = new HashMap();

  for (Object key: reference.keySet()) {
    final Map map = reference.get(key);
    cloned.put(key, new HashMap() {{
      for (Entry entry: map.entrySet()) {
        put(entry.getKey(), entry.getValue());
      }
    }});
  }

Y esto es todo por hoy. Espero vuestras opiniones o soluciones alternativas.

domingo, 7 de marzo de 2010

Envidias...


Fotografía de JC Olivera

Los compañeros del laboratorio utilizamos o hemos utilizado muchos lenguajes de programación teniendo cada uno nuestras preferencias personales más o menos pasajeras. Esto da bastate pie a la comparación y a comprobar y desmentir tópicos.

Una comparación típica es Java vs lenguajes de scripting (Python, JavaScript, Perl) y qué cosas se echan de menos o se envidian cuando se programa en Java. Pongamos como ejemplo la cantidad de líneas que hacen falta para solucionar cualquier problema en Java comparadas con un poco de hacking en Python o Perl. Como explican en el Schneide Blog:

Quiz: Whats one of the most heard flaws of Java compared to other languages?
Bad Performance? That’s a long overhauled myth. Slow startup? OK, this can be improved… It’s verbosity, right? Right but wrong. Yes, it is one of the most mentioned flaws but is it really inherit to the language Java?

La entrada, que es muy interesante, termina concluyendo que la culpa no es del lenguaje Java sino del diseño de las bibliotecas. Quizás Python y Perl le deben tanto a sus bibliotecas oficiales y al CPAN como a su sintaxis.

Una característica my envidiable es la facilidad pasmosa con la que se crean hashes de hashes en los lenguajes de scripting y para muestra un JSON:

var a = {
    "rojo": { "fichas": [1, 3, 4], "nombre": "juan" },
    "amarillo": { "fichas": [22], "nombre": "pedro" }, 
}

Lo más parecido que tenemos en Java son las clases derivadas anónimas, también conocidas como Double Brace Initialization (suena a jugada de los hermanos Derrick).Para utilizarlo, tras invocar al constructor se añade código de inicialización entre dos pares de llaves. El efecto es una clase anónima derivada de la clase cuyo constructor se invoca y que lleva adosado al constructor las líneas extra que se quiera. Repitiendo el ejemplo anterior:

Map a = new HashMap() {{
    put("rojo", new HashMap() {{
        put("fichas", new int[] {1, 3, 4});
        put("nombre", "juan");
    }});
    put("amarillo", new HashMap() {{
        put("fichas", new int[] {22});
        put("nombre", "pedro");
    }});
}};

La verdad es que sigue siendo bastante más verboso que en JavaScript, pero es un avance... Además, podemos utilizar los generics para tener tipado estático mucho más concreto que en un JSON. ¿Tenéis alguna forma más cómoda de hacerlo? ¿Y otros trucos parecidos? Los comentarios son bienvenidos.

viernes, 5 de marzo de 2010

Joose: JavaScript OOP ¡Por fin!

Me estreno en este blog (muy tarde, lo siento) con una entrada acerca de un framework JavaScript que acabo de descubrir, que me parece va a estar presente en mis futuros desarrollos: Joose. Esta librería se centra en uno de los aspectos más pobres de JavaScript, la Orientación a Objetos.

¿Para qué otro framework más?


Existen en la red multitud de frameworks para facilitar la tarea del desarrollador Web (tarea, por otro lado, bastante ingrata sin el uso de alguno o varios de estos frameworks). En general, la mayoría de ellos se centran en facilitar el acceso al DOM, las llamadas AJAX, e incluso ofrecer un entorno para desarrollo de interfaces de usuario.  Sin embargo, Joose se distingue de sus alternativas por enfocarse en el área quizá mas pobre de JavaScript, la orientación a objetos. A pesar de que otros frameworks como Prototype o Dojo ofrecen sus propios métodos para conseguir "más o menos" orientación a objetos en JavaScript, ninguno se acerca a la funcionalidad y organización de Joose. Según los propios desarrolladores, Joose ofrece "orientación a objetos postmoderna" en JavaScript.

Características básicas


No os voy a aburrir con detalles de implementación o documentación exhaustiva (la página os puede proporcionar mucha información), pero os cuento cosas que me han sorprendido gratamente:

  • Mecanismos habituales en la OO, como herencia (múltiple), interfaces, clases abstractas, singletons, etc, pero bien hecho.
  • Getters y Setters automáticos
  • Paquetes (espacios de nombres)
  • Roles (interfaces con esteroides)
  • Filosofía cercana a la orientación a aspectos
  • Persistencia automática de objetos con el storage de HTML5 y (creo) con recursos remotos usando AJAX
  • Reflexión de código y otras cosas chungas que sólo Sebas comprende

Show me the code!


Como este viernes no hay kata, como ejemplo de código publico una solución parcial (lo demás lo implementáis vosotros para probar el framework) a la kata cuatro cuatros de hace un par de semanas.

Role (interfaz) Printable, que requiere implementar el toString:

Role("Printable", {
 requires: "toString"
});

Clase Abstracta Exp, con un método estático (de clase). Implementa Printable:

Class("Exp", {
 does: Printable,
 methods: {
  toString: function(){},
  count4: function(){},
  getValue: function(){}
 },
 classMethods: {
  findExpresion(number) {
   // Resuelvelo tu
  }
 } 
});

Clase Op, que hereda de Exp:

Class("Op", {
 isa: Exp,
 has: {
  _operand: {is: "rw"},
  _left: {is: "rw"},
  _right: {is: "rw"}
 },
 override: {
  toString: function() {
   return "(" + this._left.toString() + this._operand + this._right.toString() + ")"
  },
  count4: function() {
   return this._left.count4() + this._right.count4()
  },
  getValue: function() {
   var result;
   switch(this._operand) {
    case "+":
     result = this._left.getValue() + this._right.getValue();
     break;
    case "-":
     result = this._left.getValue() - this._right.getValue();
     break;
    case "*":
     result = this._left.getValue() * this._right.getValue();
     break;
    case "/":
     if (this._left.getValue() % this._right.getValue() == 0) {
      result = this._left.getValue() / this._right.getValue();
     } else {
      throw "ValueError";
     }    
     break;
   }
   return result;
  }
 }
});

Clase Num, que también hereda de Exp:

Class("Num", {
 isa: Exp,
 has: {
  _value: {is: "rw"}
 }, 
 override: {
  toString: function() {
   return this._value
  },
  count4: function() {
   var stringifiedNumber = this._value + "";
   return countOcurrences(stringifiedNumber, '4');
  },
  getValue: function() {
   return this._value;  
  }
 }
});

Por último,una pequeña prueba de unidad (se usa el console.log que ofrece Firebug). Además, una función auxiliar que siendo puristas habría que haber metido en una clase.

countOcurrences = function(text, character) {
   return (text.length - text.replace(new RegExp(character,"g"), '').length / text.length);
  }

var exp = new Op({ 
  operand: '-', 
  left: new Num({value: 44}), 
  right: new Op({
   operand: '*', 
   left: new Num({value:4}), 
   right: new Num({value:4})})});
console.log(exp.toString());
console.log(exp.count4());
console.log(exp.getValue());

Esto es todo por hoy, espero que os haya gustado, y procuraré postear más a menudo.

jueves, 4 de marzo de 2010

Diseño UML Code Kata Parchis

Hola a todos (o a los pocos que dedicáis vuestro tiempo de procrastinación con este blog)
Tras casi una semana con el code kata del parchis voy a poner por fin el diseño en UML que hemos creído que mejor representa el escenario propuesto.
En la siguiente imagen podéis ver el diseño en un cuaderno que hemos dado a este problema, al final ha quedado un diseño bastante simple y en mi opinión bastante claro. Ante cualquier duda, ya sabéis un comentario y estaremos encantados de responderos.
Diseño kata parchis
Ya me despido y espero que el diseño os haya gustado a todos. Esta semana la dejaremos seguramente para que quien quiera implemente el parchis y la semana que viene dejaremos aquí nuestro resultado.
Un saludo a todos.