lunes, 8 de abril de 2013

Depuración (parte 1): ¿para qué sirve y cómo funciona?

Si hay una habilidad imprescindible en todo buen programador, es la habilidad para depurar un programa. La depuración es en general el proceso de corregir errores, pero cuando hablamos de programación, yendo a la práctica, la clave es ejecutar el programa con un "depurador", una herramienta que nos permite interrumpirlo en cualquier momento para ver qué está haciendo o qué tiene en su memoria. Un programador habilidoso en la depuración, sabe dónde interrumpirlo o qué buscar en la memoria a la hora de encontrar la causa de un problema, o entender cierto comportamiento. Y esto se adquiere con la práctica, como todo en la programación. Hay que conocer qué pueden hacer en teoría las herramientas, pero la práctica y la experiencia nos ayudarán a decidir cómo utilizarlas. Sin embargo, hay muchas funcionalidades básicas de un depurador que puede aprovechar incluso el principiante para entender cómo funciona un ejemplo o una estructura en particular.

El problema es que a pesar de lo importante que nos parezca a muchos programadores, cuando se enseña a programar en general se le da poco y nada de importancia. En la mayoría de los casos, los libros de programación no dedican un capítulo a esto, ni los docentes dedican una de sus clases. Pareciera que es algo para aprender cuando ya sabemos programar, para dejar para cursos avanzados y segundas partes, y esa idea no puede estar más equivocada. Las nociones básicas y el hábito de usar un depurador se deben inculcar desde temprano (desde que dejamos el pseudocódigo y pasamos a un lenguaje real diría yo). Por eso, en esta serie les voy a empezar a contar a los principiantes qué se puede hacer con un depurador, y daré algunas pistas para los más curiosos o avanzados de cómo hace lo que hace, aunque esto último no sea necesario saberlo para comenzar a utilizarlo.

viernes, 22 de marzo de 2013

Ayuda, lo necesito urgente!

Una vez más vengo a atacar (solo un poquito) a los usuarios, esos que a veces defiendo tanto. No quiero generalizar, así que al que no le toca que no le toque. Tampoco es que yo tenga un trastorno bipolar, doble personalidad o alguna de esas condiciones psicológicas que no se exactamente qué significan. Lo que pasa es que valoro mucho y trato de fomentar la contribución de muchos buenos usuarios por un lado, pero también a veces me sacan de quicio los mensajes de otros por el otro. En el fondo, puede que todo sea mi culpa, así que vamos a tratar de hacer una crítica constructiva de ambos extremos de la comunicación (va con un poco de humor para no enojar a nadie).

La gente escribe (por mail, por formularios en el sitio web, por los foros, por el chat, da igual) preguntando/diciendo cosas de PSeInt, ZinjaI, C++, programación, o cualquier cosa que les parezca. Muchos mensajes son útiles, muchos habría que ignorarlos, otros no lo se porque ni siquiera los entiendo. Hay problemas en dos niveles: qué quieren decir, y cómo lo dicen. Empecemos por el primero, más básico, elemental, aplicable a cualquier comunicación escrita en cualquier ámbito. Para que entiendan bien todos (especialmente los que lo hacen), lo voy a tratar de poner su lenguaje:
 * PARA EMPEZAR NO GRITEN.
 * Ezkrivan vien x fabor q no kuezta muchio.
 * No den ordenes ni exijan respuesta inmediata nunca jamás!
 * Aprendan comunicar al español con otros persona antes que quiere comunicar la máquina para C++.
 * Usen una coma un punto seguido dos puntos algo los signos de puntuación no muerden ayudan a entender mejor las oraciones gracias
 * Sean amables, soperútanos.

lunes, 11 de marzo de 2013

¿Cómo escribir aplicaciones portables?

Antes de decir nada tengo que hacer una aclaración sobre el título, y es qué entiendo por "portable", ya que es una palabra que se puede usar para indicar varias cosas y su significado por defecto en relación a aplicaciones de software creo que ha cambiado con el tiempo. Cuando yo uso "portable", me refiero a aplicaciones que pueden correr en distintos sistemas operativos o arquitecturas de software y hardware (por ejemplo, que puedo hacer andar tanto en Windows como GNU/Linux). La idea es que una aplicación es más portable cuanto menos depende de elementos específicos de un sistema operativo en particular. Creo que los desarrolladores seguimos teniendo ese concepto asociado a "portabilidad".

Sin embargo, actualmente muchos usuarios finales asocian "portable" al hecho de poder llevar la aplicación de una PC a otra en su pendrive para usar sin necesidad de instalarla, como un solo exe que se ejecuta y ya, o como un zip que solo hay que descomprimir. De hecho pueden encontrar googleando que por ahí alguien ofrece PSeInt portable o ZinjaI portable en este sentido, y supongo que todo lo que hizo ese alguien fue instalarlo en una pc y luego comprimir la carpeta de instalación en un zip/rar/autoextraíble/lo-que-prefieran. No se dejen engañar, mis programas se pueden copiar sin necesidad de instalar, siempre, cualquier versión, sin problemas ni modificaciones. El único trabajo adicional que hace el instalador es crear accesos directos y asociar las extenciones, pero sacando eso, no es más que un gran zip preguntando donde descomprimirse (lugar que tranquilamente puede ser un pendrive). Pero esa no es la idea de portabilidad que me preocupa, sino la anterior, y de los detalles de implementación relacionadas a esa primer interpretación es de lo que habla este post.

sábado, 2 de marzo de 2013

La importancia del testing

Cualquiera que trabaja en un ambiente profesional sabe que en un proyecto de software se dedican tiempo y recursos planificados para testing y control de calidad en general (QA). Se requiere gente capacitada y con un sexto sentido para averiguar como reventar un sistema en dos simples pasos (mi novia trabaja como tester y creanme que es increíble la facilidad que tiene para encontrar errores que jamás se me habría ocurrido siquiera buscar). Pero también, cualquier programador que desarrolla un proyecto artesanalmente por hobbie, fuera de toda formalidad como sucede a muchísimos proyectos de software libre, sabe lo tedioso que puede ser lograr eso. Ya lo dije muchas veces, en ZinjaI, en PSeInt, y en MotoGT desarrollo a mi ritmo, lo que creo necesario, y soy accidentalmente mi propio tester cuando uso las dos primeras herramientas en mi trabajo, o cuando juego un rato con el tercero.

Pero como buen seguidor del modelo de bazar de Raymond, trato de liberar seguido y esto convierte a mis usuarios en mi mayor recurso de testing. El proceso suele ser: cambio algo, lo pruebo en mi notebook mientras lo desarrollo (una prueba para nada general), lo publico creyendo ingénuamente que les va a funcionar a todos, y luego recibo unos cuantos reportes de errores. A veces son solo detalles, otras veces burradas importantes que no debieron publicarse nunca. Estos errores pueden hacerme perder muchos usuarios, ya que se pueden llevar una muy mala primera imágen y no volver. Pero más allá de eso creo que tengo que hacer una consideración especial, principalmente para con PSeInt: los usuarios son estudiantes que recién empiezan, y el software promete facilitarles el aprendizaje, pero el estudiante por su inexperiencia podría no distinguir un error en la interpretación de un error en su algoritmo. Esto ocurre, y atenta directamente contra el objetivo del proyecto, confunde al estudiante, va en una dirección perfectamente opuesta. Y entonces es doblemente preocupante. Por eso, hace un tiempo empecé a construir de a poco un sistema muy muy básico de testing automático para el núcleo del intérprete, y de eso habla este artículo.

miércoles, 13 de febrero de 2013

Feliz Cumpleaño!

Hoy se cumple un año desde el primer post de Cucarachas Racing. Lo normal es que quien cumple años reciba algún regalo, pero ¿qué se le puede regalar a un blog? (tal vez un poco de difusión, nunca viene mal, es lo único que se me ocurre). En fin, el punto es que no tiene sentido regalarle algo a un blog, pero como para celebrar igual que después de un año hay gente que sigue viniendo a leer o al menos mirar rápidamente las cosas que escribo, voy a invertir la costumbre y regalarles yo algo a esos lectores. Algo así como lo que les pasa a muchos cuando crecen y empiezan a trabajar, que tienen que llevar comida al trabajo el día de sus cumpleaños (¿que no era al revés cuando eramos chicos?).

Así que yendo al grano, como regalo de cumpleaños les ofrezco El Gran Libro Negro de las Cucarachas Pixeladas (badum, tish...). Y sí, ¿o esperaban que sortee un auto, o licencias de Windows originales? No, no hay tanto presupuesto, es solo un libro. Y no, no tiene nada nuevo, más que el formato. Más allá de lo rimbombante que suene su nombre, se trata de una recopilación de todo lo que ha pasado este año en este blog, pero en formato de libro digital. Por supuesto que libre y gratuito (bajo licencia CC BY SA).

sábado, 2 de febrero de 2013

¿Ser o no ser una tortuga?

Alan Perlis fue un pionero que se dedicó a las ciencias de la computación, especializándose en el estudio de lenguajes de programación (no en programar con ellos, sino en discutir sus diseños y fundamentos), lo cual incluso le valió el primer premio Turing (podríamos decir el Nobel de la informática). Entre las muchas cosas que escribió, hay una frase muy popular en el mundo de la programación que es la siguiente: "To understand a program you must become both the machine and the program". Podría traducirse como "para entender un programa de computadora tenés que convertirte en los dos, el programa y la computadora". Es una frase muy interesante que siempre acepté como válida (según mi experiencia) y jamás se me ocurrió cuestionar.

Por otro lado, Seymour Papert es un matemático del MIT que investigó entre otras cosas sobre la enseñanza y el aprendizaje en niños, las ciencias de la computación y la inteligencia artificial. Como fruto de todo esto, surgió el lenguaje LOGO, el de la tortuga. Además, escribió muchas cosas, entre ellas un libro genial llamado "Mindstorm: children, computers and  powerful ideas", donde habla del aprendizaje de los niños, de la enseñanza de la matemática, de su esperanza de que el uso masivo de computadoras cambiaría todo eso, y de cómo el lenguaje de tortugas fue concebido para empezar a dar ese paso. Papert sin duda fue un adelantado.

lunes, 28 de enero de 2013

Nada que no pueda hacer un script de bash (parte 2)

Siguiendo con esta idea de utilizar bash para combinar algunas de las cientos de pequeñas herramientas que se encuentran en casi cualquier GNU/Linux para automatizar tareas varias, en este segundo post traigo algunos ejemplos adicionales. Hay que aclarar, que al igual que en la primer parte, los ejemplos no están explicados 100%, sino que se comenta rápidamente qué hacen y cómo. Un lector con algunos conocimientos mínimos de programación y del uso de la linea de comandos debería poder entender los ejemplos, pero seguramente necesitará googlear un poco más o consultar los manuales para poder modificar estas ideas para sus propias necesidades. De todas formas, el objetivo era solo tirar la primera piedra, para despertar un poco la curiosidad, y si les interesa podrán encontrar fácilmente mucho más material.

lunes, 21 de enero de 2013

Nada que no pueda hacer un script de bash (parte 1)

El título de este post es una frase que uso mucho. Bash, el shell más común en sistemas GNU/Linux, es un intérprete de comandos en modo consola. Soy de esos que usan mucho mucho la consola, porque creen que así las cosas se hacen más rápido. Mucho más rápido, solo que hay que saber un montón muy grande de trucos, nombres comandos, y argumentos, en apariencia crípticos. Por eso la gente prefiere las ventanitas gráficas, porque no hay que recordar nada, todo es intuitivo. Y las ventanas son geniales para eso, pero es ridículo a mi criterio (y el de otros, recomiendo mucho esta vieja lectura, también en español), comparar las limitaciones de una interfaz gráfica simple, con la potencia de una simple linea de comandos.

Pero tampoco es que tengamos que recordar tantos comandos. Diría que la mayoría de los que usamos las terminales usamos regularmente un 5% de los comandos disponibles, y solo sabemos un 3% de sus argumentos. Es así, se puede hacer mucho con poco. Y si somos haraganes, o nos gusta automatizar todo, podemos tomarnos el trabajo de armar un script con las partes difíciles, largas o tediosas, para luego nunca más tener que escribirlas otra vez, sino simplemente invocar al script. Yo tengo mi notebook llena de pequeños scripts, para todo. Y por eso en realidad no sé tanto de bash, porque las operaciones simples son pocas, y las complicadas están dentro de scripts, así que no necesito memorizarlas. Pero sí necesité ejemplos en primera instancia para hacer esos scripts. Y de eso se tratan estos posts. Pienso presentar algunos ejemplos cortos y explicarlos para que vean la potencia de bash y otras herramientas con las cuales se combina, y para que vean el tipo de cosas que se pueden hacer. Espero que aprendan algo, los motive a acercarse a las lineas de comandos, y se les ocurran ideas para sus propias tareas.

jueves, 10 de enero de 2013

¿Todos para uno o uno para todo?

Ya expliqué hace poco que PSeInt está compuesto por varios programas separados, la mayoría de ellos independientes. El usuario percibe al conjunto de programas como si fuera uno, con varias partes trabajando en conjunto. wxPSeInt es el programa que se encarga de ser la interfaz con el usuario, y de gestionar la ejecución de los otros de forma más o menos transparente. Veamos ahora porqué esto es así y qué tiene de interesante o no, según mi experiencia con este modelo.

Empezando por el porqué, tengo que decir que es más bien una cuestión histórica. Primero que nada, lo que quería escribir cuando empecé con PSeInt era solo un intérprete (el módulo pseint), el editor de texto surgió inmediatamente como agregado necesario para poder mostrar las bondades del intérprete, pero los demás módulos no estaban previstos. Desde ese punto de vista, tendría solo dos módulos, un editor de texto y un intérprete de consola. La comunicación sería mínima: el editor guardaría el pseudocódigo en algún temporal y lanzaría el intérprete diciéndole por argumento en la linea de comandos donde estaba ese temporal. Si había errores, el camino de vuelta también sería mediante un archivo temporal. Esto sonaba razonable, y este era más o menos el modelo que seguían la mayoría de los IDEs en lenguajes reales, así que jamás se me cruzó por la cabeza plantear otra alternativa. Mucho tiempo después se fueron agregando algunos módulos nuevos que tampoco requerían de mayor comunicación, como el visualizador (no editor) de diagramas de flujo, o el que exporta a código C++. Por eso seguí con el mismo esquema. Tal vez la primer duda respecto a si este era el camino a seguir vino cuando quise integrar la ejecución paso a paso, y también más tarde para el análisis sintáctico en tiempo real.

domingo, 30 de diciembre de 2012

Destripando PSeInt

PSeInt es un programa compuesto por muchos programas. Es decir, consta en realidad de varios ejecutables que se invocan y comunican entre ellos, de forma tal que para el usuario final se ven como partes de un único entorno. En este artículo voy a comentar cuales son esas partes (desde ahora módulos, cada uno un ejecutable), y cómo y cuando se comunican. La idea es que sirva de referencia para el siguiente artículo donde discutiré porqué es así, porqué las cosas están separadas o juntas, porqué se comunican de esa manera, y qué tiene esto de bueno o de malo según mi experiencia y las necesidades particulares de este proyecto. De paso, también sirve de documentación para mí y para los que quieran mirar el código fuente.

Primero voy a hacer una descripción rápida de qué hace cada módulo, y luego cómo se relacionan. En este análisis dejo de lado intencionalmente a psdraw, ya que sus funcionalidades serán absorbidas por psdraw2 (algunas ya lo fueron, y las que no, lo serán en las próximas versiones).  Los módulos que componen entonces al sistema de PSeInt son:

domingo, 16 de diciembre de 2012

Codificar y ejecutar, ¿serie o paralelo?

Se viene algo grande en PSeInt. Por suerte 2012 ha sido un año de muchos muchos avances, y parece que 2013 también va empezar con novedades. Había advertido que no iba a hacer nada nuevo por un buen tiempo, pero me topé con un concepto demasiado bueno como para andar esperando tanto. Navegando sin rumbo llegué a un post de un tal Bret Victor, un tipo que parece tener ideas más que interesantes sobre cómo deberían ser los entornos de programación (entre otras cosas) y cómo la gente debería aprender a programar. Gracias a ese artículo dí con este video. Si miran el video (que dura más de una hora, pero yo solo vi los primeros 20 minutos cuando me decidí a empezar todos estos cambios), van a entender de qué se trata. No estoy 100% de acuerdo en todo lo que propone, pero sí en su gran mayoría, al menos pensando a nivel didáctico que es lo que me ocupa en PSeInt. Y hay momentos de la charla realmente fantásticos, de esos que le abren a uno la cabeza y lo hacen ver las herramientas que tenía desde un punto de vista completamente nuevo.

El tipo plantea un entorno de desarrollo donde los pasos para programar no son primero codificar, luego ejecutar para ver que sale, y repetir; sino que propone codificar y ver qué sale en simultáneo. Es decir, a medida que el programador va codificando el programa, este se va ejecutando, y si a mitad de una ejecución cambia algo del código fuente, la ventana de ejecución refleja inmediatamente esos cambios. El video muestra otras cosas interesantes, pero esa idea tan simple y complicada a la vez fue la que más me impactó. Aquí les presento mi video, de solo 2 minutos, con algunas de estas ideas llevadas a PSeInt:

miércoles, 12 de diciembre de 2012

Trucos para depurar con ZinjaI

Este artículo bien podría llamarse "Tips para convertirse en un ZinjaI Master (parte 5)", pero preferí ponerle un título diferente donde aparezca la palabra "Depuración" ya que trata de este tema en particular, y los tips son algo más específicos. En la pestaña Depuración del cuadro de Preferencias (al cual se accede con el ítem "Preferencias..." del menú "Archivo"), los tres últimos ítems son bastante particulares, pero bien utilizados ayudan mucho.

El primero, "Mejorar inspecciones automáticamente según tipo", hace que cuando ingresemos (durante la depuración) una inspección de algún tipo configurado allí (se configuran con el botón "Opciones" que tiene al lado), ZinjaI la modifique automáticamente. Por ejemplo, cuando trabajamos con la clase std::string, usualmente queremos inspeccionar el contenido de la cadena, y no la estructura de la clase. En gcc, por ejemplo, esta clase tiene el contenido del string en un puntero llamado _M_p que está dentro de un struct miembro llamado _M_dataplus; y la clase tiene además otras cosas que en general no nos interesa ver, como el npos. En resúmen, si el string es s, no interesa evaluar solamente el valor de "s._M_dataplus._M_p" en lugar de "s". Sin esta opción, hay que buscar dentro de la clase el atributo que queremos, lo cual se hace fácilmente con un par de dobles clicks sobre el valor de la inspección y borrando luego las inspecciones que sobren, pero se torna tedioso y repetitivo. Con esta opción, ZinjaI puede hacerlo automáticamente.

lunes, 10 de diciembre de 2012

Tips para convertirse en un ZinjaI Master (parte 4)

En la última (eso creo) entrega de esta serie, voy a hablar un poco de la personalización de ZinjaI. Es decir, de cosas que podemos configurar desde las preferencias o desde las opciones de proyectos, generalmente para mayor comodidad. No voy a cubrir todo lo que se puede configurar en ZinjaI, sino sólo lo que me parece destacable en el contexto de esta serie de posts.

Para empezar, hay una opción en la pestaña "General" del cuadro de Preferencias (al que se accede con el ítem "Preferencias..." del menú "Archivo") que dice "Ocultar paneles automáticamente". Cuando digo paneles me refiero a esas subventanas que aparecen en los bordes de la ventana principal, como el arbol de archivos, los resultados de la compilación, la ayuda rápida, el árbol de símbolos, etc. Por defecto, estos paneles aparecen cuando alguna acción en ZinjaI los necesita (por ejemplo, el de compilación al compilar) y se quedan ahí ocupando buen espacio hasta que los cerremos. Y si el monitor no es tan grande, ese espacio es importante, así que molestan. Algunos desaparecen con la tecla Escape, otros no. Pero si los cerramos, a algunos después hay que ir a buscarlos al menú cuando se necesitan otra vez, o aprender algún otro atajo de teclado (y creo que ya tienen bastante por ahora). Entonces no es tan cómodo.

jueves, 6 de diciembre de 2012

Tips para convertirse en un ZinjaI Master (parte 3)

Después de darles algunos tips para moverse fácilmente por el código, y para realizar algunas operaciones de edición básicas en un periquete, en esta tercera parte voy a comentarles sobre algunas otras funcionalidades afines que han quedado fuera de las dos primeras para no hacerlas tan largas, o porque no son tan triviales.

Por un lado están los autocódigos. Ya hablé de ellos en otro post, así que no voy a volver a explayarme. Si no saben lo que son, escriban "fori(N)" (reemplazando N por lo que quieran) y presionen la tecla Tab justo después de cerrar el paréntesis. Tengo que decir que agregarlos me llevó bastante tiempo porque no me ponía de acuerdo conmigo mismo acerca de cuál sería la forma menos intrusiva de invocarlos (problema cuya solución inspiró NetBeans si mal no recuerdo a través de un comentario de un usuario). Pero una vez implementados, resultaron mucho más útiles de lo que imaginaba, y ahora no vivo sin ellos. Pueden seguir el link que puse antes para ver cuales hay configurados por defecto y cómo definir nuevos con lo que ustedes quieran o necesiten.

lunes, 3 de diciembre de 2012

Tips para convertirse en un ZinjaI Master (parte 2)

Ya les revelé en el post anterior "secretos" varios para deslizarse de un punto a otro de su proyecto con apenas un puñado de teclas. Digo "secretos" entre comillas porque estos atajos no son secretos para nada. Están a la vista en los menúes y la mayoría comentados en la ayuda. Pero por alguna misteriosa razón, el 99% de los usuarios no los ve, entonces, cuando uso algunos de estos atajos en público no falta quien me pregunte cómo hice eso tan rápido. ¿Después de al menos un cuatrimestre de programar con ZinjaI, jamás le pegaron una mirada al menú Editar para ver que había?. Supongo que la respuesta es no, yo tampoco lo haría al principio. Soy de los que empiezan a usar y ya, sin manuales; pero cuando me decido a adoptar finalmente una herramienta para un trabajo prolongado me tomo un ratito para jugar con su interfaz y ver qué cosas pueden ser útiles que no conozca. En fin, en esta segunda entrega, quiero comentar atajos de teclados para pequeñas tareas de edición, bastante triviales, pero que hacemos millones de veces mientras programamos.