lunes, 2 de diciembre de 2013

SFML y sus dependencias

Los cambios en la interfaz binaria de los objetos compilados con MinGW hicieron que deba recompilar algunas bibliotecas externas. Compilar una biblioteca no siempre es fácil en Windows, y encima con SFML me llevé algunas sorpresas interesantes que vengo a comentar aquí.

Las bibliotecas libres suelen tener sus procesos de construcción basados en alguna herramienta libre para tal fin, como pueden ser los scripts de autotools, o la herramienta cmake. Estas herramientas son comunes en GNU/Linux, pero no en Windows (lo común en Windows creo que sería tener un proyecto de Visual Studio). Entonces, como conseguir un entorno apto para estas compilaciones no es tan directo, siempre que podamos conseguir las versiones ya compiladas de las bibliotecas para Windows, mejor (más fácil y más rápido). Es lo que pasó al principio con SFML. Para armar el complemento de sus primeras versiones (1.5 y 1.6), yo no compilé SFML, sino que bajé la versión compilada que se ofrece en su sitio oficial y le agregué lo necesario para utilizarla en ZinjaI (como las plantillas de proyectos ya configurados y los indices de autocompletado).

viernes, 29 de noviembre de 2013

Creación de complementos. Paso 2: extras

Ya tenemos un proyecto que anda, y configurado de forma que solo copiando un par de carpetas de un ZinjaI a otro podemos replicarlo. En esta tercera parte vamos a pulir algunos detallecitos y a generar el bendito índice de autocompletado que hará que ZinjaI nos ayude a utilizar las clases y funciones de la biblioteca mientras escribimos el programa cliente.

Empecemos por generar el índice. Lo vamos a hacer automáticamente a partir de las cabeceras (los .h y .hpp). Esto no siempre es lo mejor, porque a veces tienen definidas cosas demás, que no nos interesan para el autocompletado (como las guardas), o porque a veces no se condicen con la documentación. Digamos por ejemplo que para una clase Ventana la documentación dice que va "#include <Ventana.h>", pero en realidad Ventana.h no tiene la clase sino un montón de #ifs que según el sistema operativo hacen un #include diferente con la versión de la clase para cada sistema operativo. El parseo automático dirá por ejemplo que Ventana está en <Win32/Ventana.h> mientras que lo correcto es poner solo <Ventana.h> o de lo contrario no compilará en otro sistema. Como este hay muchos casos, y por eso los índices de wxWidgets y SFML-1 se generaron parseando los archivos de la referencia HTML y no las cabeceras. Pero este parseo es ad-hoc y requiere mucho trabajo (y programar), así que vamos por la forma fácil y esperemos que no traiga demasiados problemas.

sábado, 23 de noviembre de 2013

Creación de complementos. Paso 1: relatividad

En el post anterior conté algo sobre algunos problemas que aparecían al querer utilizar bibliotecas externas en un proyecto de ZinjaI, y expliqué la solución a un ejemplo paso por paso. El ejemplo se basaba en la biblioteca OpenCV en su versión para Windows. Si siguieron más o menos esos lineamientos, deberían poder compilar un programa básico con OpenCV y verlo corriendo. En ese caso tuvimos que, además de configurar el proyecto, compilar la biblioteca.

En este segundo post vamos a reacomodar esos archivos de la biblioteca, para tener lo justo y necesario en una sola carpeta, carpeta que estará dentro de la carpeta de instalación de ZinjaI para evitar andar desparramando más archivos por el sistema, y para que además podamos llevarla a cualquier otra PC y sin importar dónde se halla instalado ZinjaI en esa otra PC, el proyecto compile igual sin cambios. Todavía se podrán ajustar más detalles muy útiles (como el autocompletado por ejemplo) antes de tener todo listo para armar finalmente la plantilla y el complemento, pero eso quedará para una tercera parte.

martes, 19 de noviembre de 2013

Creación de complementos. Paso 0: configurar un proyecto

Alguien en el foro preguntó cómo hacer para utilizar OpenCV (una biblioteca con todo tipo de utilidades para cuestiones relacionadas a la visión computacional y bastante popular por estos días) en ZinjaI y en Windows. Alguna vez ya escribí de forma genérica acerca de cómo configurar un proyecto en ZinjaI para utilizar una biblioteca. Eso sigue siendo bastante cierto, pero el detalle del cambio de ABI del compilador que comenté en este otro post complicó las cosas. Y aún sin ese problema, las instrucciones aquellas son solo para compilar, pero nos vendría bien también armar una plantilla de proyecto, tener un índice de autocompletado, tal vez acceso a la referencia, etc. Entonces hoy voy a tomar el caso de OpenCV como ejemplo y contar paso a paso cómo armar todo eso y empaquetarlo en un complemento para instalar en ZinjaI en dos pasos. Espero que con este ejemplo los usuarios más interesados se animen a amar sus propios templates, autocompletados, o hasta complementos para compartir con los demás usuarios de ZinjaI.

martes, 8 de octubre de 2013

Exportar un pseudocódigo a un lenguaje real

Desde hace muchísimo tiempo, PSeInt tiene la opción para exportar un pseudocódigo a C++. Es decir, para generar un código C++ que haga exactamente lo mismo que hace un algoritmo en pseudocódigo al ejecutarse en PSeInt. No siempre es posible, pero en general se puede obtener una buena aproximación. El objetivo de esta funcionalidad es bastante dudoso. Definitivamente no está pensado para que generen a través de PSeInt programas reales (es decir, para no tener que aprender un lenguaje real, sino hacerlo acá y convertirlo). Está pensado para servir como ayuda cuando el estudiante empieza a aprender un lenguaje real, luego de haber adquirido lo básico mediante el pseudocódigo. Para generar una sintonía entre lo que ya conoce y lo que está aprendiendo.

El único motivo por el cual se convierte a C++ y no a otro lenguaje es porque C++ es el lenguaje que domino bien, en el cual me siento cómodo, y del cual creo conocer lo suficiente como para decidir cómo conviene hacer las traducciones. Pero muchos docentes que utilizan PSeInt para comenzar, luego pasan a otros lenguajes, y me gustaría que PSeInt también pudiera exportar a muchos de esos otros. En este post voy a contar un poco cómo espero lograrlo, solicitando la colaboración de los docentes (o usuarios en general) que tengan gran conocimiento de esos otros lenguajes para proporcionar ejemplos, y voy a hablar también de los problemas y desafíos que esta traducción supone.

jueves, 26 de septiembre de 2013

Variables de entorno, shells y scripts en GNU/Linux

Estoy tratando de agregar algunas opciones a ZinjaI para poder controlar la forma en que ejecuta los programas que compila. Actualmente, gracias a los toolchains alternativos se puede modificar por completo la forma en que se compila un proyecto (utilizando un makefile personalizado, o hasta un script). Ahora quiero poder hacer algo parecido con la ejecución, pero aquí hay ciertos detalles interesantes a tener en cuenta. ¿Para qué serviría esto? Algunos ejemplos son casos donde lo que ZinjaI compila es parte de algo más grande y lo que en realidad hay que ejecutar es ese algo (como los organismos para la comvida por ejemplo). En otros casos hay que correr el ejecutable a través de una herramienta (por ejemplo al utilizar mpi para paralelizar, a través de mpirun). Pero el caso más útil será cuando simplemente se quiera hacer algo antes de la ejecución, como borrar/crear archivos, o definir variables de entorno, para luego ejecutar normalmente. El problema es que hay algunas particularidades de cómo se lanzan nuevos procesos hijos desde un proceso padre en GNU/Linux, y de cómo se gestionan los entornos en los shells que interpretan los scripts, que me han dado más de un dolor de cabeza. Finalmente llegué a una forma muy simple de hacer más o menos lo que quería, forma que no pude encontrar buscando en Google, y por eso vengo a comentarla.

jueves, 19 de septiembre de 2013

Getters y setters automágicos en C++

Hablando con un amigo y colega hace unos días, me comentaba que en Haxe, un lenguaje con varias cosas tomadas (aparentemente) de actionscript y javascript, se pueden definir atributos con getters y setters en una linea como esta: "public var(A,B)", donde A y B pueden ser "null" si no queremos que se puedan ver o modificar desde fuera de la clase, "default" si queremos que se pueda como si fueran públicos, "get" o "set" si más abajo queremos implementar un getter o setter especial, y otras variantes. Algo interesante de esto es que desde el programa/función "cliente" de la clase (el que la usa para algo mediante su interfaz pública), el acceso a estos atributos no cambia de un caso a otro, sino que es siempre igual, como si fueran públicos. Pero en realidad se mete en medio (si queremos) de forma transparente el getter/setter propio.

A esta clase de cosas que parecen pero no son simples atributos públicos, muchos lenguajes las llaman propiedades. Inmediatamente me acordé de las clases para representar widgets en las ventanas con Borland Builder, donde podía hacer edit1->text="hola" en lugar de edit1->SetText("hola") sin problemas. Y dije: "esto se puede hacer igual de transparente en C++". En el caso de objetos de una interfaz gráfica, hay varias formas de que parezca transparente, pero mi idea era generalizarlo, y plantear algún mecanismo para lograr esto con cualquier atributo sin meter mucho ruido en el código de la clase.

lunes, 9 de septiembre de 2013

Sobre la Programación Orientada a Objetos

Me crié (hablando de programación) con Basic, y con uno de los viejos, donde había que ponerle a todo números de lineas y no teníamos subs. Eso hizo que mi forma de pensar un código fuera fuertemente "estructurada". Más tarde, alguien me sugirió QBasic como una forma de hacer lo mismo que hacía en Basic (el mismo código) pero con un editor más bonito. Explorando qué más tenía QBasic encontré las subs (funciones o subrutinas) y eso me hizo un poco más modular. Cuando pasé a VisualBasic, mi forma de pensar no cambió. La poca y bizarra orientación a objetos de los primeros VB pasó totalmente desapercibida para mí, y sólo incorporé el concepto de evento.

Con ese background (que llevó varios años y estaba bien acentado), entré a la universidad y me dispararon directamente con la Programación Orientación a Objetos (POO) y bastante de C++. Además, era el primer año que la materia se daba en C++; los docentes eran muy buenos programadores con Pascal/Delphi, y tuvieron que aprender C++ solo para actualizar la materia. Todo esto y más hicieron que la orientación a objetos parezca algo forzada. Y si bien no la cuestioné de entrada, tampoco la entendí ni aproveché tanto en mis primeros proyectos. Solo para la parte visual parecía realmente tener sentido.

domingo, 1 de septiembre de 2013

Exprimiendo mejor al Diagrama de Flujo

Con la verificación de sintaxis en tiempo real, una mejor sincronización con la ayuda rápida, las plantillas de estructuras de control de la derecha, y la lista de funciones y operadores de la izquierda, el autocompletado y los tooltips, el indentado inteligente, y algunos otros detalles, creo que la interfaz para escribir un algoritmo en pseudocódigo en PSeInt está bastante bien encaminada y completa. La que no está taaan completa es la de edición de diagramas de flujo, ya que hasta hace poco, si bien se podía editar el diagrama y mandar a ejecutar directamente desde ese editor, tenía varias falencias. Por ejemplo, si había errores de sintaxis, había que volver al pseudocódigo para ver cuales eran y dónde estaban, o si se quería hacer un seguimiento paso a paso también. Estas cosas están cambiando, y en este post les cuento las novedades (a nivel usuario) que ya están listas en el repositorio, y también los cambios de diseño interno (a nivel desarrollador) que tengo que analizar antes de seguir en esta linea.

miércoles, 28 de agosto de 2013

Primeros pasos con git (parte 1)

Lo prometido es deuda, así que vamos a empezar a hacer cosas con git. En este post vamos a crear un repositorio "central" en algún lado, clonarlo en otro, y luego modificarlo y publicar los cambios en el primero, para que después un tercero pueda obtener también esos cambios. En realidad este post no es más que una excusa para documentar en algún lado lo básico de mi forma de trabajar con git para la próxima vez que empiece un proyecto, porque ya voy armando una receta y me la suelo olvidar.

Antes de empezar aclaro que considero a un repositorio como "central", al de sourceforge si estamos hablando de alguno de mis proyectos públicos, o a un repositorio en una carpeta especial de mi disco si estamos hablando de uno privado, pero acuérdense que es solo una idea mía, a git le da igual cualquiera. Luego, en otro lugar, en una carpeta de trabajo, hago los cambios y los subo al "central". Más tarde si alguien más quiere ver que hice se baja los cambios, o si yo mismo quiero seguir en otra pc, me los bajo también.

lunes, 12 de agosto de 2013

Mejor interfaz para los errores en PSeInt

Siempre digo que aprender a programar involucra aprender dos o tres grandes cosas: en un primer escalón los fundamentos (la lógica), luego el lenguaje, y tal vez un poco más abajo las herramientas (el compilador y el IDE). No es fácil aprender todo al mismo tiempo, y creo que sin dudas los fundamentos son lo primero y más importante, son la parte más universal y duradera de este conocimiento. Por eso siempre planteo que para enseñar a programar debemos primero sentar buenas bases en este aspecto tratando de que los otros dos no "molesten" demasiado. Para evitar que el lenguaje "moleste" es que utilizamos el pseudocódigo. Para evitar que la herramienta "moleste" es que, o bien no utilizamos ninguna (pseudocódigo solo en papel como le gustaba a Dijkstra), o bien propongo PSeInt. Es decir, el pseudocódigo debe ser natural y flexible para que los errores que consuman el tiempo sean los de lógica, y la interfaz intuitiva y rápida para que tampoco desvíe la atención, de forma que todo esto se vuelva invisible.

La interfaz de PSeInt arrastra varias decisiones de diseño tomadas por razones "históricas" a veces, técnicas otras, o hasta simplemente por no pensarlas demasiado. En los últimos años he intentado pensarlas más y con un sentido didáctico, pero arrastrando la inercia inicial. Un punto importante y ejemplificador de esto que hablo es la forma en que se muestran los errores de un algoritmo dentro del editor. En este artículo cuento los porqués de algunos cambios que estoy probando para la próxima versión, y los invito a dejar sus opiniones.

martes, 6 de agosto de 2013

Primeros pasos con git (parte 0)

Trabajé durante mil años sin usar sistemas de control de versiones (cosas como svn, cvs, git, mercurial, bazaar, etc) ni nada parecido, y durante todo ese tiempo no sentí la necesidad de hacerlo. Principalmente porque trabajaba solo, o en pequeños grupos, entonces el modelo de llevar y traer zips/tgzs fechados alcanzaba como para no complicarse "por demás" con todo un repositorio. Sin embargo, en algún momento quise ofrecer el código de ZinjaI y PSeInt "en tiempo real" (que cada cambio que haga esté inmediatamente disponible para quien lo quiera probar), porque eso es algo que me gusta de muchos proyectos de los que soy usuario, y porque tiene otras ventajas adicionales (como por ejemplo que algunos usuarios puedan ayudar con el testing de forma temprana).

Hasta entonces, como dije, solo había usado los sistemas de control de versiones para clonar repositorios ajenos y nada más. A partir de ese momento, empecé a experimentar un poco con crear repositorios, hacer y publicar cambios, etc. Y tuve que elegir un sistema en particular, y me incliné por git porque era el que estaba de moda, y porque es un producto que nace de la mano del mismísimo Torvalds para gestionar nada menos que El Kernel, así que potencia y flexibilidad estaban garantizadas. Además, su popularidad prometía mucha documentación actualizada, es decir, un fácil y rápido aprendizaje.

jueves, 25 de julio de 2013

MinGW y las calling conventions

Ya hace más de 6 meses que no vemos publicada una nueva versión "oficial" de ZinjaI. Es normal que en el primer tercio del año los esfuerzos se dirijan mayormente a PSeInt, y este año se han presentado motivaciones adicionales para que así sea aún en mayor medida y por algo más de tiempo. Sin embargo, el desarrollo de ZinjaI nunca se detiene por completo, y quienes observan de tanto en tanto el repositorio saben que siempre hay algo nuevo, aunque solo sea un bug. Pero esta vez hay una razón más para retrasar el lanzamiento de una nueva versión, y esta es un cambio importante en mingw (el port del compilador gcc a Windows). Siempre lleva tiempo actualizar gcc ya que hay que "armarlo" por partes, compilar algunas bibliotecas que agrego en ZinjaI, y luego acomodar y empaquetar todo, pero esta nueva versión tiene algo especial. En qué consiste este cambio y cómo nos afecta a los usuarios de ZinjaI es lo que voy a tratar de explicar en este post.

miércoles, 10 de julio de 2013

En cajas de 12

Programar me divierte, y mucho. Pero estoy hablando de resolver problemas interesantes, no de hacer ABMs y páginas webs para el negocio de la esquina (no lo tomen a modo despectivo). Me refiero a problemas de optimización, algoritmos y estructuras de datos por ejemplo. Por eso, cuando veo algún contest de programación, intento participar. Un contest de programación es una competencia, donde hay que resolver problemas programando, y gana el que resuelve más problemas, o el que los resuelve en menos tiempo, o el que hace el código más eficiente. Allí suelen aparecer problemas muy interesantes, y suele ser además el pie para después sentarme a aprender algo nuevo (a pelear otra vez con ese problema que no me salió durante la competencia). Un contest de mucho nombre a nivel mundial es el Google Code Jam, y ya se imaginarán por qué. Empecé a participar ahí creo que en 2008, y hasta el día de hoy sigo más o menos igual: cada año avanzo dos o tres rondas, pero nunca llego a las finales, y usualmente ni siquiera estoy cerca. Solo un año me gané una remera, pero ese año el contest no era global, sino limitado a Latinoamérica.

Cuando me inscribí por primera vez en el sistema online para participar, tuve que llenar un formulario con varias preguntas, entre ellas una que decía si me gustaría trabajar en Google. Obviamente Google busca, además de buena publicidad, identificar buenos programadores para reclutar. Como todo geek que se precie de tal dije que sí sin pensarlo porque: a) ¿a quien no le gustaría trabajar en la empresa más importante del mundo en lo que a software se refiere? b) ¿qué importa qué responda, si total está claro que está fuera de mi alcance? Pero todo esto viene al caso, por algo que pasó hace poco.

martes, 2 de julio de 2013

Herramientas mágicas: CppCheck

En la primer entrega de la serie Herramientas Mágicas les presenté Valgrind, un analizador dinámico. Lo de dinámico es porque analiza al programa en movimiento, mientras se ejecuta. No es el único de este tipo, ya volveremos a eso, pero ahora voy a presentar un analizador estático: CppCheck. Esto quiere decir que, por el contrario, este tipo de analizador no ejecuta al programa en cuestión, sino que se basa solamente en inspeccionar muy minuciosamente su código fuente.

Para hacer una analogía con algo conocido, digamos que un analizador estático es parecido a medio compilador. Sería la parte del compilador que mira el código generando los warnings y errores, no la que traduce. Pero el objetivo del compilador es traducir a código máquina. Dado que para ello tiene que hacer un análisis previo del código fuente, va detectando "de paso" (como efecto colateral) potenciales errores que avisa en forma de warning. Pero solo hace el análisis necesario para traducir y eventualmente optimizar, y no pierde tiempo en otros detalles. Un analizador estático como CppCheck, en cambio, tiene por objetivo el encontrar errores, por lo que el tipo de análisis que hace toma más tiempo, para detectar cosas más específicas o intrincadas.