jueves, 1 de junio de 2023

¿Y ahora qué sigue?

Finalmente pude publicar una actualización de PSeInt después de tanto tiempo. Repasemos en qué situación quedó este proyecto y cuáles serían mis próximos pasos, tanto para PSeInt como para ZinjaI.

 

Primeros pasos en ZinjaI

Habiendo trabajado tanto en PSeInt últimamente, lo lógico sería que ahora me concentré por un tiempo en ZinjaI. Lleva mucho más tiempo desactualizado que PSeInt. Todavía ni publiqué una versión que use wx3 y strings unicode (aunque esto ya "compila" desde hace un par de años). A la par de publicar estos cambios (hay pequeños detalles que pulir antes de dar por finalizada la transición), tengo que actualizar el toolchain para Windows (que es el que más usan los alumnos y está muy desactualizado). El problema de cambiar el toolchain (en este caso será mingw32 por mingw-w64), es que hay que actualizar también todos los complementos, y registrar todo esto en la documentación (ya que es software de terceros, hay que tener cuidado con las licencias por ej).

De la mano de esto vendrá además, como pasó con PSeInt, una nueva versión nativa de 64bits para Windows (esto no debería requerir mucho trabajo), y versiones actualizadas para macOS (esto sí probablemente requiera mucho trabajo), ya que la versión actual ya no funciona en este sistema.

 

Nuevas funcionalidades en ZinjaI

Una vez finalizados los cambios que mencioné antes, podré entonces aprovechar la nueva base y empezar a agregar funcionalidad. Por ej: que los fuentes puedan tener cualquier codificación (poder usar por ej UTF8, que se ha vuelto más común, en  lugar de ISO8859 como ahora);  tratar de poner (un poquito) al día el mecanismo autocompletado; agregar facilidades para cosas útiles como usar los múltiples sanitizers disponibles en los compiladores modernos; mejorar el mecanismo de complementos; explorar las nuevas funcionalidades de scintilla y ver qué se puede hacer/simplificar con eso (por ej, ahora permite editar en múltiples lugares en simultáneo, cosa que antes debía "simular" zinjai; o utilizar las anotaciones para mensajes de error o resultados de herramientas como cppcheck); etc.



El interior de PSeInt


Respecto a PSeInt, el gran refactory que quería lograr para tener un diseño mucho mejor y más flexible todavía está por la mitad. El trabajo de cada módulo todavía no es reutilizable como biblioteca, pero el principal (pseint) está un poco más cerca (digamos que ya hice el 50% de ese camino), y como efecto colateral otras partes del código se fueron simplificando también (como psexport). Una vez que tenga esa flexibilidad en el núcleo de PSeInt, tendré que hacer lo propio en la GUI. Todavía hay mucho trabajo en wxPSeInt para poder aprovechar toda la flexibilidad que va a dar el nuevo pseint (por ejemplo, poder variar las palabras reservadas arbitrariamente).

Una vez que cada módulo individualmente esté suficientemente "bonito", probablemente intente jubilar el mecanismo de módulos y pasar a integrar las partes como verdaderas bibliotecas en un solo gran ejecutable, para simplificar y optimizar muchísimo la comunicación entre ellas. Con esto el ida y vuelta entre partes será mucho más fluido y seguramente se notará en los detalles.



El exterior de PSeInt

De la mano de los nuevos cambios y la futura flexibilidad, vendrá por ejemplo un mayor poder de personalización de los perfiles. Esto me obligará a rediseñar el cuadro de selección y configuración (al de selección ya tuve que reimplementarlo en la última actualización porque con tantos perfiles ya se volvía muy lento para cargar). Por otro lado, si el lenguaje puede cambiar tanto, la ayuda como está ahora (texto fijo) dejará de tener sentido. Me gustaría que la ayuda se adaptara al perfil, y para eso tengo que poder escribir texto de ayuda condicional y plantillas donde el sistema reemplace las palabras claves (planeo definir un formato simple basado en markdown + un pequeño preprocesador). Y así, muchas cosas de las que sí ve el usuario irán cambiando/mejorando. Hasta podría integrar un mecanismo de traducción de la GUI similar al de ZinjaI para poder traducir PSeInt completo a otros idiomas. Pero para todo esto, todavía falta terminar de ajustar el interior.



En resumen, hay mucho por hacer en estos dos proyectos. En el corto plazo, supongo que intentaré completar una actualización de ZinjaI que use la última versión de wxWidgets y ofrezca un compilador y complementos actualizados para Windows. Esa sería la primera prioridad, y de hecho necesitaría tener lo de los complementos listo para el segundo cuatrimestre, ya que en el cursado de Computación Gráfica utilizo complementos nuevos, y me vendrían muy bien algunas funcionalidades recientes de C++ en los códigos de los TPs. Una vez resuelto eso, no se cual de los otros tres grandes grupos de cambios atacaré primero. Probablemente marchen muy de a poco y en paralelo los tres, según ganas, tiempo, estado de ánimo, etc. El tiempo dirá, pero lo importante será no quedarse quieto.

17 comentarios:

  1. Hay bastante trabajo para entretenerse en este cuasi nuevo semestre. Excelente que retomes ZinjaI, pero antes hay que corregir esos detalles pequeños que hacen que la ultima versión de PseInt, no este trabajando a full, como por ejemplo si ejecutas en modo paso a paso, la consola no opera, al iniciar el panel grafico y regresar al modo código fuente, los comentarios se desfasan 2 líneas abajo, la instrucción Sin Saltar se une a la instrucción a anterior, así otros problemas que están reportados en el foro.
    Jaime

    ResponderEliminar
  2. Encuesta
    ¿Quién tiene problemas en la ultima versión de PseInt de mayo 2023? o ¿siguen usando la versión anterior?

    ResponderEliminar
  3. Hola, en la universidad que trabajo, la facultad de ingeniería a decidido que los cursos de fundamentación de lógica algorítmica y programación, se dicten en un lenguaje profesional como c++, python o pseudocódigo pero en ingles smallbasic, raptor etc., pues su argumento es que causan 'traumatismos' al codificar en nuestro idioma el castellano aka español, ellos quieren que los estudiantes codifiquen directamente en ingles. traté de converserlos de las bondades de usar pseint, como el diagrama de flujo, correr paso a paso entre otras, pero no lo avalaron. Pienso que es hora de dar el siguiente paso y dar soporte a codificación en ingles. Creo que Pablo ya esta dando los primeros pasos en soporte multilenguaje, hay que lanzar una versión próxima de pseInt donde se pueda codificar con el lenguaje universal técnico mundial, el eng =)

    ResponderEliminar
  4. Pseint es un cancer para la comunidad hispana de estudiantes de programacion. Que software tan terrible! Es màs facil e intuitivo programar en Python. Los gringos deben reirse de nosotros por un software tan mal hecho. Hace programar mas dificil.

    ResponderEliminar
    Respuestas
    1. No estoy de acuerdo para nada en lo que decís Adrián, PSeInt es un éxito muy grande como herramienta educativa, muy especialmente en la formación secundaria (bachillerato) e inicios de la terciaria (universidad). Lo que si debe es actualizarse, en ciertas características para dar soporte a un contenido más amplio de lógica algorítmica 1(lógica + GUI por manejo de pixeles coordenados) y logica2 (POO).
      Soy ingeniero en electrónica, docente de lógica algo1 y2, ojalá fuera ingeniero de aplicaciones, ya hubiera colaborado con el desarrollo, me extraña que hay una inmensa cantidad de docentes hispanoamericanos que desarrollan de software para PC y no estén aportando.
      Los invito a unirse al proyecto, por mi parte reporto errores, propongo ideas y mejoras.

      Eliminar
    2. Programalo vos entonces, master...

      Eliminar
  5. Hola. Idea para mejorar Zinjai y PSeint.
    Estamos en épocas que mostrar I/O en Consola solo en formato de texto lineal consecutivo, ya esta pasado de moda, y pienso que PseInt puede dar un paso a otra dimensión incorporando simples funciones para crear TUI (TEXT USER INTERFACE) con el fin de simular una simple GUI, para lo cual se necesita funciones básicas de C#.
    El sucesor de C++ es (C++)++ símbolo agrupado como C#, este tiene funciones preincluidas (built-in) que permiten al estudiante crear sus primeros algoritmos de forma mas creativa, porque incorpora funciones por ejemplo de posicionamiento de texto en (Cols, Filas) y otras que se mencionan mas abajo.
    Los nombres siguientes serian adaptados dentro de Zinaji como una biblioteca para que los estudiantes la usen, (platilla TUI por ej.) Convert_ToString(), Thread_Sleep() Console_BackgroundColor(), Console_ForegroundColor(), Console_SetCursorPosition(), Cursor_Hide(); Cursor_Show(); Todos nombres adaptados de C# para que la transición sea consecutiva de c++ a c#
    Las anteriores funciones sirven por ejemplo para crear TUI simples que motivan al estudiante a mostrar sus soluciones en cajas de diálogos con símbolos ASCII

    ╔════════════════════════╗
    ║ Ingrese valor de la altura : | ║
    ╚════════════════════════╝

    ResponderEliminar
  6. Ejemplo con el uso de las funciones anteriores, parte #1
    #include
    using namespace std;

    // Función que convierte un numero en cadena (string)
    #include
    string Convert_ToString(float numero)
    {
    stringstream cadena_char; // variable que almacena un flujo de caracteres
    cadena_char << numero;
    return cadena_char.str();
    }

    // Función que espera un determinado tiempo en milisegundos
    #include
    void Thread_Sleep(double tiempo)
    {
    clock_t tiempo_inicial = clock();
    double e = 0;
    do
    {
    e = 1000 * double(clock() - tiempo_inicial) / CLOCKS_PER_SEC;
    } while (e < tiempo);
    }

    // DEFINICIÓN o ETIQUETAS DE COLORES
    #include
    #define Negro 0
    #define Azul 1
    #define Verde 2
    #define Aguamarina 3
    #define Rojo 4
    #define Purpura 5
    #define Amarillo 6
    #define Blanco 7
    #define Gris 8

    #define Azul_claro 9
    #define Verde_claro 10 // A
    #define Aguamarina_claro 11 // B
    #define Rojo_claro 12 // C
    #define Purpura_claro 13 // D
    #define Amarillo_claro 14 // E
    #define Blanco_brillante 15 // F
    #define color_x1 16
    #define color_x2 17
    // #define ...

    // Función que cambia el color del fondo y texto
    void Console_BackForeGroundColor(int BackGround_color, int ForeGround_color)
    {
    int colorBF_int = BackGround_color * 16 + ForeGround_color;
    //int colorBF_int = BackGround_color | ForeGround_color;
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colorBF_int);
    }

    void Console_BackgroundColor(int c)
    { // NOP
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO csbi;

    GetConsoleScreenBufferInfo(hConsole, &csbi);

    SetConsoleTextAttribute(hConsole, (csbi.wAttributes & 0xFF0F) | (((WORD)c) << 4)); // Background colors take up the second-least significant byte
    }

    // Función que posiciona un texto en una determinada columna y fila
    void Console_SetCursorPosition(int columna, int fila)
    {
    HANDLE hcon;
    hcon = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD dwPos;
    dwPos.X = columna;
    dwPos.Y = fila;
    SetConsoleCursorPosition(hcon, dwPos);
    }

    void Console_Pause(int tipo_pausa)
    {
    switch (tipo_pausa)
    {
    case 1:
    system("pause");
    break; // espera una Tecla, y coloca un mensaje de
    case 2:
    cin.get();
    break; // espera un Enter, no cualquier tecla
    default:
    system("pause");
    break;
    }
    }

    // Función que oculta o muestra el cursor
    void Set_Cursor(int value)
    {
    CONSOLE_CURSOR_INFO cci;
    GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
    cci.bVisible = value;
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);
    }

    // Función que muestra el cursor
    void Cursor_Hide()
    {
    Set_Cursor(0);
    }

    // Función que muestra el cursor
    void Cursor_Show()
    {
    Set_Cursor(1);
    }

    void Console_Clear()
    {
    system("cls");
    }

    void Console_Write_ASCII(int number)
    {
    printf("%c", number);
    }

    void fadeMaxButton(){
    HWND consoleWindow;
    consoleWindow = GetConsoleWindow();
    SetWindowLong(consoleWindow, GWL_STYLE,GetWindowLong(consoleWindow, GWL_STYLE) & ~WS_MAXIMIZEBOX & ~WS_SIZEBOX);
    }

    void alert_campana(){
    cout<< "\a";
    }

    ResponderEliminar
  7. // parte #2

    int main()
    {

    int ancho = 110, alto = 30;
    Cursor_Hide();
    system("mode con: cols=110 lines=30");
    fadeMaxButton();
    SetConsoleTitle("App bases de datos de la universidad");
    Console_BackForeGroundColor(Aguamarina_claro, Azul);
    Console_Clear();
    Thread_Sleep(100);

    int columna, fila;
    columna = 0; fila = 0;
    for (columna = 1; columna <= ancho - 2; columna = columna + 1)
    {
    Console_SetCursorPosition(columna, fila);
    Console_Write_ASCII(205);
    Thread_Sleep(10);
    }
    columna = 0;
    for (fila = 1; fila <= alto - 4; fila = fila + 1)
    {
    Console_SetCursorPosition(columna, fila);

    Console_Write_ASCII(186);
    Thread_Sleep(10);
    }
    columna = ancho-1;
    for (fila = 1; fila <= alto - 4; fila = fila + 1)
    {
    Console_SetCursorPosition(columna, fila);

    Console_Write_ASCII(186);
    Thread_Sleep(10);
    }
    fila = alto-3;
    for (columna = 1; columna <= ancho - 2; columna = columna + 1)
    {
    Console_SetCursorPosition(columna, fila);
    cout << "-";

    Thread_Sleep(10);
    }
    Console_SetCursorPosition(0, 0);
    Console_Write_ASCII(201);
    Thread_Sleep(200);

    Console_SetCursorPosition(0, alto-3);
    Console_Write_ASCII(200);
    Thread_Sleep(200);

    Console_SetCursorPosition(ancho-1, 0);
    Console_Write_ASCII(187);
    Thread_Sleep(200);

    Console_SetCursorPosition(ancho-1, alto-3);
    Console_Write_ASCII(188);
    Thread_Sleep(200);
    fila = 4;
    for (columna = 1; columna <= ancho - 2; columna = columna + 1)
    {
    Console_SetCursorPosition(columna, fila);
    cout << "-";

    Thread_Sleep(10);
    }
    fila = alto-5;
    for (columna = 1; columna <= ancho - 2; columna = columna + 1)
    {
    Console_SetCursorPosition(columna, fila);
    cout << "-";

    Thread_Sleep(10);
    }
    fila = 2;
    columna = 3;
    Console_SetCursorPosition(columna, fila);
    Console_BackForeGroundColor(Aguamarina_claro, Rojo);
    string titulo_app = "Base de datos Universidad Del Sur";
    cout << titulo_app;
    string caracter_j;
    int tamanio_texto = string(titulo_app).size();
    for (int j = 0; j < tamanio_texto; j++)
    {
    caracter_j = titulo_app.substr(j, 1);
    Console_SetCursorPosition(j + 3, fila + 1);
    cout << caracter_j;
    Thread_Sleep(70);
    }
    Console_BackForeGroundColor(Aguamarina_claro, Negro);
    fila = alto-4;
    Console_SetCursorPosition(5, fila);
    cout << "Cargando...";
    fila = alto-4;
    for (columna = 20; columna <= ancho - 5; columna = columna + 1)
    {
    Console_SetCursorPosition(columna, fila);

    Console_Write_ASCII(176);
    Thread_Sleep(0);
    }
    fila = alto-4;
    for (columna = 20; columna <= ancho - 5; columna = columna + 1)
    {
    Console_SetCursorPosition(columna, fila);

    Console_Write_ASCII(219);
    Thread_Sleep(30);
    }
    Thread_Sleep(100);
    fila = alto-4;
    Console_SetCursorPosition(5, fila);
    cout << " ";
    fila = alto-4;
    for (columna = 3; columna <= ancho - 5; columna = columna + 1)
    {
    Console_SetCursorPosition(columna, fila);
    cout << " ";
    Thread_Sleep(0);
    }

    ResponderEliminar
  8. // parte #3
    Console_BackForeGroundColor(Aguamarina_claro, Negro);
    fila = 5;
    columna = 1;
    Console_SetCursorPosition(columna, fila);
    string mensaje00 = "Ingrese nombre y apellido del cliente:";
    int longitud_cadena = string(mensaje00).size();
    cout << mensaje00;
    Cursor_Show();
    Console_SetCursorPosition(columna+longitud_cadena, fila);
    cout << "_______________";
    Console_SetCursorPosition(columna+longitud_cadena, fila);
    string nombre;
    getline(cin, nombre);
    fila = 5 + 1;
    columna = 1;
    Console_BackForeGroundColor(Aguamarina_claro, Gris);
    Console_SetCursorPosition(columna, fila);
    string mensaje00a = "Su nombre es ";
    cout << mensaje00a + nombre << endl;
    fila = 5;
    columna = 55;
    Console_SetCursorPosition(columna, fila);
    Console_BackForeGroundColor(Aguamarina_claro, Negro);
    string mensaje01 = "Ingrese edad del cliente entre [0,120): ";
    longitud_cadena = string(mensaje01).size();
    cout << mensaje01;
    Console_SetCursorPosition(columna+longitud_cadena, fila);
    cout << "___";
    Console_SetCursorPosition(columna+longitud_cadena, fila);
    int edad;
    cin >> edad;
    bool dominio_valido;
    dominio_valido = ((edad>=0) && (edad<120));
    while (dominio_valido == false ){
    Cursor_Hide();
    fila = 5;
    columna = 55;
    Console_SetCursorPosition(columna, fila);
    cout << "Ingrese edad del cliente entre [0,120): ";
    Console_SetCursorPosition(3, alto-4);
    cout << "Dato invalido";
    Thread_Sleep( 1000 );
    Console_SetCursorPosition(columna+longitud_cadena, fila);
    cout << "___"; // Limpia el campo de entrada

    Console_SetCursorPosition(columna+longitud_cadena, fila);
    Cursor_Show();
    cin >> edad;
    Cursor_Hide();
    dominio_valido = ((edad>=0) && (edad<120));
    Console_SetCursorPosition(3, alto-4);
    cout << " "; // limpia el mensaje
    }

    fila = 5 + 1;
    columna = 55;
    Console_SetCursorPosition(columna, fila);
    Console_BackForeGroundColor(Aguamarina_claro, Gris);
    cout << "Su edad es " + Convert_ToString(edad) + " años" << endl;


    Console_BackForeGroundColor(Aguamarina_claro, Amarillo_claro);
    Console_SetCursorPosition(3, alto-4); cout << "";
    return 0;
    }

    ResponderEliminar
    Respuestas
    1. Aunque la idea me parece excelente ya puede hacer lo de los colores en la terminal con un simple printf y secuencias de escape ANSI, ya que windows a partir de su soporte de WSL incluyó estos en su sistema operativo desde la version 10, si buscas algo más sofisticado puedes usar ncurses que es una librería (archivo de cabecera para los especialitos xd) que sirve para crear interfaces muy bien pulidas dentro de consola, esta "librería" la conozco por Linux aunque también tiene su versión de windows en el proyecto msys2, sería una muy buena opción implementarla dentro de lo que sería la carpeta include de los archivos de zinjai

      Eliminar
  9. Hola muy buenas, no sé si esta información te sirva, tal vez ya la conozcas pero bueno, existe el proyecto msys2 que es una recopilación de herramientas de unix y compiladores, personalmente dejé de utilizar zinjai hace mucho tiempo debido a la falta de soporte para UTF8, pero si vas a retomar el proyecto podrías echarle un vistazo al proyecto que te comento, yo utilizo el compilador gcc que viene en el msys2 y es la ultima versión, los paquetes se actualizan con un gestor de paquetes llamado pacman, basicmente como si se tratase de ArchLinux

    ResponderEliminar
  10. Consulta no se si responderán, pero si quiero agregar nuevos comandos como un struct dentro de pseint Existe documentación? para poder realizarlo? o poder agregara idiomas por mi cuenta?

    ResponderEliminar
  11. Ojalá puedas continuar con el desarrollo de Zinjai y puedas agregarle muchas funciones, es el IDE de C++ que más me gusta, su diseño y facilidad hace que no sea tan frio o aburrido como otros, y lo uso desde que entré a la universidad :D

    ResponderEliminar
  12. Hola, No puedo utilizar Pseint en celulares o tablets con Android 13, hay alguna solución para utilizarlo en versiones anteriores?

    ResponderEliminar
  13. No queremos que muera el foro

    ResponderEliminar
  14. Sería lindo tener una compilación de PSeInt en WebAssembly para probar en el navegador sin tener que instalarlo.

    ResponderEliminar