Mostrando entradas con la etiqueta programming. Mostrar todas las entradas
Mostrando entradas con la etiqueta programming. Mostrar todas las entradas

miércoles, 7 de abril de 2010

El arte de programar

Leído en Watch What I Do: Programming by Demonstration


This urge to create something living is common among artists. Michelangelo is said to have struck with his mallet the knee of perhaps the most beautiful statue ever made, the Pieta, when it would not speak to him. And then there's the story of Frankenstein. Artists have consistently reported an exhilaration during the act of creation, followed by depression when the work is completed. "For it is then that the painter realizes that it is only a picture he is painting. Until then he had almost dared to hope that the picture might spring to life." (Lucien Freud, in [Gombrich 60], p.94) This is also the lure of programming, except that unlike other forms of art, computer programs do "come to life" in a sense.

viernes, 12 de marzo de 2010

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.

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

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.