jueves, 2 de julio de 2015

Mientras tanto, en... (III)

Van dos meses sin novedades visibles en PSeInt: sin publicar versiones nuevas, sin hacer comentarios en el blog y sin terminar de ponerme al día con el foro. Por el lado de ZinjaI, pasa algo similar (no hay versiones desde hace 4 meses), aunque es más común dado que los cambios en ZinjaI usualmente requieren más tiempo y más pruebas. Y para completar, hace casi un mes que no escribo nada en el blog. En ambos proyectos hemos visto períodos mucho más largos sin novedades, pero no quiere decir que esa situación me simpatice. Me gusta que siempre haya algún movimiento, por mínimo que sea. Y en verdad lo hubo. Tratando de seguir la filosofía "release erale, release often", en breve lanzaré un par de actualizaciones para compartirlos. Mientras tanto, les cuento por dónde pasan los cambios y les adelanto un "trailer" de la próxima release.

Empecemos por PSeInt que es donde creo que está lo más interesante. Antes de que se ilusionen mucho, advierto que no hice ninguna mejora importante en el lenguaje, no hay cosas nuevas en ese sentido. Pero sí hay cosas muy interesantes a nivel interfaz/presentación, y la mayoría de ellas pasan por el editor de diagramas de flujo. La nueva versión tendrá un editor visualmente renovado. Si bien los diagramas serán en esencia "casi" los mismos, creo que se verán mucho más lindos.

Lo primero que hice, fue finalmente reemplazar la siempre fiel pero muy tosca fuente que usaba (la ugly-font, gentileza del genial capitán YS), por una fuente real. Digamos que poner texto "escalable" en OpenGL no es una tarea trivial, pero hay soluciones no tan complejas que quedan razonablemente bien. Opté por poner en una textura todos los caracteres del código ascii renderizados con una fuente real (usé Deja Vu Sans Mono, por ser libre y monospace) y un tamaño mediano, y armar los textos cortando y uniendo pedacitos de esa textura. El resultado no es súper genial, pero sí mucho mejor que lo que tenía.


Lo segundo es mucho más interesante: comentarios! Sí, ahora se pueden ver/agregar/quitar comentarios en el diagrama de flujo. Hay un tipo de entidad nuevo, que se muestra a un costado, en gris y líneas de puntos para tener menos peso visual, que representa un comentario. Puede ser una línea con solo el comentario, o bien un comentario asociado a una instrucción o estructura de control. El último caso, en pseudocódigo, sería un comentario que se pone en la misma linea que la instrucción, al final. En el diagrama, la entidad del primero se "conecta" (une con linea punteada) al punto en el flujo del algoritmo en donde debe insertarse dicho comentario, mientras que la del segundo se conecta a la entidad de la instrucción a la que está asociada. Esto hace que el pasaje (ida y vuelta) entre código y diagrama sea ahora 99% fiel. Ya casi no hay pérdida entre un formato y el otro. Las "pérdidas" que restan son: algunos comentarios al final del pseudocódigo fuera de todo proceso o subproceso (todavía no está bien resuelto en el diagrama), las líneas en blanco para separar visualmente partes del algoritmo en el pseudocódigo, o algún reformateo que se le hace a cada instrucción a modo de normalizado al pasar al diagrama. Son cambios que nunca alteran el algoritmo, sino solo su presentación, y en la mayoría de los casos ni eso.


Por otro lado, reemplacé el menú que tenía el editor de diagramas en la esquina superior izquierda por una barra de herramientas, que ofrece un acceso más rápido a las mismas opciones, una interfaz más coherente en relación a la ventana principal, y algunas acciones nuevas. Entre las acciones nuevas se destacan un conjunto de botones para configurar la presentación del diagrama. Ahora se puede, por ejemplo, alternar entre diagramas clásicos y diagramas Nassi-Shneiderman desde el mismo editor de diagramas, sin salir ni recargar el algoritmo. De igual forma, se puede habilitar y deshabilitar el coloreado de las entidades por tipo, mostrar u ocultar los comentarios, y habilitar o deshabilitar una nueva opción que hace que los textos de las entidades que son demasiado largos se muestren abreviados para que el diagrama no se deforme tanto y se vea mejor el flujo. He aquí una demo del nuevo editor:



Pasando ahora a lo que respecta a ZinjaI, los cambios no son muy grandes, pero todos los detalles suman. Para empezar, corregí algunos problemas relacionados al uso de C++11 y/o C++14. En particular, algunas funciones lambdas podían mostrarse mal en el trazado inverso (o hasta hacer que el entorno se cerrase), y algunas palabras claves (como final y override) confundían al parser y degradaban el autocompletado. Por otro lado, investigué por qué ZinjaI tardaba tanto para analizar la configuración de un proyecto con muchos fuentes para saber qué recompilar y qué no antes de ejecutarlo, y solucioné ese problema. En mi propia notebook el proyecto ZinjaI (con más de 250 fuentes entre cpps y hs) tardaba de 3 a 5 segundos, y ahora tarda menos de uno. También reacomedé un poco los archivos, tanto en la carpeta ZinjaI, como en la carpeta donde se guarda la configuración en el home del usuario. En la primera, todos los binarios auxiliares de ZinjaI están un subdirectorio "bin", y todos los de herramientas externas en uno "third". Esto soluciona además algunos pequeños problemas al utilizar otras instalaciones de MinGW. En la segunda separé las configuraciones de los temporales para que sea fácil limpiar lo innecesario, o copiar lo útil al cambiar de PC. Finalmente agregué una herramienta externa más al menú de herramientas, que sirve para analizar complejidad ciclomática (ya hablaré más de esto en el próximo post).

En ambos proyectos hubo además correcciones menores como siempre, y algunos cambios internos interesantes para mejorar los códigos, pero que no notará el usuario final. Para completar el informe de situación, en MotoGT, no hubo mucho más desde el último post al respecto. Tengo 90% resueltos los menúes y el manejo interno de perfiles y campeonatos, pero todavía 0% resuelta la escena de la carrera, que es la más importante. Lo último que queda por comentar, es que junto con las próximas releases de ZinjaI y/o PSeInt, van a ver también algunos cambios en los sitios web, para modernizarlos un poquito (nada muy grande, pero sí detalles que suman). Y eso es todo por hoy, no se pierdan la próxima edición de "Mientras tanto, en..." (Nana-nana-nana-....).

5 comentarios:

  1. Hola Pablo, visualizar los comentarios en el diagrama de flujo esta genial, ya no hay perdida de información al editar el diagrama, pero estoy en PAUSA con respecto a PSEINT, pues los algoritmos que programo requieren de 2 instrucciones mágicas que no las puedo solventar con los comandos actuales, la una es convertir una cadena que contiene una expresión aritmética a valor numérico ejemplo "3+4" evaluada retorna 7, la otra funcion es que una funcion pueda retornar una arreglo por lo menos unidensional con esto PSEINT abarcaría o mejor resolvería algoritmos que con la estructura actual seria imposible codificarlos

    Gracias.

    ResponderEliminar
  2. Acá el desafío resuelto:
    La función "evaluar(expresion)": dada una cadena evalúa el resultado (sin precedencia de operadores)

    SubProceso retorno <- calcular (operador, a, b)
    Si operador = '+' entonces
    retorno <- a + b
    FinSi
    Si operador = '-' entonces
    retorno <- a - b
    FinSi
    Si operador = '*' entonces
    retorno <- a * b
    FinSi
    Si operador = '/' entonces
    retorno <- a / b
    FinSi
    Fin SubProceso

    SubProceso retorno <- evaluar(expresion)
    Definir num1, num2 Como Real
    Definir letra, operar, numstr Como Caracter
    operar <- ''
    Para i <- 0 Hasta Longitud(expresion) - 1 Hacer
    letra = SubCadena(expresion,i,i)
    si letra = '+' o letra='-' o letra='*' o letra='/' Entonces
    si operar = '' Entonces
    num1 = ConvertirANumero(numstr)
    Sino
    num2 = ConvertirANumero(numstr)
    num1 = calcular(operar, num1, num2)
    FinSi
    operar <- letra
    numstr <- ''
    Sino
    numstr <- numstr + letra
    Fin Si
    FinPara
    num2 = ConvertirANumero(numstr)
    num1 = calcular(operar, num1, num2)
    retorno <- num1
    Fin SubProceso

    Proceso main
    Escribir evaluar("3+4")
    FinProceso

    ResponderEliminar
  3. Gracias por iniciar el interprete de expresiones algebraicas, pero este es solo un paso por ejemplo falta que analice funciones aritméticas de PSEINT, paréntesis, etc

    ResponderEliminar
  4. Agregados los paréntesis y los operadores ^ y mod, además soporta espacios en blanco:

    SubProceso retorno <- calcular (operador, a, b)
    Si operador = '+' entonces
    retorno <- a + b
    FinSi
    Si operador = '-' entonces
    retorno <- a - b
    FinSi
    Si operador = '*' entonces
    retorno <- a * b
    FinSi
    Si operador = '/' entonces
    retorno <- a / b
    FinSi
    Si operador = '^' entonces
    retorno <- a ^ b
    FinSi
    Si operador = 'm' entonces
    retorno <- a mod b
    FinSi
    Fin SubProceso

    SubProceso retorno <- evaluar(expresion)
    Definir num1, num2 Como Real
    Definir letra, operar, numstr, subexpresion Como Caracter
    Definir inicioSubExpresion Como Logico
    operar <- ''
    inicioSubExpresion <- Falso
    subexpresion <- ''
    Para i <- 0 Hasta Longitud(expresion) - 1 Hacer
    letra = SubCadena(expresion,i,i)
    si letra <> ' ' entonces
    si letra = 'm' entonces
    si SubCadena(expresion,i,i+2) = 'mod' entonces
    i <- i + 2
    FinSi
    FinSi
    Si letra = '(' Entonces
    inicioSubExpresion <- Verdadero
    subexpresion <- ''
    SiNo
    si inicioSubExpresion Entonces
    Si letra = ')' Entonces
    inicioSubExpresion = Falso
    numstr <- ConvertirATexto(evaluar(subexpresion))
    Sino
    subexpresion <- subexpresion + letra
    FinSi
    Sino
    Si letra = '+' o letra='-' o letra='*' o letra='/' o letra='^' o letra='m' Entonces
    si operar = '' Entonces
    num1 <- ConvertirANumero(numstr)
    Sino
    num2 <- ConvertirANumero(numstr)
    num1 <- calcular(operar, num1, num2)
    FinSi
    operar <- letra
    numstr <- ''
    Sino
    numstr <- numstr + letra
    Fin Si
    FinSi
    FinSi
    FinSi
    FinPara
    num2 <- ConvertirANumero(numstr)
    num1 <- calcular(operar, num1, num2)
    retorno <- num1
    Fin SubProceso

    Proceso main
    Definir expresion Como Caracter
    Definir resultado como Real
    expresion <- "3^2 * (4 + 5) mod 8"
    Escribir 'Evaluando la expresión ', expresion
    resultado <- evaluar(expresion)
    Escribir 'Resultado = ', resultado
    FinProceso

    Era cuestión de razonarlo un poquito, jeje.
    SUERTE!!!

    ResponderEliminar
  5. Hola,

    He intentado compilar PSeInt desde las fuentes 20150505, pero me generó muchos errores (No compiló), seguí exactamente los mismos pasos que aparecen aquí http://cucarachasracing.blogspot.com/2012/11/compilar-la-version-del-repositorio-en.html, estoy utilizando debian jessie. Siguiendo la misma guía, en debian wheezy compiló y funcionó bien la versión 20140215 (A excepción del editor de diagramas).

    Es de anotar que con debian jessie he podido compilar otros paquetes sin ningún problema. De antemano agradezco su colaboración.

    ---Publicado en el foro "Reporte de errores" el 17-06-2015, sin ninguna respuesta.---


    ResponderEliminar