2025-01-05 01:01:39 +01:00
|
|
|
from datatypes import *
|
2025-01-09 22:33:04 +01:00
|
|
|
from imgui_bundle import imgui, imgui_ctx, imgui_md, implot, ImVec2
|
|
|
|
import numpy as np
|
2025-01-05 01:01:39 +01:00
|
|
|
|
|
|
|
from model import *
|
|
|
|
|
|
|
|
class StudentInfo:
|
|
|
|
def __init__(self):
|
|
|
|
super().__init__()
|
2025-01-09 22:33:04 +01:00
|
|
|
self.select_class = 0
|
|
|
|
self.select_student = 0
|
2025-01-05 01:01:39 +01:00
|
|
|
|
2025-01-09 22:33:04 +01:00
|
|
|
def student_graph(self, student_id: int) -> None:
|
|
|
|
student = Student.get_by_id(student_id)
|
|
|
|
clas = Class.get_by_id(student.class_id)
|
|
|
|
lectures = Lecture.select().where(Lecture.class_id == clas.id)
|
|
|
|
submissions = Submission.select().where(Submission.student_id == student.id)
|
|
|
|
|
|
|
|
overall_points = np.sum([l.points for l in lectures])
|
|
|
|
points = np.sum([sub.points for sub in submissions])
|
|
|
|
if points.is_integer():
|
|
|
|
points = int(points)
|
2025-01-05 01:01:39 +01:00
|
|
|
|
2025-01-09 22:33:04 +01:00
|
|
|
subs_data = np.array([sub.points/l.points for sub, l in zip(submissions, lectures)])*100
|
|
|
|
subs_labels = [str(l.title) for l in lectures]
|
|
|
|
|
|
|
|
with imgui_ctx.begin_group():
|
|
|
|
imgui_md.render(f"# {student.prename} {student.surname}")
|
|
|
|
imgui_md.render(f"### {clas.name}")
|
|
|
|
|
|
|
|
pb_content = f"{points}/{overall_points} {points/overall_points:.1%}"
|
|
|
|
imgui.progress_bar(points/overall_points, overlay=pb_content)
|
2025-01-05 01:01:39 +01:00
|
|
|
|
2025-01-09 22:33:04 +01:00
|
|
|
implot.push_colormap(implot.Colormap_.deep.value)
|
|
|
|
if implot.begin_plot("Performance"):
|
|
|
|
implot.setup_axes("Lectures", "Percentage")
|
|
|
|
implot.setup_axes_limits(-1, len(subs_data), 0, 110)
|
|
|
|
implot.setup_axis_ticks(implot.ImAxis_.x1.value, 0, len(subs_labels), len(subs_labels), subs_labels, False)
|
|
|
|
implot.plot_bars("Submissions", subs_data)
|
|
|
|
implot.end_plot()
|
|
|
|
|
|
|
|
def student_list(self) -> int:
|
|
|
|
classes = Class.select()
|
|
|
|
content = [f"{n}. {c.name}" for n, c in enumerate(classes, start=1)]
|
|
|
|
students = Student.select().where(Student.class_id == classes[self.select_class].id)
|
|
|
|
lectures = Lecture.select().where(Lecture.class_id == classes[self.select_class].id)
|
|
|
|
|
|
|
|
overall_points = np.sum([l.points for l in lectures])
|
|
|
|
points = list()
|
|
|
|
for student in students:
|
|
|
|
submissions = Submission.select().where(Submission.student_id == student.id)
|
|
|
|
cummultative = [sub.points for sub in submissions]
|
|
|
|
passed = np.sum([p > overall_points*0.3 for p in cummultative])
|
|
|
|
points.append((student, np.sum(cummultative)/overall_points, passed > 1))
|
|
|
|
|
|
|
|
students = sorted(points, key=lambda x: x[1], reverse=True)
|
|
|
|
|
|
|
|
with imgui_ctx.begin_group():
|
|
|
|
_, self.select_class = imgui.combo("##class_list", self.select_class, content, len(content))
|
|
|
|
for n, student in enumerate(students, start=1):
|
|
|
|
s = student[0]
|
|
|
|
display = f"{n}. {s.prename} {s.surname}"
|
|
|
|
_, clicked = imgui.selectable(display, self.select_student == n-1)
|
|
|
|
if clicked:
|
|
|
|
self.select_student = n-1
|
|
|
|
|
|
|
|
return students[self.select_student][0].id
|
|
|
|
|
|
|
|
def __call__(self):
|
|
|
|
with imgui_ctx.begin("Student Info"):
|
|
|
|
w, h = imgui.get_window_size()
|
|
|
|
with imgui_ctx.begin_child("Student Selector", ImVec2(w*0.25, h*0.9)):
|
|
|
|
id = self.student_list()
|
|
|
|
imgui.same_line()
|
|
|
|
with imgui_ctx.begin_child("Student Graph", ImVec2(w*0.7, h*0.9)):
|
|
|
|
self.student_graph(id)
|
|
|
|
|