
Hoy he visto por casualidad el programa redes en la tele y cuando estaba terminando han tenido la genial idea de poner la url del blog.
Redes es un programa de televisión que siempre me ha encantado, porque cuenta de manera más o menos divertida cosas muy interesantes. Una pena que siempre lo echaran a horas intempestivas, aunque ahora lo están echando los domingos a eso de las 21:00 o 21:30. Pero con esto de internet podemos disfrutar de todos los episodios que queramos cuando estemos aburridos de ver porno y esas cosas para lo que realmente se inventó esto de la red de redes.
Después de este descubrimiento me he puesto a ver algunos episodios y me he encontrado con este El cerebro es una chapuza que en una parte me ha recordado algo en lo que estuve pensando la semana pasada, y es que el lenguaje como medio de comunicación entre personas es una chapuza.
En este episodio hablan sobre las chapuzas de la evolución y se centran en el cerebro. Así pues comentan que la naturaleza hace lo que puede con lo que tiene, lo adapta a las circunstancias y así se evoluciona. Nada de pararse a pensar cuál sería la mejor manera de hacerlo, sino que coges lo que tienes y resuelves un problema con el menor esfuerzo posible.
Un buen ejemplo de esto es el lenguaje humano. Para desarrollar el lenguaje nuestra laringe tuvo que moverse un poco, y se adaptó algo existente como el aparato digestivo/respiratorio para crear la capacidad de hablar y como consecuencia también conseguimos la capacidad de atragantarnos.
Si nos fijamos bien, además de en la naturaleza, podremos encontrar todo tipo de chapuzas en todo lo que hacemos, porque realmente esa es la forma más efectiva de hacer las cosas. Tenemos un problema y una serie de herramientas y lo que hacemos es solucionar el problema al menor coste, por supuesto podemos prever algunos posibles problemas futuros pero nunca todos, ni tan siquiera los más probables, así que con el paso del tiempo comenzaremos a ver que nuestra solución era simplemente un apaño, que no tuvimos en cuenta todas las posibilidades y que esas cosas que no habiamos previsto son las que ahora nos causan problemas.
Que todo sea una chapuza no quiere decir que todo sea malo. Si intentáramos hacer las cosas perfectas nos volveríamos locos porque no es posible precedir el futuro ni tener en cuenta todo, así que intentar hacer algo perfecto nos lleva definitivamente al fracaso, porque la solución perfecta no existe.
La clave del exito está en saber que no hay nada perfecto y que no podemos prevenir todo. Definiendo bien los límites aceptables podremos tener soluciones que serán chapuzas, pero que solucionarán nuestros problemas, y agrupando una chapuza sobre otra se pueden crear grandes cosas.
Que hablen de chapuzas en redes me ha gustado mucho porque yo siempre he sido un "chapucero" y siempre he huido de la perfección. Nunca he intentado encontrar la perfección, porque llegar a ella es tan costoso que no merece la pena.

Hoy me he encontrado algunos folios viejos que tengo por ahí tirados. En estos folios tengo algunos comics a medio empezar y hoy voy a enseñar algo de lo que hice hace tiempo.
Hace ya mucho tiempo (más de 5 años creo) estaba yo apuntado a una lista de correo dónde la gente envíaba dibujos, comics, etc. Una vez se lanzó un "concurso" (creo que no era concurso, era más bien un reto, no hay premio ni nada) que consistió en que uno de la lista mandó un guión de un pequeño comic de tres páginas y había que dibujarlo, cada cual con su estilo.
Pues bien, yo comencé a dibujarlo y nunca lo terminé. Dibujé dos páginas a lápiz.
No sé qué ha sido de esa lista, es más no recuerdo ni su nombre, pero me gustaría volver a meterme en alguna lista de ese estilo.
Aquí dejo las dos páginas, se ve mal, está a lápiz y se ha degradado un poco. Podría dedicarme un día a terminar la página que falta y entintarlo.

Introducción
Ah, la programación, es algo de lo que muchos estudiantes y
profesores de informática y otras gentes hablan. Hoy os voy a contar
mi visión de lo que es, o debería ser, la programación.
Mucha gente conoce las reglas de la programación, pero no todos saben
programar. Programar es un arte que requiere una forma de pensar un
tanto peculiar, pero tranquilo, no hace falta estudiar ninguna
ingeniería para programar cosas maravillosas, sólo hace falta ponerse
a programar.
No voy a hablar de ningún lenguaje de programación en particular,
realmente casi todos son iguales, donde sí existen diferencias es en
los diferentes paradigmas de la programación como por ejemplo la
programación funcional, la programación orientada a objetos, y demás
que al final son diferentes formas de buscar una solución a un mismo
problema utilizando diferentes técnicas algorítmicas. Tonterías al fin
y al cabo. Lo realmente interesante y divertido es programar sin
preocuparse del lenguaje ni de los paradigmas de programación.
Programar no es más que convencer a una máquina para que haga una
acción repetitiva por ti. Después de esto vendrá el tratamiento de la
información, las redes, y otra serie de tonterías en principio
irrelevantes, aunque al final sean el verdadero progreso.
Como bien sabrás querido lector, la programación es una "ciencia" que
proviene directamente de las matemáticas y por tanto verás muchas
cosas relacionadas con esta ciencia si decides meterte realmente en
esto de la programación real. Por eso si has decidido estudiar
ingeniería informática y no te gustan las matemáticas, lo mismo estás
equivocado, o lo más probable es que tus profesores no sean demasiado
buenos, porque al fin y al cabo, ¿a quién no pueden gustarle las
matemáticas?
Bueno, vamos al lío, en cada sección voy a poner un ejemplo de código
en python, que bien podría ser en C, C++, java o lo que sea. Pero
python es más legible.
Supongamos que estoy iniciándome en esto de las matemáticas, y como
tengo poca memoria no soy capaz de memorizar la tabla del 2. Me puedo
hacer un programa que me lo recuerde, ya que un ordenador no es más
que una gran calculadora y de multiplicar sabe un rato:
2 * 1 2 * 2 2 * 3 2 * 4 2 * 5 2 * 6 2 * 7 2 * 8 2 * 9 2 * 10
Variables
Las variables, como en las funciones matemáticas son elementos
variables, como su propio nombre indica. Esto quiere decir que lo
mismo vale 2 que vale 3, no lo sabes, no quieres saberlo, es variable.
En todo lenguaje de programación que aprendas (o en casi todo) tendrás
que lidiar con variables que serán de diferentes tipos. Al final todo
se reduce a números, enteros, flotantes (los que llevan un punto),
caracteres, etc. Y algún día tratarás con conjuntos de variables que
se pueden llamar vectores (o arrays), estructuras, etc. que al final
no son más que bonitos contenedores de tipos básicos, como cajitas que
te permitirán hacer cosas chulas.
Supongamos ahora que ya me he aprendido la tabla del 2, pero ahora estoy
con la tabla del 3 que me está dando más problemas de los que debería.
Puedo utilizar el código anterior que me resolvería mis problemas,
pero tendría que cambiar todos los 2 por 3, y como yo soy un hombre
inteligente y pienso en el futuro, lo mismo también debería pensar en
la tabla del 4 y posteriores.
Como habrás observado avispado lector el primer número es "variable"
y por tanto es un caso estupendo para usar esto:
variable = 3 variable * 1 variable * 2 variable * 3 variable * 4 variable * 5 variable * 6 variable * 7 variable * 8 variable * 9 variable * 10
Y con este código si quiero la tabla del 2, del 3, o del 4 sólo tengo
que cambiar el valor de la variable.
Es muy recomendable poner nombres a las variables que representen bien
lo que pueden contener, es decir, que si lees el código puedas saber
qué va a tener esa variable. En nuestro ejemplo podríamos llamar a la
variable multiplicando, pero le vamos a dejar variable porque esto son
ejemplo tontos.
Condicionales
¿Qué sería de la programación si no tienes posibilidad de ejecutar
acciones diferentes según algún criterio? Pues nada, los condicionales
son la parte más básica de la programación, te permiten hacer una cosa
si esto y si no pues otra. Es decir, que teniendo partes "variables" y
condicionales ya puedes programar cualquier cosa. Por ejemplo un juego
de fútbol: Si la pelota entra en la portería es gol. Muy fácil de
programar.
Tan solo se trata de evaluar una condición y en función de si es
verdadero o falso se ejecuta una porción de código u otra.
Ahora que ya tengo las tablas de multiplicar del número que me
apetezca quiero conseguir las multiplicaciones hasta el 11 si el
número es mayor que 3, para el 1,2 y 3 me basta con las
multiplicaciones hasta el 10. ¡Pues puedo usar un condicional para
hacer esto!.
variable = 4 variable * 1 variable * 2 variable * 3 variable * 4 variable * 5 variable * 6 variable * 7 variable * 8 variable * 9 variable * 10 if variable > 3: variable * 11
Bucles
Los bucles te permiten repetir una instrucción una y otra vez haciendo
pequeñas variaciones en las variables implicadas. Son bucles son los
que le dan realmente potencia a la programación, además de que son la
causa directa de la complejidad computacional, pero eso es otra
historia.
Muchas personas creen que los bucles son imprescindibles, pero como
veremos más adelante con recursividad se pueden ejecutar bucles de
manera simple y en muchas ocasiones es más simple que un bucle
tradicional. Normalmente los bucles se utilizan para iterar sobre una
lista de elementos.
variable = 4 i = 1 while i<=10: variable * i i = i + 1 if variable > 3: variable * 11
Anda, conseguimos un código mucho más corto. En casi todos los
lenguajes de programación tendrás una instrucción while o for para
iterar. Si eres observador te habrás dado cuenta de que se declara
otra variable nueva, i, que nos sirve para llevar la cuenta de cuantas
iteraciones llevamos.
Funciones
Todo lenguaje de programación que se precie te permitirá definir
funciones, otros lo llamarán métodos y a las variables las llamarán
atributos, pero al final será lo mismo.
Cuando escribes código normalmente tendrás partes que se repiten, eso
puedes convertirlo en una función y luego puedes hacer llamadas a esa
función cada vez que quieras. Una función recibirá una serie de
argumentos que serán las variables definidas que harán que la función
haga una cosa u otra. También suelen devolver un valor. Si una función
no recibe parámetros y no devuelve nada se suele llamar rutina.
Ahora que ya tengo resuelto lo de las tablas de multiplicar puedo
escribir una función que me haga eso y conseguir la tabla del 2, 3 y 4
a la vez.
def tabla(n): i = 1 while i<=10: n * i i = i + 1 if n > 3: n * 11 for i in [2, 3, 4]: tabla(i)
Si la función que estás escribiendo ocupa más de una pantalla (y con
una pantalla quiero decir 30 líneas) algo está mal, así que tienes que
dividir la función en varias más, ninguna función debe ocupar más de
30 líneas.
Recursividad
Como último recurso programático te presento la recursividad. ¿Qué es
eso? La recursividad es un nombre bonito para una cosa simple, tan
solo es llamar a la función que estás definiendo desde dentro de la
misma función.
Una función recursiva siempre tiene que tener una condición de parada
para que no sea infinita. Ademas tiene que tener al menos una llamada
a la misma función que se está definiendo para que se pueda llamar
función recursiva.
Ahora que soy un maestro de las matemáticas puedo jugar un poco con la
programación y voy a definir la función tabla de manera recursiva.
def tabla(x, i): if i == 11: if x > 3: x*i else: x*i tabla(x, i+1) tabla(4, 1)
Con esto acaba la clase práctica de hoy.

Últimamente he estado jugando con JQuery y llamadas ajax a servcios json y me he encontrado con un pequeño problema. Cuando intentas acceder a un servicio que te ofrece json plano jquery peta y te devuelve un error como este en la consola de javascript del navegador:
Error: uncaught exception: [Exception... "Access to restricted URI denied" code: "1012" nsresult: "0x805303f4 (NS_ERROR_DOM_BAD_URI)" location: "js/jquery-1.3.2.min.js Line: 19"]
Esto ocurre porque el navegador implementa una política de seguridad mediante la cual no permite que se acceda a urls diferentes a la que hace la petición. Osea que no puedes hacer peticiones a un servidor externo de json pelado.
Para realizar este tipo de peticiones existen callbacks y jsonp. La idea es que en la url de la petición jquery debes añadir "http://.../?callback=?" y jquery rellenará el resto. Para cada petición jquery pasará como callback un nombre de función "jsonp1234" donde los números son diferentes por petición y el servidor ha de responder con el código json envuelto en esa función "jsonp1234({...});".
¿Qué haces cuando el servidor no ofrece el servicio jsonp?
Aquí es donde viene el proxy guarrón que me he implementado. La idea es pillar todas las peticiones al servidor, pillar el json plano y modificarlo para que sea jsonp.
Para ello lo primero que desarrollé fué un proxy http plano y feo:
# python proxy.py twitter.com 80 import sys import socket s = socket.socket() mserver = 'localhost' mport = 8080 s.bind((mserver, mport)) s.listen(10) server = sys.argv[1] port = int(sys.argv[2]) while True: try: print "waiting for requests at %s:%s" % (mserver, mport) s1 = s.accept() except KeyboardInterrupt: s.close() print "bye" break s2 = socket.socket() s2.connect((server, port)) s1 = s1[0] v = '' r = 0 while not r or len(r) == 1024: r = s1.recv(1024) v += r v = v.replace('Host: %s:%s' %(mserver, mport), 'Host: %s:%s' % (server, port)) print v s2.send(v) v2 = '' r = 0 while True: s2.settimeout(0.3) try: r = s2.recv(1024) except: break v2 += r s1.send(v2) s2.close() s1.close()
¿Qué hace? pues monta un servidor en el puerto 8080 y cada petición a este servidor la hace directamente al servidor remoto y la respuesta de este es lo que devuelve. Simple ¿verdad?.
Pero yo quiero modificar lo que me devuelve, así que hay que tratar la respuesta del servidor remoto:
#!/usr/bin/python # proxy.py twitter.com 8080 import sys import socket import gzip import StringIO import re pet = re.compile('(GET) (?P<url>.*)\?(?P<args>.*) (HTTP/1.1)') js = re.compile('(\{.*\})') def html(out): ret = '' ret += "Content-type: text/html\r\n" ret += 'Content-Encoding: gzip\r\n' ret += 'Content-Length: %s\r\n' % len(out) ret += '\r\n' ret += out return ret def compressBuf(buf): zbuf = StringIO.StringIO() zfile = gzip.GzipFile(mode = 'wb', fileobj = zbuf, compresslevel = 9) zfile.write(buf) zfile.close() return html(zbuf.getvalue()) def json(cad, callback="json"): if not callback: return cad else: return "%s(%s);" % (callback, cad) s = socket.socket() mserver = 'localhost' mport = 8080 s.bind((mserver, mport)) s.listen(10) server = sys.argv[1] port = int(sys.argv[2]) while True: try: print "waiting for requests at %s:%s" % (mserver, mport) s1 = s.accept() except KeyboardInterrupt: s.close() print "bye" break s2 = socket.socket() s2.connect((server, port)) s1 = s1[0] v = '' r = 0 while not r or len(r) == 1024: r = s1.recv(1024) v += r v = v.replace('Host: %s:%s' %(mserver, mport), 'Host: %s:%s' % (server, port)) callback='' args = pet.search(v) if args: args = args.group('args').split('&') for a in args: c,val = a.split('=') if c == 'callback': callback = val break v = pet.sub(r'\1 \2 \4', v) print v s2.send(v) v2 = '' r = True while r: s2.settimeout(1) try: r = s2.recv(1024) except: break v2 += r v3 = v2.split('\r\n') print v3 encoding = '' for i in v3: if i.startswith('Content-Encoding: '): encoding = i[len('Content-Encoding: '):] if encoding == 'gzip': st = StringIO.StringIO(v3[-1]) content = gzip.GzipFile(fileobj=st).read() else: try: content = js.search(v2).groups()[0] except: content = '' print content s1.send(json(content, callback)) s2.close() s1.close()
Puedes probar con twitter por ejemplo, lanzando el proxy "python proxy.py twitter.com 80" y haciendo la petición desde el navegador "http://localhost:8080/status/user_timeline/danigm.json?callback=jsonp123" o "http://localhost:8080/status/user_timeline/danigm.json?callback=holaaaaa".
Y jugando con esto puedes hacer un proxy que modifique toda respuesta, por lo que te puedes divertir mucho.
Por supuesto habrá muchos proxys http hechos en python, pero este lo he hecho yo, a bajo nivel y de mala manera :P

Ya están disponibles los paquetes debian de geco. Todo el proyecto está compuesto por un total de cuatro paquetes independientes:
- gecod: Servidor GECO, es el que tiene la base de datos y el que alamacena la contraseñas. Combinandolo con cualquier cliente tienes un gestor de contraseñas completo.
- python-gecoc: Módulo python que proporciona las funcionalidades necesarias para crear un cliente geco o para interactuar con un servidor geco desde python (de este dependen los clientes gtk-geco y web-geco). También incluye el script terminal-geco
- gtk-geco: La interfaz de escritorio. Es la interfaz más completa y usable. Ofrece toda la funcionalidad.
- web-geco: Interfaz web. Con esta interfaz puedes ofrecer un servicio de acceso a contraseñas remoto
Para usarlo como un gestor de contraseñas de escritorio es necesario instalar gecod, python-gecoc y gtk-geco. El servidor se lanzará por defecto, por lo que el cliente de escritorio deberás conectarlo a https://localhost:4343 que es tu servidor gecod, te registras, guardas tu configuración y a disfrutar.
Trucos para gtk-geco
Si pulsas con el botón derecho sobre una contraseña se copia la cuenta al portapapeles no la contraseña.
Si haces doble click sobre el icono aparecerá un dialogo de busqueda, para un acceso más rápido.
Pulsando con el botón derecho sobe el icono aparecen más opciones.
Si te dice que no ha encontrado el fichero de configuración y ya existe, es posible que hayas puesto mal la contraseña, pulsa en olvidar y luego en preferencias, volverá a pedirte la contraseña.
Otras cosas
Por otra parte he añadido nuevas funcionalidades al cliente de escritorio. Por ejemplo ya se puede cambiar la contraseña maestra desde la preferencias. Además de poder realizar busquedas con autocompletado y también es posible copiar la cuenta en lugar de la contraseña al portapapeles.
Ah, y he cambiado el desarrollo del proyecto a la forja de sugus, así que si te interesa participar, te falla algo o tienes alguna sugerencia, puedes crear una petición nueva.

El teclado tradicional que se usa en españa el archiconocido qwerty. Como bien indican en la wikipedia este mapa de teclado no es optimo para la escritura ya que distribuye las teclas mas usadas por todo el teclado haciendo que al escribir nuestros dedos bailen a lo largo del teclado.
Sin embargo existen otras distribuciones de teclado que hacen la escritura mas fluida. Por ejemplo el teclado dvorak está diseñado para que las manos se muevan mucho menos.
Hay mucha gente que opina que es una perdida de tiempo el aprender una distribución nueva de teclado, puesto que QWERTY es un estándar y ya que conozco una forma de escribir no voy a aprender otra. Esto puede ser cierto, pero si hay una distribución de teclado mejor al menos debería intentarlo, y más aún una persona como yo que se pasa casi todo el día escribiendo.
El comienzo
Como todo en esta vida al principio es difícil, y ahora mismo estoy en esa etapa, escribiendo una entrada a velocidad de tortuga.
Es muy complicado porque en primer lugar ya conoces una manera de escribir que se ha convertido en casi instintiva y tienes que esforzarte a cada pulsación para no dejarte llevar por tus instintos y pulsar la tecla adecuada. Y en segundo lugar si cometes el error de mirar el teclado estás perdido porque seguramente tendrás un qwerty y te perderás completamente.
Pues nada más, seguiré informando.

Esta semana, los días 7 y 8 de Mayo ha tenido lugar la fase final de Concurso Universitario de Software Libre. Esta final, como las dos anteriores ha tenido lugar en la Escuela Técnica Superior de Ingeniería Informática de la Universidad de Sevilla. Y como en anteriores ediciones ha consistido en dos días completos de ponencias y charlas, incluyendo entre estas las presentaciones de los seis proyectos finalistas y la entrega de premios.
Este año además de como colaborador he asistido como finalista con el proyecto GECO. Además este año se ha celebrado la fase final en el salón de actos mientras que en años anteriores se hizo en el salón de grados. El salón de actos es realmente grande y separa muchísimo a los ponentes del público, algo que intimida al ponente y por otra parte hace que los asistentes tengan más complicado participar con preguntas.
Como en todo evento de este tipo lo más importante es relacionarse con ponentes y otros participantes, compartir ideas e impresiones, poner cara a gente que sólo conoces a través de internet y hacer amigos.
Yo por mi parte he aprendido mucho de los demás participantes y ponentes, me gustaría haber hablado más, pero por diferentes motivos al final hemos hablado poco, pero bueno, ha estado bastante bien.
El año que viene no creo que pueda participar, porque comenzaré con los estudios de doctorado, que quedan fuera del ámbito del concurso, pero me tocará colaborar, medio organizar y espero poder "tutorar" o ser el mentor de algún estudiante que necesite mi ayuda o guía para participar. Tengo varios proyectos para el que no tenga nada en mente y seguro que saldrán muchos más.
Premios
Premio innovación: eOPSOA
Finalista innovación: Cool Imaging
Premio comunidad: AVBOT
Finalista comunidad: Digital Coach
Premio ocio: Tucan
Finalista ocio: Geco
Los premiados se llevan 2000 euros y una subscripción a Linux Magazine y los finalistas 1000 euros y una subscripción digital.
Quiero decir que para los participantes el concurso no acaba aquí, en septiembre comienza de nuevo y podréis participar incluso mejorando el mismo proyecto, si os pasa como a mí que ya acabáis y demás siempre podéis seguir ligados al concurso colaborando a la difusión, impulsando a nuevos alumnos universitario a participar e incluso colaborando con los proyectos, porque no olvidemos que esto es software libre y que toda colaboración es bienvenida.

Para la presentación de GECO en la Fase Final del Concurso Universitario de Software Libre he preparado un pequeño comic en el que creo que se muestra de una manera más clara y amena el porqué de GECO.

El 28 de abril se dió a conocer la lista de finalistas del tercer concurso universitario de software libre (CUSL3) y resulta que GECO ha salido seleccionado.
Esto es una gran noticia después de que en el concurso local de Sevilla también recibiera un premio, así que parece ser que el tiempo y esfuerzo dedicado a este proyecto está dando sus frutos.
GECO no nació como un proyecto para ganar el concurso, tan solo era una necesidad personal que quería implementar y para la cual aproveché el concurso como medio de motivación y una oportunidad para aprender un poco más. Marcandome unos plazos e implementando la parte funcional primero he conseguido un proyecto que podría considerarse casi cerrado, hoy en día se podría decir que está en la versión 0.99, tan sólo falta por añadir una pequeña funcionalidad a los clientes, pero que gecolib ya contempla.
Muchas gracias a todos los que han hecho posible este concurso y a todos los participantes. Una idea que no se intenta llevar a cabo es una idea menos. Así que ningún desarrollo es en vano.



