DMarlon Studio

Lección 20 · 20 de 20

Proyecto: boletín de notas · Python

Un proyecto que reúne el curso básico de Python: lee notas de un archivo, ignora datos erróneos y escribe un boletín con medias y calificaciones.

Python · Proyecto: boletín de notas en DMarlon Studio: el código del ejemplo y su salida en la terminal

Este programa junta casi todo lo visto en el curso. Empieza con una función, grade(), que convierte una media en una letra usando if y return: en cuanto una condición se cumple, devuelve la letra y termina.

Después escribe un archivo marks.txt con una línea por alumno y lo vuelve a abrir para leerlo línea a línea. line.split(":") separa el nombre de las notas y se desempaqueta en name y text.

Las notas se separan con split(",") y cada una se convierte con float(), que acepta los espacios de alrededor. Ben tiene un «five» escrito con letras: float() lanza un ValueError, el except lo avisa y esa nota se descarta sin detener el programa.

Las notas válidas se van añadiendo a la lista marks y la media de cada alumno se guarda en el diccionario averages, con el nombre como clave.

Para terminar, un for sobre averages.items() escribe el boletín en columnas con f-strings, apunta en la lista passed a quien aprueba y recuerda la mejor media. ", ".join(passed) une los nombres en una sola línea.

Código · main.py

# Grade report: files, strings, lists, dicts, functions and errors.def grade(mark):    if mark >= 9:        return "A"    if mark >= 7:        return "B"    if mark >= 5:        return "C"    return "F"with open("marks.txt", "w") as file:    file.write("Ana: 8, 9.5, 7\nBen: 4, 6, five\nCarla: 9, 10, 9.5\nDani: 3, 5, 4\n")averages = {}with open("marks.txt") as file:    for line in file:        name, text = line.split(":")        marks = []        for part in text.split(","):            try:                marks.append(float(part))            except ValueError:                print(f"{name}: '{part.strip()}' is not a mark, skipped")        averages[name] = sum(marks) / len(marks)print(f"{'Student':<8}{'Avg':>6}  Grade")passed, best_name, best = [], "", 0for name, avg in averages.items():    print(f"{name:<8}{avg:>6.2f}  {grade(avg)}")    if avg >= 5:        passed.append(name)    if avg > best:        best_name, best = name, avgprint("Passed:", ", ".join(passed))print(f"Best average: {best_name} ({best:.2f})")

Salida · python3 main.py

Ben: 'five' is not a mark, skipped
Student    Avg  Grade
Ana       8.17  B
Ben       5.00  C
Carla     9.50  A
Dani      4.00  F
Passed: Ana, Ben, Carla
Best average: Carla (9.50)

Para recordar

  • Las funciones ordenan el programa en piezas con nombre.
  • Archivos + split() convierten texto en datos.
  • try/except evita que un dato erróneo pare el programa.
  • Listas y diccionarios guardan los resultados para el informe.
  • Las f-strings con ancho alinean la tabla.

Ejercicio

Amplíe el proyecto para que guarde el boletín en un archivo report.txt y añada al final la media de toda la clase y cuántos alumnos sacaron cada letra (con un diccionario de contadores).