Quote of the GET: Controlling complexity is the essence of computer programming. Brian Kernigan

Archive for python

removing your facebook photo tags automagically

Este post también está escrito en español aquí.

Privacy at Facebook is heavy-duty. As a big fan of the Worlds Collide Theory I hate be tagged compulsively. I would like to select in which photos appear in my profile and feed. Since I couldn’t find that option in the setting menu, I looked for the answer in my favorite scripting language: Python.

This 60-lines-long script removes your tag from the latests photos where you has been labelled. You can download it from here. You may run it hourly (or every 15 minutes, or every 5 minutes, depends how paranoid you are) via cron or whatever.

Any improvement is welcome. It probably runs on Windows too. If you managed to do it, leave a comment for the others.

NEW VERSION! (available here).

Comments (2)

remover tu etiqueta de las fotos de facebook automágicamente

This post has been written in English too.

La privacidad en Facebook es un asunto complejo. Como gran suscriptor a la Teoría de Colisión de Mundos es que odio ser etiquetado en fotos de forma compulsiva. Me gustaría tener alguna forma de elegir en que fotos aparezco en mi perfil y actualizaciones. Dado que no pude encontrar tal opción entre la configuración, busqué la respuesta en mi lenguaje de scripting favorito: Python.

Este script de 60 lineas remueve tu etiqueta de las últimas fotos donde te hayan tagueado. Puede ser descargado desde aquí. Hay que correrlo cada hora (o cada 15 minutos, o cada 5, dependiendo de que tan paranoico seas) a través de cron o como sea.

Cualquier mejora es bienvenida. Posiblemente también corra en Windows. Si lograste hacer esto, deja un comentario que pueda serle útil a otros.

¡NUEVA VERSIÓN! (disponible aquí).

Comments (13)

φbonacci

Mi conjunto de números favoritos son los enteros en general y los naturales en particular. Son los primeros números que aprendemos en la vida, sencillos, de apariencia intuitiva pero con poderosas propiedades. Dado que mi amateur aproximación a la matemática se dio por el camino de la teoría de números, fueron mi primer gran amor matemático.


Sin embargo, no es difícil encontrar fascinante a otros conjuntos de números. Muchas de estos patean el tablero de formas agradables, como los complejos, que se escaparon de la recta real para irse de vacaciones al plano. Entre los más impetuosos contra la intuición están, obviamente, los irracionales. Y a uno de ellos va dedicado este post.

Hace un par de meses divagué con π. Este semana terminé de leer el libro La Proporción Áurea de Mario Livio. Este libro, que evidentemente trata sobre la constante φ (phi), lo compré en Madrid, atraído por la promesa de desasnarme con respecto a la historia de este número.

Primero me gustaría hablarles sobre el libro como tal, el cual resultó sumamente entretenido, aunque tal vez le sobren unas 50 o 100 páginas. Es un paseo por la historia del arte plástico, arquitectónico, escultural y matemático con φ como eje central hilador. Además de dar ejemplos de como se expresan los números en la naturaleza, explica con profundo detalle ciertas propiedades matemáticas en sus numerosos apéndices e invita al lector a pensar sobre porque la matemática encaja también como explicación del universo. Por momentos se va por las ramas pero casi siempre de forma afable y atrapante. Son altamente rescatables los pasajes donde el autor trata con ácida ironía los esfuerzos de los numerólogos de meter a φ lugares arbitrarios cualquiera, como en las dimensiones de Panteón. En mi opinión es un libro altamente recomendable para el aficionado a la matemática y mi calificación (hace mucho que no califico libros con estrellas) es .

En segundo lugar quisiera comentar algunas nerdeadas matemáticas inspiradas en el la lectura de este libro. Empezando por lo principio, presentar a quienes no conozcan el número φ, en las palabras de Euclides:

Se dice que una línea recta está dividida en el extremo y su proporcional cuando la línea entera es al segmento mayor como el mayor es al menor

La frase dividida en el extremo y su proporcional hace referencia a la proporción de la que estamos hablando. La definición para mortales es:

La longitud total a+b es al segmento más largo a como a es al segmento más corto b

El valor en cuestión se puede calcular despejando algebraicamente tomando b=1, y es:

Puede verse que, al igual que π(pi), es un número irracional. Pero, a diferencia de π, es un número algebraico, lo que lo emparenta bastante con teoría de números. Sin embargo, su expresión como fracción continua compuesta de solo 1s (unos), hace que converja muy lentamente, convirtiéndolo en el más irracional entre todos los irracionales. En términos llanos, φ puede expresarse como la siguiente fracción continua:

Nótese que, cada iteración de esta fracción continua puede expresarse como (los primeros 15 valores, esta secuencia fue resultado de este script):

2 / 1 = 2
3 / 2 = 1.5
5 / 3 = 1.666666666666666666666666667
8 / 5 = 1.600000000000000000000000000
13 / 8 = 1.625
21 / 13 = 1.615384615384615384615384615
34 / 21 = 1.619047619047619047619047619
55 / 34 = 1.617647058823529411764705882
89 / 55 = 1.618181818181818181818181818
144 / 89 = 1.617977528089887640449438202
233 / 144 = 1.618055555555555555555555556
377 / 233 = 1.618025751072961373390557940
610 / 377 = 1.618037135278514588859416446
987 / 610 = 1.618032786885245901639344262

Aquel lector atento notará que las fracciones tiene cierto patrón. Por un lado, el numerador de cada reglón pasa a ser el denominador en el siguiente. Los números son:
1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,….
¡Exacto! ¡Es la sucesión de Fibonacci! Cada número es la suma de los dos anteriores. En efecto, siendo F(n) el termino n-ésimo de la serie de Fibonacci:

Así es como puede verse una fuerte relación entre φ y Fibonacci. Y si con Fibonacci se puede calcular la proporción áurea… ¿cómo es la relación a la inversa?

Con esta formula se puede calcular el valor del término n-ésimo de la serie de Fibonacci:

Es fácil reconocer que dentro de esa fórmula está φ.

La propoción áurea φ tiene un montón de raras y divertidas propiedades. Entre las más atractivas se encuentran:


En lo personal aprendí muchas cosas nuevas sobre la proporción áurea. Pero en el apéndice 9 (como dije, es un libro con muchos apéndices) se comenta un concepto que me voló la cabeza: la ley de Benford. El tema se toca tangencialmente, promediando el último capítulo, como un ejemplo de como las matemáticas sorprenden. Y sí que lo hacen.

Pero ese será tema del siguiente post.

Comments (2)

Asimov, Leibniz, pi, python, floats y evadirse de la realidad

La matemática tiene cosas sorprendentemente lindas. Y una de las que siempre me gustó de forma especial es la formula de Leibniz para el cálculo de π. También conocida como la serie de Gregory-Leibniz es una simpática manera de expresar el más famoso de los números irracionales:

O para aquellos no gustan de las notación sigma-grande:

Como verán, se trata de una serie sumamente simple y elegante. Y como suele ocurrir con estas cosas, aparecen en la vida de uno en momentos extraños, casi que al rescate.

Anoche me hallé frente a la biblioteca buscando nada en espacial. Necesitaba despejar la cabeza, olvidarme de los asuntos terrenales asociados con las complejas interacciones y relaciones humanas.

Fue en esa circunstancia que me encuentro con De los números y su historia de Isaac Asimov (que puede ser descargado desde aquí). Mientras lo hojeaba vi la formula de Leibniz, promediando el capítulo 6 e inmediatamente atrajo mi atención.

Después de expresar la serie, Asimov explica:

<<Ustedes podrán condenar mi falta de perseverancia, pero los invito a calcular la serie de Leibniz simplemente hasta donde la hemos escrito más arriba, es decir hasta 4/15. Incluso pueden enviarme una postal para darme el resultado. Si al terminar se sienten desilusionados al descubrir que su respuesta no está tan cerca de π como lo está el valor 355/113, no se den por vencidos. Sigan sumando términos. Sumen 4/17 al resultado anterior, luego resten 4/19, después sumen 4/21 y resten 4/23, etcétera. Pueden seguir hasta donde lo deseen, y si alguno de ustedes descubre cuántos términos se requieren para mejorar el valor 355/113, escríbanme unas líneas y no dejen de decírmelo. >>
En efecto, la fracción 355/113 parece ser la forma que mejor balancea precisión y simpleza a la hora de arrimarse a π desde lo números racionales, quedando a solo 2.66764189 × 10-7 de distancia. Mucha gente también utiliza la relación 22/7, aunque con menor precisión.

El desafío propuesto parecía interesante. Resultaba una entretenida oportunidad de jugar con floats en python, que siempre a resultado ser bastante tricky (además de ser un excusa para despejar la cabeza).

Empecé por escribir una versión relativamente obvia de la solución, que me dijo que al llegar al cociente 7497257 (n=3748629 en la sumatoria de Leibniz) el valor de la sumatoria estaría en 3.14159292035, quedando a 2.66764081935 x 10-7 de π. Dado que los decimales (floats, representaciones de punto flotante) en Python no se comportan de forma intuitiva, decidí hacer una segunda versión.

En esta versión traté de mudarme al predecible mundo de los enteros. Y obtuve valores levemente distintos. En el cociente 7497247 (n=3748624) se obtiene la primera aproximación mejor que 355/113, que es 3.141592386825… (a 2.66764162 x 10-7 de π)

Tampoco estoy seguro de que la segunda solución sea la correcta. Me pregunto cual será el promedio de valores en las postales que la viuda Asimov seguramente guarda en una caja de zapatos.

El hecho es que fue entretenido intentarlo y tal vez continúe con la experiencia la próxima vez que quiera desconectarme del mundo. Después de todo, como dijo el mismo Asimov: “Los hombres que se acostumbran a preocuparse por las necesidades de unas máquinas, se vuelven insensibles respecto a las necesidades de los hombres”, y hay veces que volverse insensible se ve, erróneamente, como una propuesta seductora. Hay gente que ahoga penas en alcohol, mucho más sano es ahogarlas matemáticas…

BTW, ya que tenía los datos armé un plot de los primeros 1000 valores de la serie para mostrar de forma gráfica la convergencia.

Ahora es momento de volver a la realidad, que buena o mala, irracional o racional (seguro que real al menos), inexacta o precisa, después de este recreo metal ya no se ve tan mal :-)

UPDATE: Sat, 20 Sep 2008 22:18:18 -0300: La solución estaba realmente cerca (en mi misma ciudad) y se llama Facundo, quien dejó un comentario. Bah.. se llama decimal, pero existe gracias a Facundo :). La biblioteca decimal permite manejar de forma exacta una cantidad arbitraria de decimales. La respuesta correcta es…….. (redoblantes de suspenso) con n=(7497259+1)/2! aproxima a Π en 3.141592386825668744985771256 a solo 2.66764125 × 10-7 del número irracional. El nuevo script.. aquí.

Gracias Facundo, gracias decimal, gracias Asimov, gracias Leibniz….

Comments (10)

sudoku, algorítmos genéticos, la estrategia backtracking, programación lineal y R

/* Habiendo leído El curioso incidente del perro a medianoche le tomé cierto buen gusto a los títulos largos :-) */

Hace unas semanas, Mahoo me regaló un pequeño libro con un montón de sudokus para resolver. Si bien conocía el juego, nunca me atrajo particularmente. En esos días, yo estaba buscando algún tema original para uno de los trabajos prácticos de Inteligencia Artificial. La consigna se refería al uso de algoritmos genéticos para la resolución de algún problema. Lo importante no era el programa, sino el análisis de su comportamiento: estudiando, por ejemplo, qué método de cruzamiento se aplica mejor o qué función de aptitud es más representativa.

Viendo como Mahoo se entretenía con alguno de ellos (práctica en la que también se iniciaba) se me ocurrió que un resolver de sudokus podría ser una linda propuesta para mi TP.

Los algoritmos genéticos intentan emular a la naturaleza, a base de prueba y error, favoreciendo a las soluciones más aptas y castigando a las que no lo son tanto. Suponiendo que el cruzamiento de las buenas-soluciones generan aún-mejores-soluciones. Se trata de la búsqueda probabilística, muy parecida a meter muchas soluciones en un cubilete gigante y agitarlas hasta encontrar algo útil.

Al tratarse de un problema determinístico, la solución dista muchísimo de ser óptima. De hecho, ni siquiera se asegura que vaya a haber una solución. Pero me pareció algo simpático de intentar.

El resultado, escrito en mi rústico Python, puede ser bajado de aquí (incluye instrucciones para correrlo en Windows). No, no esperen que funcione bien, advertidos están. Es uno de los peores métodos posibles para este tipo de problemas. Sólo llega a una solución cuando la cantidad de incógnitas es (muy) limitada. Se plantean soluciones a base de llenar de random cada uno de los casilleros vacíos y chequeando cuantos valores se repiten en cada fila, columna y región. Cuando este chequeo da 0, se llega a una solución. Bastante cavernícola como notarán.

Es natural pensar en cuál sería la forma correcta de llegar a una solución. Recordé las clases de Investigación Operativa y la utilización del método simplex para la solución a problemas con restricciones. De hecho, es una solución que muchos proponen. No se si alguno de ustedes lo ha intentado. Yo sí, durante las clases aburridas me senté a pensar como sería el conjunto de ecuaciones y me encontré con una demencial y frustrante cantidad de ecuaciones. Acá hay una linda explicación, la que resumo, haciendo énfasis en las complicaciones:
Se necesitan variables binarias de la forma xijk donde 1 significa que el símbolo k (de 1 a 9) va en la celda (i,j) de la solución. 0 significa que no está. Esto genera un total de 729 variables (93) lo que, como mínimo, asusta. Veamos las ecuaciones:

(1) Para que cada celda (i,j) tenga un símbolo y éste sea único. Se necesitan 81 ecuaciones como éstas (una por cada celda).
(2) Para que en la fila i cada símbolo esté una vez y que en todas las columnas sea distinto. Se necesitan 81 ecuaciones como éstas(una por cada columna y cada símbolo posible).
(3) Para que en la columna j cada símbolo esté una vez y que en todas las filas sea distinto. Se necesitan 81 ecuaciones como éstas(una por cada fila y cada símbolo posible).
(4) Para que en cada región cada símbolo esté una y solo una vez. Se necesitan 81 ecuaciones como éstas (una por cada región y cada símbolo posible).
(5) Representa el enunciado, es decir, el problema a resolver. Por ejemplo, x115=1 significa que en la celda (1,1) hay un 5. Dependiendo cuantos casilleros vengan asignados es la cantidad de igualdades como estas que se necesitan; típicamente, ~30.
(6) Restringe las variables al conjunto binario.

¡En total son más de 350 ecuaciones! Hay propuestas con menos ecuaciones, pero siempre serán muchísimas. Evidentemente, ésta tampoco es la solución óptima (aunque es mucho mejor que los algoritmos genéticos). Y su problema radica en que, desde algún punto de vista, el método simplex no se ajusta al problema. Gráficamente, las ecuaciones representan semiplanos en un hiperespacio multidimencional (de 9 dimensiones?) cuya intersección es, en caso que haya una única solución, un único punto. /* Puede que le esté pifiando en esta conclusión final y cualquier ratificación o rectificación es bienvenida */

Simplex está pensado para restricciones de máximos y mínimos donde el objetivo es maximizar o minimizar y las variables binarias intentan ampliar el método para restricciones de este tipo. Da soluciones múltiples en forma de un polígono, donde a una o más se las llama óptima, porque maximiza o minimiza la función objetivo. Es claro que el problema del sudoku no usa sus ventajas y abusa de sus debilidades.

Curiosamente, cuando comenté este problema a un reciente conocido, surgió que también él tuvo que hacer un trabajo práctico que resolvía sudokus. En este caso, el TP giraba entorno a la gestión de la pila para recorrer árboles. Particularmente, árboles empleados en la estrategia de backtracking. Así pues, éste es su programita, sencillo, simpático y rápido. Gracias Nacho :).

Los métodos basados en búsqueda combinatoria sobre árboles parecen ser particularmente buenas para el problema del sudoku. En la wikipedia figuran dos interesantes formas: backtracking y ramificación y poda.

Para terminar, una última casualidad: Por razones que no vienen al caso ahora y que seguramente provocarán un nuevo post en el futuro estoy aprendiendo un lenguaje para el procesamiento de señales llamado R. Estoy trabajando mucho con una biblioteca llamada sound. Buscándola en el repositorio de bibliotecas, me encuentro con una llamada sudoku. No resistí la tentación de probarla :). Un ejemplo de su uso:

> install.packages("sudoku")
> # es necesario instalar tcltk si se quiere la parte gráfica
> install.packages("tcltk")
> library(sudoku)
> library(tcltk)
> library(tkrplot)
> miSudoku <- generateSudoku(Nblank=50, print.it=TRUE)
  +-------+-------+-------+
  |   6   |   7   |   8 2 |
  | 4 8   |     1 | 7     |
  |       | 8 2   | 5     |
  +-------+-------+-------+
  |       | 1     | 9 7   |
  |       |     2 |   5 1 |
  | 5 1 6 |   9 7 |       |
  +-------+-------+-------+
  |       |   4 8 |       |
  | 6 5   | 7   9 | 8     |
  |       |       |   9 7 |
  +-------+-------+-------+
> # la variable miSudoku es una matriz
> miSudoku
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    0    6    0    0    7    0    0    8    2
 [2,]    4    8    0    0    0    1    7    0    0
 [3,]    0    0    0    8    2    0    5    0    0
 [4,]    0    0    0    1    0    0    9    7    0
 [5,]    0    0    0    0    0    2    0    5    1
 [6,]    5    1    6    0    9    7    0    0    0
 [7,]    0    0    0    0    4    8    0    0    0
 [8,]    6    5    0    7    0    9    8    0    0
 [9,]    0    0    0    0    0    0    0    9    7
> #La biblioteca incluye una función para para solucionarlo
> solveSudoku(miSudoku)
       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
 [1,]    1    6    5    9    7    3    4    8    2
 [2,]    4    8    2    5    6    1    7    3    9
 [3,]    3    7    9    8    2    4    5    1    6
 [4,]    2    4    8    1    5    6    9    7    3
 [5,]    7    9    3    4    8    2    6    5    1
 [6,]    5    1    6    3    9    7    2    4    8
 [7,]    9    3    7    2    4    8    1    6    5
 [8,]    6    5    1    7    3    9    8    2    4
 [9,]    8    2    4    6    1    5    3    9    7
> # Incluso trae soporte gráfico para resolverlo en una ventanita :)
> playSudoku()

Así fue como, un simple regalo, un TP universitario y un montón de simpáticas casualidades tuvieron su punto de conexión. Y que divertido que resultó ser :). Ahora tengo que escribir el informe sobre los algoritmos genéticos en el sudoku. La semana que viene espero publicarlo aquí.

UPDATE August 6th: El informe y los archivos relacionados ya está publicados.

Comments (1)