Poniendo calificaciones con Emacs

Daniel Molina published on
5 min, 1000 words

A estas alturas a nadie le extrañará que soy un gran fan de Emacs.

Cada vez lo uso más para corregir a los alumnos. Tiene grandes ventajas:

En presentaciones (como esta mañana) me resulta muy cómodo tener la pantalla compartida en un buffer el pdf (que puedo abrir incluso aunque me lo mandasen en zip) y en otro el fichero con los comentarios.

Pero lo más interesante son las calificaciones, gracias a dos grandes descubrimientos recientes:

Explico un poco cómo corrijo.

Comentarios para cada estudiante

Tengo un apartado en el que pongo comentarios por cada estudiante.

* Comentarios

** Estudiante1

- Ej1: ...
- Ej2: ...
...

** Estudiante2

- Ej1: ...
- Ej2: ...

Usando este formato me resulta muy cómodo de mover. Además, la parte Ej1, ... lo guardo como plantilla y lo copio para cada estudiante.

Pero lo más interesante son las tablas, suelo corregir ponderando cada prueba en función de su puntuación, y me viene muy bien.

Puntuando a los alumnos

Creo una fila por cada estudiante, y una columna por prueba, marcando cada casilla con un valor entre 0 y 1. 0 indica totalmente mal,0.5 sería que le doy la mitad de la puntuación de la prueba correspondiente, y 1 toda la puntuación.

Por ejemplo, supongamos tres pruebas en el que la media final sería que el primero vale 3 puntos, el siguiente 4 y el tercero otros 3 puntos, creo la tabla de la siguiente forma:

#+name: grupoE
| Nombre     | Apellidos |  3 |    4 |  3 | Total |
|            |           | P1 |   P2 | P3 |       |
|------------+-----------+----+------+----+-------|
| Apellidos1 | Nombre1   |  1 |  0.5 |  0 |   5.0 |
| Apellidos2 | Nombre2   |  0 | 0.75 |  1 |   6.0 |
| Apellidos3 | Nombre3   |  0 |    0 |  1 |   3.0 |
|            
#+TBLFM: $6=vsum((@1$3..@1$5)*($3..$5));%.1f

La primera fila almacena la puntuación de cada punto, de forma que la puntuación final se puede actualizar de forma automática al cambiar tanto la ponderación como la calificación de estudiantes (Con C-c C-c).

En https://orgmode.org/worg/org-tutorials/org-spreadsheet-lisp-formulas.html hay una buena introducción del uso de fórmulas, que un día complementaré 😊.

Las tablas pueden también ordenarse, basta con ponerse en la columna a ordenar (como apellidos), y org-table-sort-lines para ordenar (, t s en spacemacs). Hay dos enfoques muy útiles:

  • Ordenar alfabéticamente, como ponerse en la columna Apellidos y tras org-table-sort-lines seleccionar la a para ordenar alfabéticamente.

  • Ordenar por puntuación, ponerse en la columna Total, y tras org-table-sort-lines seleccionar la n para ordenar por puntuación.

Tablas resumen

Una utilidad muy cómoda es el paquete orgtbl-aggregate que permite hacer tablas resúmenes de forma muy cómoda.

Por ejemplo, si quisiésemos una tabla adicional solo con la final:

#+name: final
#+BEGIN: aggregate :table "grupoE" :cols "Nombre Apellidos Total;'Calificación';%1f"
#+END:

Como se ve, se menciona una tabla externa a través de su nombre (en #+name: ...) y listar las columnas que nos interesan.

Y al pulsar C-c C-c en el begin, se completa automáticamente:

#+BEGIN: aggregate :table "grupoE" :cols "Nombre Apellidos Total;'Calificación';%1f"
| Nombre     | Apellidos | Calificación |
|------------+-----------+--------------|
| Apellidos1 | Nombre1   |          5.0 |
| Apellidos2 | Nombre2   |          6.0 |
| Apellidos3 | Nombre3   |          3.0 |
#+END:

Como se puede ver también se puede renombrar los atributos como se muestra en el ejemplo usando el ; y las cursivas.

Al cambiar la tabla anterior, se puede ejecutar C-c C-c y se actualiza automáticamente.

Filtrando

También se puede seleccionar. Por ejemplo, si queremos mostrar sólo los aprobados podemos limitar la búsqueda usando :cond. En este caso es necesario un poco de emacs lisp, pero limitar la puntuación es sencillo (sólo hay que acordarse de que hay que convertir la cadena en número para comparar).

#+name: aprobados
#+BEGIN: aggregate :table "grupoE" :cond(>= (string-to-number Total) 5.0):cols "Nombre Apellidos Total;'Calificación';%1f"
#+END:

Al pulsar C-c C-c se completa automáticamente únicamente con los aprobados.

#+name: aprobados
#+BEGIN: aggregate :table "grupoE" :cond(>= (string-to-number Total) 5.0):cols "Nombre Apellidos Total;'Calificación';%1f"
| Nombre     | Apellidos | Calificación |
|------------+-----------+--------------|
| Apellidos1 | Nombre1   |          5.0 |
| Apellidos2 | Nombre2   |          6.0 |
#+END:

Ordenando tablas resumen

Se puede ordenar directamente las tablas resumen usando ^a para alfabético, o ^n para ordenar numéricamente (y ^A y ^N para ordenarlo en forma descendente).

#+BEGIN: aggregate :table "grupoE" :cols "Nombre Apellidos Total;^N;'Calificación';%1f"
#+END:

Que al pulsar C-c C-c automáticamente completa de forma aleatoria:

#+BEGIN: aggregate :table "grupoE" :cols "Nombre Apellidos Total;^N;'Calificación';%1f"
| Nombre     | Apellidos | Calificación |
|------------+-----------+--------------|
| Apellidos2 | Nombre2   |          6.0 |
| Apellidos1 | Nombre1   |          5.0 |
| Apellidos3 | Nombre3   |          3.0 |
#+END:

Completando información

Vamos a completar la tabla original con el número de estudiantes evaluados (números de filas), y la media de las calificaciones:

  • Vamos a añadir el número de evaluaciones:

#+TBLFM: @>$2=vlen(@I..@II)

Esta línea añadiría en la última fila (@>) y segunda columna ($2) el número de elementos. Para no contar los apellidos, se puede sumar sólo las regiones separadas entre dos líneas verticales (entre @I y @II).

  • Hacer el promedio:

Es muy fácil hacer una fila promedio usando vmean:

#+TBLFM: @>$6=vmean(@I$6..@II$6)

Combinándolo todo:

| Nombre     | Apellidos |  3 |    4 |  3 | Total |
|            |           | P1 |   P2 | P3 |       |
|------------+-----------+----+------+----+-------|
| Apellidos1 | Nombre1   |  1 |  0.5 |  0 |   5.0 |
| Apellidos2 | Nombre2   |  0 | 0.75 |  1 |   6.0 |
| Apellidos3 | Nombre3   |  0 |    0 |  1 |   3.0 |
|------------+-----------+----+------+----+-------|
| Total      | 3         |    |      |    |  4.67 |
#+TBLFM: $6=vsum((@1$3..@1$5)*($3..$5));%.1f::@>$2=vlen(@I..@II)::@>$6=vmean(@I$6..@II$6);%.2f

Calculando datos

En las tablas resumen se pueden añadir fórmulas, y se aplican automáticamente.

Voy a hacer una tabla que indica los aprobados, los suspensos y el ratio de aprobados:

#+begin: aggregate :table "aprobados" :cols "count();'Aprobados' count();'Suspensos';%.0f count();'Ratio'"
| Aprobados | Suspensos | Ratio |
|-----------+-----------+-------|
|         2 |         1 |  66.7 |
#+TBLFM: $2=remote(grupoE,@>$2)-$1::$3=$1/($1+$2)%; %.1f
#+end:

Remote permite acceder a una columna de otra tabla, en este caso lo usamos para acceder al total de filas. El % permite mostrar el porcentaje, si no estuviese habría que multiplicar por 100. El %.1f indica que se desea un decimal.

Espero que estos consejos os hayan dado ideas de cómo usar Emacs y org-table para hacer cosas chulas.