Indice / Practicas / EJ-1.3
EJ-1.3 · Promedios descartando notas invalidas
Cuarenta estudiantes, tres notas cada uno, y nueve filas que hay que dejar afuera. La mitad del ejercicio es calcular el promedio; la otra mitad es decidir a quién no calculárselo.
Qué hay que hacer
A partir de estudiantes_notas.csv (40 filas), producir
promedios_descarte.csv con una fila por estudiante que tenga las
tres notas usables: el legajo, el nombre, las tres notas y el promedio con dos
decimales.
La política es descartar: si una sola de las tres notas no sirve, el estudiante no aparece. Sin pandas.
ELI5Explicado facil
Un promedio de dos notas y uno de tres no son el mismo número, aunque los dos se llamen «promedio». Compararlos es como comparar el promedio de goles de un jugador que jugó todo el año con el de otro que jugó tres partidos.
Este ejercicio elige la respuesta conservadora: si no están las tres, no hay promedio.
Archivos
- Entrada ·
estudiantes_notas.csv - Objetivo ·
promedios_descarte.csv - Herramienta ·
comparar.py
El par con EJ-5.7
El ejercicio EJ-5.7 de la unidad 5 usa este mismo archivo y en vez de descartar, imputa las notas que faltan. Su objetivo tiene 40 filas; este tiene 31.
Ninguno de los dos está mal. La política la fija el enunciado, no los datos, y esa es la idea que ninguna otra sección del curso enseña.
Los tres defectos, en orden de peligro
| Cuántos | Qué | Cómo se detecta |
|---|---|---|
| 4 celdas | Los tokens '', 'N/A' y '-' (dos veces) | float() falla: un except ValueError alcanza |
| 1 celda | El token 'NaN' | Nadie. float("NaN") devuelve un número y el promedio da nan |
| 4 celdas | Notas fuera de 0 a 10, incluida una de -1 | Nadie. Son números perfectamente válidos… para Python |
Nueve celdas defectuosas, nueve estudiantes descartados: cada uno tiene un solo problema. Si te dan 5 descartados te faltó el chequeo de rango; si te dan 4, te faltó el de ausentes.
Cómo saber si te salió
python comparar.py mi_salida.csv promedios_descarte.csv
Si no dice nada, tu archivo es idéntico al esperado. Si difiere, te dice qué fila y qué columna.
Antes de arrancar, mirá los datos
| legajo | estudiante | nota_1 | nota_2 | nota_3 |
|---|---|---|---|---|
| L2601 | Karina Acosta | 9.7 | 4.7 | 8.6 |
| L2602 | Santiago Ramos | 6.0 | 3.8 | 4.2 |
| L2603 | Carla Luna | 8.1 | 3.6 | 3.8 |
| L2604 | Lucas Núñez | 7.3 | 7.4 | 3.4 |
| L2605 | Tamara Torres | 9.5 | 9.5 | 7.8 |
El contrato de salida
promedios_descarte.csv · 31 filas
| Columna | Tipo | Que lleva |
|---|---|---|
legajo | texto | El legajo tal cual vino |
estudiante | texto | El nombre tal cual vino |
nota_1 | decimal | La nota como numero, 2 decimales |
nota_2 | decimal | La nota como numero, 2 decimales |
nota_3 | decimal | La nota como numero, 2 decimales |
promedio | decimal | (nota_1 + nota_2 + nota_3) / 3, redondeado a 2 decimales |
Que hacer con cada defecto
| Defecto | Donde | Accion | Adonde va |
|---|---|---|---|
| nota ausente | 5 celdas, todas en nota_3: los tokens '', 'N/A', '-' (x2) y 'NaN' | descartar descartar al estudiante entero, no solo la nota | no aparece en promedios_descarte.csv |
| el token 'NaN' en nota_3 | 1 celda | tratarlo tratarlo como ausente. Es el caso peligroso: float('NaN') NO falla, devuelve nan, y un solo nan convierte el promedio entero en nan | no aparece en promedios_descarte.csv |
| nota fuera del rango 0 a 10 | 4 celdas: 2 en nota_1, 1 en nota_2 y 1 en nota_3, incluida una nota de -1 | descartar descartar al estudiante entero. El rango lo fija el reglamento de la materia, no los datos | no aparece en promedios_descarte.csv |
| nota no numerica | 0 celdas en este archivo | la la comprobacion va igual: los cuatro tokens de ausente ya la cubren, pero un 'ocho' escrito con letras entraria por aca | no aparece en promedios_descarte.csv |
Una fila puede tener mas de un problema. Se informa solo el primero de esta lista:
- para cada una de las tres notas: token de ausente, conversion a float, rango 0 a 10
- si alguna de las tres falla, el estudiante no participa
- recien con las tres notas usables se calcula el promedio
El token de ausente se revisa ANTES de convertir, porque float('NaN') no falla: si se convierte primero, ese estudiante entra con un nan y arruina su promedio sin levantar ninguna excepcion.
Conteos clave
| filas de entrada | 40 |
|---|---|
| promedios_descarte.csv | 31 |
| estudiantes descartados | 9 |
| por motivo | ausente: 5, fuera_de_rango: 4 |
Invariantes
Comprobaciones que tu resultado tiene que cumplir. Corrilas vos mismo antes de comparar los archivos:
len(promedios) == 31
promedios['legajo'].is_unique
promedios['legajo'].is_monotonic_increasing
not promedios.isna().any().any()
promedios[['nota_1', 'nota_2', 'nota_3']].ge(0).all().all()
promedios[['nota_1', 'nota_2', 'nota_3']].le(10).all().all()
promedios['promedio'].between(0, 10).all()
(promedios['promedio'] - promedios[['nota_1','nota_2','nota_3']].mean(axis=1)).abs().max() < 0.005
PISTASSi te trabas, abri esto
- float('NaN') no levanta ValueError: devuelve nan. Si no filtras el token antes de convertir, ese estudiante entra y su promedio da nan.
- El estudiante se descarta ENTERO, no la nota suelta. Un promedio sobre dos notas no es comparable con uno sobre tres.
- Los 9 descartados son 5 por nota ausente y 4 por nota fuera de rango. Si te dan 5, te falto el chequeo de rango; si te dan 4, te falto el de ausentes.
- Compara tu resultado con el de EJ-5.7 cuando llegues: mismo archivo, politica opuesta, y ninguno de los dos esta mal.
Así tiene que quedar
| legajo | estudiante | nota_1 | nota_2 | nota_3 | promedio |
|---|---|---|---|---|---|
| L2601 | Karina Acosta | 9.7 | 4.7 | 8.6 | 7.67 |
| L2602 | Santiago Ramos | 6.0 | 3.8 | 4.2 | 4.67 |
| L2603 | Carla Luna | 8.1 | 3.6 | 3.8 | 5.17 |
| L2604 | Lucas Núñez | 7.3 | 7.4 | 3.4 | 6.03 |
| L2605 | Tamara Torres | 9.5 | 9.5 | 7.8 | 8.93 |
El token de ausente se revisa antes de convertir. Si convertís
primero, float("NaN") no se queja, ese estudiante entra con un
nan, y su promedio queda en nan sin que se levante ninguna
excepción - ni siquiera se nota hasta que alguien mira el archivo.
round(suma / 3, 2) sobre el número, no al escribir. Las tres notas ya
vienen con un decimal y se escriben tal cual; el único cálculo es el promedio.