Indice / Practicas / EJ-6.6
EJ-6.6 · De ancho a largo con melt
Una planilla de asistencia de 30 alumnos por 12 sesiones se
convierte en 360 filas. La conversión es una línea; lo que hay que decidir es qué
hacer con las cinco celdas que no dicen ni P ni A.
Qué hay que hacer
A partir de asistencia_sesiones.csv, producir
asistencia_larga.csv: una fila por celda, con el legajo,
el nombre, la sesión, el estado y una bandera que diga si ese estado es
reconocible.
ELI5Explicado facil
La grilla de asistencia pegada en la pared tiene un alumno por fila y una columna por clase. Es cómoda de mirar y pésima para contar.
Este ejercicio la pasa a un cuaderno donde cada renglón dice «tal alumno, tal clase, presente». Con 360 renglones en vez de una grilla, contar ausencias pasa a ser una sola línea - y de paso saltan a la vista las cinco anotaciones que nadie entiende.
Archivos
- Entrada ·
asistencia_sesiones.csv - Objetivo ·
asistencia_larga.csv - Herramienta ·
comparar.py
Las cinco celdas raras
Entre las 360 celdas hay una X, un PRESENTE escrito
completo, una p minúscula, un guion y una vacía. Ninguna se
corrige: se conservan tal cual, con valido = 0.
La p minúscula es la más tentadora: es obvio que quiso decir presente,
y normalizarla es una línea. Y este ejercicio no la normaliza a propósito.
Si el programa arregla lo obvio en silencio, el informe dice que las 360 celdas están
bien y nadie se entera de que alguien está cargando datos de cualquier forma.
Marcar es distinto de corregir: deja el problema visible y la decisión en manos de quien corresponde.
Cómo saber si te salió
python comparar.py mi_salida.csv asistencia_larga.csv
Antes de arrancar, mirá los datos
| legajo | estudiante | sesion_01 | sesion_02 | sesion_03 | sesion_04 | sesion_05 | sesion_06 | sesion_07 | sesion_08 | sesion_09 | sesion_10 | sesion_11 | sesion_12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| L2701 | Rocío Duarte | P | P | A | P | P | A | P | A | A | P | A | A |
| L2702 | Yamila Escobar | P | P | P | P | A | A | P | P | P | P | P | P |
| L2703 | Fabián Bravo | A | P | P | P | vacio | P | P | P | P | P | P | P |
| L2704 | Pablo Luna | A | P | P | P | P | P | P | P | P | P | A | A |
| L2705 | Valeria Vidal | P | P | P | P | P | P | P | A | P | P | P | P |
El contrato de salida
asistencia_larga.csv · 360 filas
| Columna | Tipo | Que lleva |
|---|---|---|
legajo | texto | El legajo del estudiante, repetido una vez por sesion |
estudiante | texto | Su nombre, tambien repetido |
sesion | texto | El nombre de la columna de origen: sesion_01 a sesion_12 |
estado | texto | El contenido de la celda, sin espacios en los extremos. Puede quedar vacio |
valido | entero | 1 si el estado es exactamente P o A; 0 si no |
Que hacer con cada defecto
| Defecto | Donde | Accion | Adonde va |
|---|---|---|---|
| estado 'X' | 1 celda, L2711 en sesion_01 | NO NO se corrige ni se descarta: se conserva tal cual con valido = 0 | asistencia_larga.csv |
| estado 'PRESENTE' escrito completo | 1 celda, L2724 en sesion_03 | NO NO se normaliza a P. Adivinar la intencion es una decision que este ejercicio no toma | asistencia_larga.csv con valido = 0 |
| estado 'p' en minuscula | 1 celda, L2717 en sesion_08 | NO NO se normaliza. Es el caso mas tentador y el que mejor muestra el punto: normalizar aca seria decidir por el que cargo el dato | asistencia_larga.csv con valido = 0 |
| estado '-' | 1 celda, L2728 en sesion_10 | se se conserva tal cual con valido = 0 | asistencia_larga.csv |
| celda vacia | 1 celda, L2703 en sesion_05 | se se conserva como campo vacio con valido = 0 | asistencia_larga.csv |
Una fila puede tener mas de un problema. Se informa solo el primero de esta lista:
- melt con id_vars=['legajo', 'estudiante'] y value_vars = las 12 sesiones
- sacarle los espacios de los extremos al estado
- marcar valido = 1 solo si el estado es exactamente P o A
- ordenar por legajo y sesion
value_vars se declara explicitamente: sin el, melt derrite TODAS las columnas que no son id_vars, y si manana el archivo trae una columna mas se cuela en el resultado. El strip va antes de comparar; la normalizacion de mayusculas NO se hace, y esa es la decision del ejercicio.
Conteos clave
| alumnos | 30 |
|---|---|
| sesiones | 12 |
| asistencia_larga.csv | 360 |
| estados P | 283 |
| estados A | 72 |
| validos (P o A) | 355 |
| invalidos | 5 |
| por motivo |
Invariantes
Comprobaciones que tu resultado tiene que cumplir. Corrilas vos mismo antes de comparar los archivos:
len(largo) == 360
30 * 12 == 360
int(largo['valido'].sum()) == 355
int((largo['valido'] == 0).sum()) == 5
largo.duplicated(subset=['legajo', 'sesion']).sum() == 0
largo['legajo'].nunique() == 30
largo['sesion'].nunique() == 12
set(largo.loc[largo['valido'] == 1, 'estado']) == {'P', 'A'}
PISTASSi te trabas, abri esto
- Declara value_vars aunque parezca redundante: es lo que hace que el resultado no dependa de que columnas traiga el archivo el mes que viene.
- El par (legajo, sesion) tiene que ser unico en la salida: es la comprobacion de que el melt no duplico nada.
- No normalices la 'p' minuscula. Es tentador y es exactamente lo que el ejercicio no quiere: el informe tiene que mostrar que hay 5 celdas para revisar.
- Esta salida es la ENTRADA de EJ-6.7. Si la haces bien, el ejercicio siguiente arranca del archivo correcto.
Así tiene que quedar
| legajo | estudiante | sesion | estado | valido |
|---|---|---|---|---|
| L2701 | Rocío Duarte | sesion_01 | P | 1 |
| L2701 | Rocío Duarte | sesion_02 | P | 1 |
| L2701 | Rocío Duarte | sesion_03 | A | 1 |
| L2701 | Rocío Duarte | sesion_04 | P | 1 |
| L2701 | Rocío Duarte | sesion_05 | P | 1 |
value_vars aunque parezca redundante
Sin él, melt derrite todas las columnas que no están en
id_vars. Hoy da lo mismo; el día que el archivo traiga una columna
observaciones, esa columna se convierte en una «sesión» más y el
resultado pasa a tener 390 filas sin que nada avise.
EJ-6.7
El ejercicio siguiente calcula el porcentaje de asistencia a partir de esta tabla,
y ahí la columna valido deja de ser un detalle: define el
denominador. Un alumno con una celda ilegible no tiene 12 sesiones
computables, tiene 11.