# Imprime una lista de tuplas, donde cada tupla está conformada por un valor "x" y un valor de "y"
# Y es llamada la función 'otro' pasándole una función lambda que suma dos números
#Proyecto Unidad 4
#Programa 18
#en este programa inicialmente mediante una función
#fue pedida la cantidad de materias con un try-except
#dentro de un while que se rompía despues de haber sido dado
#un número de materias
#la función regresa el número de materias
#después mediante una variable llamada mlista es mandada a llamar la función
#después fue declarada una lista llamada lista
#que seriá igual al rango del numero de materias dado por el usuario
def materias():
c = 1
while c:
try:
pmaterias = int(input("¿Cuántas materias? "))
c = 0
except:
print("Algo no funciona. Intenta de nuevo.")
return pmaterias
mlista = materias()
lista = list(range(mlista))
#este for es útil para asignar el nombre a cada materia por el usuario
#los nombres asignados por el usuario serán guardados en la lista creada
# Pide nombres de materias
for i in lista:
print("Materia", lista[i] + 1, ",", end=" ") # letrero
lista[i] = input("Dame el nombre de la materia: ")
#este for inicial recorrerá cada elemento de la lista
#a cada elemento en una variable le asignará el .txt en su nombre
#por cada materia se crea un archivo de texto para guardar datos
#se escribe el nombre de la materia al inicio del archivo
#la lista calificacionesmateria será útil para guardar todas las
#calificaciones de todos los estudiantes dentro de una materia
#y será reiniciada al principio del ciclo for cuando el índice
#este en la siguiente materia
#temp2 será util para guardar la suma de todas las calificaciones
#dentro de una materia (será útil esta suma para la media o promedio por materia)
#y será reiniciada al principio del ciclo for cuando el índice
#este en la siguiente materia
#la variable totalunidades será útil para contar la cantidad de unidades
#por materia entre todos los estudiantes dentro de una materia
#será útil para el promedio o media por materia
#esta variable será reiniciada cada que el ciclo este en su índice en la siguiente
#materia
#convertir materias a archivos mediante un for
for materia in lista:
nombre_archivo = materia + ".txt"#nombra como archivos las materias
archivo = open(nombre_archivo, "w") #crea el archivo y escribe en el
archivo.write("Materia: " + materia+"\n")
calificacionesmateria=[]
temp2=0
totalunidades=0
#mediante este try-except es pedido en entero cuantos estudiantes habrá en la
#materia actual
try:
num_estudiantes = int(input("\n¿Cuántos estudiantes hay en " + materia + "? "))
except:
print("Deben ser números")
#mediante este for recorrerá en un rango el total de estudiantes en la materia actual
#este for es útil para asignar un nombre a cada estudiante
#y escribir el nombre de cada estudiante en el archivo creado de la materia actual
#mediante un try-except dentro de este for será pedido el número de unidades por estudiante
#en entero, el ciclo se repetirá según el total de estudiantes en la materia actual
#despues es creada dentro de este for una lista vacia llamada calificacionesunidad
#será reiniciada cada que el índice del for pase al siguiente estudiante
#en la materia, esta lista será util para almacenar las calificaciones por estudiante
#y será útil esta lista para la media/promedio,mediana y moda
#la variable temp será útil para acumular la suma de calificaciones del estudiante actual
#para calcular su promedio personal, se reiniciará cada que el índice
#del for este en el siguiente estudiante
for estudiantes in range(num_estudiantes):
nombre_estudiante = input("\nNombre del estudiante " + str(estudiantes + 1) + ": ")
archivo.write("\nEstudiante " + str(estudiantes+1) + ": "+ nombre_estudiante+"\n")
try:
num_unidades = int(input("¿Cuántas unidades tiene " + nombre_estudiante + "? "))
except:
print("Deben ser numeros")
calificacionesunidad=[]
temp=0
#en este for recorrerá cada unidad por estudiante en la materia actual
#según el total dado
#mediante la variable calificación sera pedida cada calificación por unidad
#y cada calificación será escrita en el archivo
#por cada unidad que recorre el for por estudiante en la materia actual:
#temp acomulará la suma de todas las calificaciones por estudiante
#para el promedio/media, mediana y moda por estudiante
#temp2 acomulará la suma de todas las calificaciones por materia
#para el promedio/media, mediana y moda por materia
#a total unidades se le será incrementado 1, esta variable servirá para el promedio
#por materia
#serán agregadas cada calificación en las listas calificacionesunidad
#y calificacionesmateria, estas listas serán útiles para la mediana y moda
#por estudiante y materoa
for unidad in range(num_unidades):
calificacion =input("Calificación de la unidad #" + str(unidad + 1) + ": ")
archivo.write("Unidad " + str(unidad + 1) + ": " + calificacion + "\n")
temp+=int(calificacion)
promedio=temp/ num_unidades#calculo de promedio por estudiante
temp2+=int(calificacion)
totalunidades+=1
calificacionesunidad.append(int(calificacion))
calificacionesmateria.append(int(calificacion))
#.sort() lo investigue en internet, sirve para ordenar de menor a mayor una lista
#me resulto util para reducir código y no haber tenido que haber utilizado
#un for para ordenar las listas(lo que hubiera hecho mas largo el programa)
calificacionesunidad.sort()
calificacionesmateria.sort()
#cálculo moda por estudiante:
#primero fue declarado un diccionario vacio llamado moda
moda={}
#despues mediante un for que recorre la lista de las calificaciones por
#estudiante en la materia actual
#si la calificación actual que recorre el for ya estaba en el diccionario
#su value se le incrementará 1, sino se quedará en 1
#moda mayor se inicializara en 0 y se reiniciara por cada estudiante
#moda mayor sera igual al value maximo en el diccionario
#aqui utilizamos la herramienta max para reducir código y sirvió para
#saber que value en el diccionario moda era el mayoe
for i in calificacionesunidad:
if i in moda:
moda[i]+=1
else:
moda[i]=1
#print(moda)
modamayor=0
modamayor=max(moda.values())
#print(modamayor)
modas=[]
#mediante este for si el valor de modamayor es valor de una llave del diccionario
#sera agregado a una lista previamente creada llamada modas
#en esta lista se almacenará la moda o modas(en caso de haber mas de 1)
for j in moda:
if moda[j]==modamayor:
modas.append(j)
#cálculo de mediana por estudiante:
#fue declarada una variable n que seria igual a la longitud
#de la lista que contiene la calificación por estudiante
#si es impar la cantidad de calificaciones
#la mediana será igual al elemento que esta en la posición:
#de la longitud de la lista calificacionesunidad
#dividida en división entera entre 2
#si es par la cantidad de calficaciones
#la mediana será igual al elemento que esta en la posición:
#de la suma entre la división entera entre 2 menos 1 de la longitud
#de la lista calificacionesunidad mas la división entera entre 2
#de la lista calificacionesunidad
n=len(calificacionesunidad)
if n%2 ==1:
mediana=calificacionesunidad[n//2]
else:
mediana=(calificacionesunidad[n//2-1]+calificacionesunidad[n//2])/2
#cálculo de mediana por materia:
#es declarada una variable "X" que será igual a la longitud
#de la lista que almacena las calificaciones por materia
#el procedimiento es el mismo que el calculo de mediana por
#estudiante, solo las variables cambian
x=len(calificacionesmateria)
if x%2 ==1:#si es impar la cantidad de calificaciones
medianamateria=calificacionesmateria[x//2]
else:#si es par la cantidad de calficaciones
medianamateria=(calificacionesmateria[x//2-1]+calificacionesmateria[x//2])/2
#Impresión del promedio por estudiante en la materia actual
#es escrito tambien en el archivo de la materia:
#el promedio por estudiante en la materia actual
print("Promedio de ",nombre_estudiante," en ", materia,":",promedio)
archivo.write("Promedio de "+ nombre_estudiante+": " + str(promedio)+"\n")
#Impresión de la mediana por estudiante en la materia actual
#es escrito también en el archivo de la materia:
#la mediana por estudiante en la materia actual
print("La mediana entre las calificaciones de ",nombre_estudiante,"en la materia ", materia, "es: ",mediana)
archivo.write("Mediana de "+nombre_estudiante+" en la materia "+materia+" es: "+str(mediana)+"\n")
#imprimir moda/modas y escribirlas en el archivo
#el for sirve para que si son mas de 1 moda se escriba una coma entre ellas
print("Moda de ",nombre_estudiante," en ",materia,":",end=" ")
for k in range(len(modas)):
if k<(len(modas)-1):
print(modas[k],end=",")
else:
print(modas[k])
archivo.write("Moda de "+nombre_estudiante+" en "+materia+": ")
for k in range(len(modas)):
if k<(len(modas)-1):
archivo.write(str(modas[k])+",")
else:
archivo.write(str(modas[k])+"\n")
#cálculo de moda por materia:
#este proceso es el mismo que el que
#fue realizado para el cálculo de la moda por estudiante
#solo cambia el nombre de las variables
modamat={}
for i in calificacionesmateria:
if i in modamat:
modamat[i]+=1
else:
modamat[i]=1
modamatmayor=0
modamatmayor=max(modamat.values())
modasmat=[]
for j in modamat:
if modamat[j]==modamatmayor:
modasmat.append(j)
#en esta sección estas variables son reiniciadas
#estas variables son utiles para cálculos solo para estudiantes
#y no para materias completas
calificacionesunidad=[]
temp=0
promedio=0
#en la siguiente sección hay sólo cálculos y impresiones
#de operaciones/datos correspondientes a lo que corresponde
#a materias completas y no a estudiantes individuales en materias
if totalunidades>0:
#cálculo de promedio por materia:
promediomateria=temp2/totalunidades
#imprimir promedio por materia y escribirlo en el archivo:
archivo.write("\nPromedio de la materia "+materia+" es: "+ str(promediomateria))
print("\nPromedio de la materia", materia, ":",promediomateria)
#imprimir mediana por materia y escribirla en el archivo
print("La mediana en la materia ", materia, "es: ",medianamateria)
archivo.write("\nMediana en la materia "+materia+" es: "+str(medianamateria))
#imprimir moda por materia y escribirla en el archivo
#el for es para que si hay mas de una moda imprima y escriba
#una coma entre ellas
print("La moda en la materia ",materia," es: ",end=" ")
for k in range(len(modasmat)):
if k<(len(modasmat)-1):
print(modasmat[k],end=",")
else:
print(modasmat[k])
#escribir en archivo moda/modas por materia
archivo.write("\nLa moda en la materia "+materia+" es: ")
for k in range(len(modasmat)):
if k<(len(modasmat)-1):
archivo.write(str(modasmat[k])+",")
else:
archivo.write(str(modasmat[k])+"\n")
#lo siguiente cierra el archivo de la materia actual
archivo.close()
#la primer libreria permite las gráficas
#la segunda para realizar operaciones matemáticas
import matplotlib.pyplot as plt
import numpy as np
# Gráfica 1, de un alumno específico
#Primero fue definida una función llamada grafica_alumno que no recibe parámetros
#esta función será útil para graficar las calificaciones de un alumno específico en una materia
#su media,mediana y moda
#dentro de esta función primero:
#solicita al usuario el nombre del alumno y el de la materia para poder buscar sus datos
def grafica_alumno():
nombre_alumno = input("\nIngresa el nombre del alumno a graficar: ")
materia_grafica = input("Ingresa el nombre de la materia: ")
#mediante un try-except intenta abrir el archivo de la materia
#si no existe ejecutará el except y con el return sale de la función
try:
with open(materia_grafica + ".txt", "r") as archivo:
lineas = archivo.readlines()
except:
print("algo salio mal o no existe")
return
# Buscar las calificaciones del alumno
#la lista calificaciones servirá para guardar las calificaciones del alumno
#la variable encontrado para saber si fue encontrado
calificaciones = []
encontrado = False
#en este ciclo while:
#el índice i inicia en 0
#este bucle recorre cada linea del archivo, mientras el índice sea
#menor que el número total de lineas
#así también extraé la linea actual del archivo en la posición del índice
#y la guarda en linea
i=0
while i< len(lineas):
linea= lineas[i]
#en este if si la linea actual contiene la palabra "Estudiante
#y el nombre del alumno dado previamente al que se quiere obtener su gráfica
#encontrado será igual a True (es decir que si fue encontrado)
#el índice se incrementará 1 (es decir avanzará al siguiente renglón,
#que será la primera calificación del alumno en la primer unidad)
if "Estudiante" in linea and nombre_alumno in linea:
encontrado= True
i+=1
#en este while:
#mientras no este el índice en el final del archivo
#y la linea actual contenga la palabra "Unidad"
#seguirá leyendo calificaciones
while i < len(lineas) and "Unidad" in lineas[i]:
#la siguiente linea:
#separa los dos elementos que separa ":" mediante .split
#mediante [i] toma la calificación
#.strip quita espacios
#por ejemplo: "Unidad 1: 90"
#tomará 90 y lo convierte a entero
calificacion = int(lineas[i].split(": ")[1].strip())
#la siguiente linea
#agrega la calificación extraída a la lista calificaciones
#para la media,mediana y moda
calificaciones.append(calificacion)
#el índice es aumentado 1 para cambiar de unidad
i+=1
#si el while se deja de cumplir se romperá el previo también
break
#este else sirve por si la linea no contiene al alumno buscado para
#pasar a la siguiente linea hasta que la linea contenga al alumno
#deseado
else:
i+=1
#si no se encontró el alumno o no tiene calificaciones
#se imprime "no existe"
#y ocasiona salida de la función con el return
if not encontrado or not calificaciones:
print("no existe")
return
# Cálculo de estadísticas
#mediante la libreria numpy se obtuvo la media y la mediana
#de una forma mas reducida que al usar varios ciclos for
media = np.mean(calificaciones)
mediana = np.median(calificaciones)
#la moda para la gráfica la obtuvimos por el mismo método
#que usamos para la moda por estudiante y por materia
modagraf={}
for m in calificaciones:
if m in modagraf:
modagraf[m]+=1
else:
modagraf[m]=1
maxmodagraf=max(modagraf.values())
modasgraf=[]
for n in modagraf:
if modagraf[n]==maxmodagraf:
modasgraf.append(n)
# Gráfica de barras (unidades con calificaciones)
#el eje X que es la variable unidades esta definido en el rango
#de 1 a la longitud de las calificaciones + 1
#si hay 3 unidades, unidades será igual a 1,2,3
#y la figura que tendrá las subgráficas será de 12x5 pulgadas
unidades = range(1, len(calificaciones) + 1)
plt.figure(figsize=(12, 5))
#se crea la primer subgráfica dentro de la figura 1
#que tendrá 1 fila y 2 columnas
plt.subplot(1, 2, 1) # Subgráfica 1: Calificaciones por unidad
#en la siguiente linea se dibuja la gráfica de barras
#donde el eje X son las unidades y el Y las calificaciones
plt.bar(unidades, calificaciones, color='blue', alpha=0.7)
#la siguientes lineas son el titulo y las etiquetas para el eje X y Y
plt.title(f"Calificaciones de {nombre_alumno} en {materia_grafica}")
plt.xlabel("Unidad")
plt.ylabel("Calificación")
#establece el rango del eje Y
plt.ylim(0, 100)
#se selecciona 1 fila, 2 columnas y la 2da gráfica
plt.subplot(1, 2, 2) # Subgráfica 2: Estadísticas
#despues es creada una lista llamada estadisticas que contiene la media,
#mediana y moda/modas
estadisticas = [media, mediana] + modasgraf
#lo siguiente son etiquetas
etiquetas = ['Media', 'Mediana']+ ["Moda" + str(i+1) for i in range(len(modasgraf))]
plt.bar(etiquetas, estadisticas, color=['red', 'green']+['purple']*len(modasgraf))
plt.title("Estadísticas del alumno")
plt.ylabel("Cálculos")
plt.ylim(0, 100)
#ajusta el espaciado entre las subgráficas para que no se sobrepongan
plt.tight_layout()
#muestra la gráfica
plt.show()
#Gráfica 2, de una materia:
#Fue definida una función llamada grafica_materia que no recibe parámetros
#esta función será útil para graficar las calificaciones de una materia
#su media,mediana y moda
#dentro de esta función primero:
#solicita al usuario el nombre de la materia a graficar
def grafica_materia():
materia_grafica = input("\nIngresa el nombre de la materia a graficar: ")
#mediante un try-except intenta abrir el archivo de la materia
#si no existe ejecutará el except y con el return sale de la función
try:
with open(materia_grafica + ".txt", "r") as archivo:
lineas = archivo.readlines()
except:
print("la materia no existe o algo salió mal")
return
# Listas para datos de todos los alumnos
#servirán para almacenar los nombres
#y la otra lista para el promedio final
alumnos = []
calificacionestotales = []
#en este ciclo while:
#el índice i inicia en 0
#este bucle recorre cada linea del archivo, mientras el índice sea
#menor que el número total de lineas
i = 0
while i < len(lineas):
#si se encuentra una linea con estudiante en el indice actual del archivo
#se extraerá su nombre y se guarda en la lista alumnos
if "Estudiante" in lineas[i]:
nombre_alumno = lineas[i].split(": ")[1].strip()
alumnos.append(nombre_alumno)
#j se incrementa para que empieze a leer el índice
#las calificaciones
j = i + 1
califalumno = []
#en este while se procesan las lineas que sean menor a
# la longitud del archivo y contengan la palabra
#"Unidad" a partir de la linea después despues del nombre del
#estudiante, aqui se extraén las calificaciones y se guardan
#en califalumno
while j < len(lineas) and "Unidad" in lineas[j]:
calif = int(lineas[j].split(": ")[1].strip())
califalumno.append(calif)
j += 1
#al terminar el índice con un alumno se guardan sus calificaciones
#en calificacionestotales
#i se actualiza para continuar en el siguiente alumno
calificacionestotales.append(califalumno)
i = j
else:
i += 1
#si no hay alumnos habrá salida de la función
if not alumnos:
print("no hay alumnos en esta materia, o algo salió mal")
return
# Cálculo de estadísticas de la materia
#califestad servirá para guardar todas las calificaciones en total
califestad = []
#mediante este for se agregarán todas las calificaciones a
#una sola lista (califestad)
for alumno in calificacionestotales:
for calif in alumno:
califestad.append(calif)
#asi como en la función pasada usamos la libreria numpy para
#calcular la media y la mediana mas cortamente
media = np.mean(califestad)
mediana = np.median(califestad)
#y usamos el metodo que hemos utilizado durante el todo programa
#para obtener la moda/modas
modagrafmat={}
for n in califestad:
if n in modagrafmat:
modagrafmat[n]+=1
else:
modagrafmat[n]=1
maxmodagrafmat=max(modagrafmat.values())
modasgrafmat=[]
for o in modagrafmat:
if modagrafmat[o]==maxmodagrafmat:
modasgrafmat.append(o)
# Gráfica de barras (alumnos con cálculos)
#la figura tendra 14x6 pulgadas
plt.figure(figsize=(14, 6))
# Subgráfica 1: Calificaciones por alumno
#se define la gráfica 1 de 1 fila y 2 columnas
plt.subplot(1, 2, 1)
etiquetas=[]#lista para nombres
valores=[]#listas para calificaciones
colores=[]#lista para color de barra
posiciones=[]#guardar´z las posiciones
coloresunidades=['red','green','blue']#colores según la unidad
posicion = 0#irá aumentando para el eje X
indicealumno=0
espacio=0.5#separación entre grupos de alumnos
#este ciclo while recorre todos los alumnos que hay en la lista alumnos
#se ejecutará mientras indicealumno sea menor a la cantidad de alumnos
#servirá para la construcción de la subgráfica 1
while indicealumno < len(alumnos):
indiceunidad=0
#el siguiente while recorre las calificaciones en el alumno actual
#agregará la calificación de la unidad actual en valores
#crea la etiqueta que irá en cada unidad en el eje X
#asigna un color diferente a cada unidad, % servirá para repetir los colores
#de forma cíclica
#posiciones es para guardar en que lugar horizontal debe ir cada barra
#en el eje X
#asi tambien se incrementará una posición
#y una unidad
#si se el índice terminó con las unidades de un alumno incrementara 0.5 a
#la posición y pasará al siguiente alumno
while indiceunidad < len(calificacionestotales[indicealumno]):
valores.append(calificacionestotales[indicealumno][indiceunidad])
etiquetas.append("U"+str(indiceunidad+1)+"-"+alumnos[indicealumno])
colores.append(coloresunidades[indiceunidad % len(coloresunidades)])
posiciones.append(posicion)
posicion +=1
indiceunidad+=1
posicion += espacio
indicealumno+=1
#posiciones es la ubicación horizontal
#valores es la altura
#color los colores de cada barra
#alpha la transparencia de la barra
plt.bar(posiciones,valores,color=colores,alpha=0.7)
#la siguiente linea indica donde ira cada etiqueta en el eje x
#y las establece
#con su rotación
#y ha es la alineación
plt.xticks(posiciones,etiquetas,rotation=45,ha="right")
#lo siguiente son títulos
plt.title("Calificaciones en " +materia_grafica)
plt.xlabel("Unidad - Alumno")
plt.ylabel("Calificación")
plt.ylim(0, 100)#limite del eje y
# Subgráfica 2: Estadísticas de la materia
#la segunda subgráfica tendrá una fila y 2 columnas en su espacio
#es decir en las etiquetas
plt.subplot(1, 2, 2)
#etiquetas del eje X
estadisticas = [media, mediana]
etiquetasest = ['Media', 'Mediana']
#el siguiente for es por si hay mas de 1 moda
for f in range(len(modasgrafmat)):
estadisticas.append(modasgrafmat[f])
etiquetasest.append("Moda "+ str(f + 1))
#etiquetasest son los nombres en el eje X
#estadisticas su valor
#color los colores
plt.bar(etiquetasest, estadisticas, color=['red', 'green']+ ['purple']*len(modasgrafmat))
#lo siguiente corresponde a los títulos y al limite en el eje Y
plt.title("Estadísticas de la materia")
plt.ylabel("Cálculos")
plt.ylim(0, 100)
#ajusta espacios
plt.tight_layout()
#muestra la gráfica
plt.show()
#el siguiente menú mostrará la gráfica que el usuario desee ver según las
#funciones hechas
#Menú para elegir gráficas
def menu_graficas():
while True:
print("\n--- MENÚ DE GRÁFICAS ---")
print("1. Gráfica de un alumno")
print("2. Gráfica de una materia")
print("3. Salir")
opcion = input("Elige una opción (1-3): ")
if opcion == "1":
grafica_alumno()
elif opcion == "2":
grafica_materia()
elif opcion == "3":
break
else:
print("Opción inválida. Intenta de nuevo.")
# Ejecutar el menú después de guardar los datos
menu_graficas()
Comentarios
Publicar un comentario