Avances varios

Hace días que no escribo… en este tiempo, me he dedicado a muy variados asuntos. He estado creando una plantilla para la documentación según la normativa del PFC, he juntado, maquetado y revisado toda la documentación que había creado hasta el momento. Además, me he personalizado el paquete fncychap, que es un paquete de LaTeX para modificar el formato de los capítulos.

En cuanto a el framework que comenté en el anterior post, me he leído los capítulos básicos del libro de Django, estuve diseñando el aspecto de la aplicación y modificando el aspecto del render de las preguntas de HTML. El complemento para Iceweasel está muy curioso para el diseño web.

De todos modos, enseguida dejé aparcado el tema de Django, y volví a la aplicación de escritorio. He modificado la capa de persistencia, y he realizado los cambios necesarios en la capa de dominio, para que el Agente siempre devuelva objetos de la capa de dominio. De este modo se consiguen varios objetivos, pero hay que destacar que este es el modo para facilitar el uso de Slice e ICE. La aplicación todavía no la he modificado para que sea distribuida, espero hacerlo en breve. Sí he realizado el fichero slice, digamos que es un lenguaje que sirve para establecer un contrato entre las distintos lados(peers) de la aplicación. En este caso, un lado siempre hará de servidor y otro siempre de cliente. El lado del servidor se basará en el Agente y la base de datos. También he actualizado los diagramas de clases.

Los otros avances se han centrado en mejorar la interfaz a la hora de crear exámenes, así como en los render, a parte del comentado en HTML anteriormente, también se ha mejorado el render de LaTeX. Se ha añadido la lógica de negocio necesaria para trabajar con exámenes, así como las tablas en la base de datos, en la línea de la especificación IMS QTI v2.1. También, se crea el fichero xml de acuerdo a ésta especificación.

Las nuevas ideas que se están implementado ahora son ideas referentes a que una pregunta que ha sido utilizada en un examen, no puede ser editada, ya que si se edita una pregunta y se quiere ver el examen o datos almacenados relacionados a esa pregunta, se contemplarían datos falseados. Por lo tanto, hay que poner una barrera para no poder editar las preguntas utilizadas. Con objeto de no tener que crear de nuevo la pregunta con la modificación que se pretendía realizar, se trabaja en el clonado de una pregunta. Es decir, poder disponer de una pregunta igual(el mismo contenido) pero no la misma(no es el mismo archivo xml ni la misma instancia en la base de datos), de este modo, se puede editar la pregunta clonada para realizar las modificaciones que se deseen, utilizarla en futuros exámenes sin tener que crearla desde cero.

Framework elegido

De entre todos los frameworks, realicé una última criba por lenguaje. Sí, quizás hubiese sido magnífico hacerla desde el principio, pero hasta que no he visto un poquito más en profundidad no me he dado cuenta. Los de Java, ofrecen muchos efectos visuales casi todos basados en tecnología AJAX, pero lo necesario es buscar un framework que ofrezca mecanismos de seguridad, de desarrollo fácil y rápido, sesiones, etc. Por la parte de PHP, está muy de moda y eso, pero no lo he visto muy elegante, sobre todo, a la forma de trabajar con los datos. Por último Ruby o Python, me he quedado con Python porque conozco el lenguaje y me va a ser más sencillo programar en Python, aunque lo poco que he visto de Ruby está bastante bien.

Entre TurboGears y Django, la verdad es que son bastante parecidos, los dos se basan en CherryPy, otro framework de Python. Me he decantado finalmente por Django por dos motivos:

  • La facilidad de crear interfaces de administración.
  • La información de errores en el desarrollo. Si en Django intentas acceder a una URL no conocida, aparece una página de error muy bien formateada con las urls existentes, las variables de contexto y mucha más información.

He leído el tutorial, bastante largo, pero las cosas van quedando claras, menos las vistas generales, creo que por meterlas en el ejemplo y no hacer el tutorial más largo no quedan del todo ilustradas. Han sacado un libro y además, se está trabajando en la traducción al español del mismo.

Repaso de Frameworks

Hace tiempo ya hablé algo sobre los frameworks, han pasado unos meses y ahora que es el momento de utilizar alguno, creo que estaría bien, rehacer esa tabla con los frameworks más actualizados.

Table 1:
Frameworks ordenados por lenguaje
Lenguaje Framework
Java Apache Cocoon · Apache Struts · Google Web Toolkit · Grails · JBoss Seam · OpenLaszlo · Spring Framework · Stripes · Wicket framework · ZK Framework
PHP CakePHP · CodeIgniter · Horde · KohanaPHP ·  PRADO · Zend Framework
Python Django · TurboGears
Ruby Ruby on Rails

Cambios en el editor y en los enunciados

Para facilitar un poco más la creación del editor, que realmente se ha vuelto más costoso de lo previsto y del objetivo de este proyecto, se ha asociado al editor con tipos de contenido. Esto es, asociar la clase editor con una clase content, que tendrá como hijos los distintos contenidos que se puedan meter a la hora de crear una pregunta. Éstos serán:

  • Texto.
  • Tablas.
  • Imágenes.
  • Fórmulas.

Cada vez que se cree contenido aparecera un diálogo para introducir información sobre esto y se irá añadiendo al editor como un elemento más de un HBox. Este cambio ha llevado también a redefinir la forma en la que se trabaja con enunciados, ahora el enunciado de una pregunta es una lista de contenidos, conllevando la realización diversos cambios en la capa de persistencia.

Cambios en los módulos

Hasta el momento, cada clase era un módulo, en Python esto significa, que tenía un fichero para cada clase. A causa también del Render y siguiendo el sentido común, los distintos tipos de clases, hijos de la clase Question, los he juntado con la clase Question, en un sólo módulo (fichero) formando el módulo Questions, por otro lado, he hecho lo propio con los subtipos de render para cada render, es decir, juntar en un fichero cada render (html, tex y gtk) con sus clases hijas (renders para cada tipo de pregunta).

De este modo, a parte de ser algo con mucho sentido, se evita la importación circular, o lo que es lo mismo que A importe a B y B importe a A. Esto ocurriría por las clases padres en estos casos actúan como fábricas, es decir construyen objetos de las clases hijos con los parámetros oportuno y se lo devuelven a aquellos que se lo piden.

Cambios en la capa de persistencia

Para hacer un poco más fácil y extensible la aplicación, y a raíz del desarrollo de los renders he creído oportuno modificar la forma de guardar y obtener los datos. Hasta el momento, la base de datos era muy sencilla, guardaba los datos mínimos de una pregunta, su nombre, su tipo, la ruta del fichero XML y poca información más. Esto obliga a que si quiero renderizar la pregunta, tenga que abrir el fichero XML parsearlo (estaba utilizando Amara hasta el momento) y esto es algo poco elegante y bastante lioso. Por lo tanto, la base de datos pasa a ser una correspondencia directa con la capa de dominio (algo así como seguir el patrón una clase una tabla) para así, obtener los datos directametne de la base datos y ahorrarnos el parseo del XML.

Sigo trabajando con SQLObject, cada día lo voy entendiendo mejor, ya permite herencia y además en la lista de correo son muy colaborativos 🙂

Aplicación del patrón Visitor

En este patrón participan un Visitor (nodo visitante) en el que normalmente se declaran de forma abstracta los métodos para visitar un elemento concreto en mi caso está clase será la clase Render. Después como hijos tenemos ConcreteVisitors (visitantes de distintos tipos) que implementan las operaciones declaradas en Visitor. En mi caso son DocHTMLRender, DocTeXRender y GTKRender. Estas clases tendrán además subclases para cada uno de los tipos de preguntas:

  • Preguntas a desarrollar.
  • Preguntas de elección múltiple con una o varias respuestas correctas.
  • Pregunta de entrada de texto.
  • Pregunta de elección en línea.

Otro participante es Element, que define una operación abstracta llamada Accept, en mi caso será la clase Question. Como hijos estarán los ConcreteElement, que implementan la operación Accept teniendo como argumento un visitor; serán los diferentes tipos de preguntas.

Por último, hay un ObjectStructure, que puede enumerar elementos concretos y facilita una interfaz de alto nivel que permite al visitante visitar sus elementos, en casos se puede tratar de un Composite. Este rol lo hará la clase Collection que serán listas de preguntas. De este modo, podremos previsualizar una o más preguntas.