Added: Student Ranking

This commit is contained in:
DerGrumpf 2025-01-08 11:38:31 +01:00
parent 0cc4ed243d
commit 70ea8899e2
10 changed files with 232 additions and 35 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
# ---> ImGUI # ---> ImGUI
imgui.ini *.ini
# ---> Python # ---> Python
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files

33
assets/Student_list.csv Normal file
View File

@ -0,0 +1,33 @@
First Name,Last Name,Sex,Tutorial 1,Tutorial 2,Extended Applications,Numpy & MatPlotLib,SciPy,Monte Carlo,Pandas & Seaborn,Folium
Abdalaziz,Abunjaila,Male,30.5,15,18,28,17,17,17,22
Marleen,Adolphi,Female,29.5,15,18,32,19,0,17,24
Aurela,Brahimi,Female,17.5,15,15.5,26,16,17,19,16
Cam Thu,Do,Female,31,15,18,34,19,20,21.5,22
Nova,Eib,Female,31,15,15,34,20,20,21,27
Nele,Grundke,Female,23.5,13,16,28,20,17,21,18
Anna,Grünewald,Female,12,14,16,29,16,15,19,9
Yannik,Haupt,Male,18,6,14,21,13,2,9,0
Janna,Heiny,Female,30,15,18,33,18,20,22,25
Milena,Krieger,Female,30,15,18,33,20,20,21.5,26
Julia,Limbach,Female,27.5,12,18,29,11,19,17.5,26
Viktoria,Litza,Female,21.5,15,18,27,13,20,22,21
Manthey,Leonie,Female,28.5,14,18,29,20,10,18,23
Izabel,Mike,Female,29.5,15,15,35,11,4,19,21
Lea,Noglik,Female,22.5,15,17,34,13,10,20,0
Donika,Nuhiu,Female,31,13.5,18,35,14,10,17,18
Julia,Renner,Female,27.5,10,14,0,20,17,11,20
Fabian,Rothberger,Male,30.5,15,18,34,17,17,19,22
Natascha,Rott,Female,29.5,12,18,32,19,20,21,26
Isabel,Rudolf,Female,27.5,9,17,34,16,19,19,21
Melina,Sablotny,Female,31,15,18,33,20,20,21,19
Alea,Schleier,Female,27,14,18,34,16,18,21.5,22
Flemming,Schur,Male,29.5,15,17,34,19,20,19,22
Marie,Seeger,Female,27.5,15,18,32,14,9,17,22
Lucy,Thiele,Female,27.5,15,18,27,20,17,19,18
Lara,Troschke,Female,28.5,14,17,28,13,19,21,25
Inga-Brit,Turschner,Female,25.5,14,18,34,20,16,19,22
Alea,Unger,Female,30,12,18,31,20,20,21,22
Marie,Wallbaum,Female,28.5,14,18,34,17,20,19,24
Katharina,Walz,Female,31,15,18,31,19,19,17,24
Xiaowei,Wang,Male,30.5,14,18,26,19,17,0,0
Lilly-Lu,Warnken,Female,30,15,18,30,14,17,19,14
1 First Name Last Name Sex Tutorial 1 Tutorial 2 Extended Applications Numpy & MatPlotLib SciPy Monte Carlo Pandas & Seaborn Folium
2 Abdalaziz Abunjaila Male 30.5 15 18 28 17 17 17 22
3 Marleen Adolphi Female 29.5 15 18 32 19 0 17 24
4 Aurela Brahimi Female 17.5 15 15.5 26 16 17 19 16
5 Cam Thu Do Female 31 15 18 34 19 20 21.5 22
6 Nova Eib Female 31 15 15 34 20 20 21 27
7 Nele Grundke Female 23.5 13 16 28 20 17 21 18
8 Anna Grünewald Female 12 14 16 29 16 15 19 9
9 Yannik Haupt Male 18 6 14 21 13 2 9 0
10 Janna Heiny Female 30 15 18 33 18 20 22 25
11 Milena Krieger Female 30 15 18 33 20 20 21.5 26
12 Julia Limbach Female 27.5 12 18 29 11 19 17.5 26
13 Viktoria Litza Female 21.5 15 18 27 13 20 22 21
14 Manthey Leonie Female 28.5 14 18 29 20 10 18 23
15 Izabel Mike Female 29.5 15 15 35 11 4 19 21
16 Lea Noglik Female 22.5 15 17 34 13 10 20 0
17 Donika Nuhiu Female 31 13.5 18 35 14 10 17 18
18 Julia Renner Female 27.5 10 14 0 20 17 11 20
19 Fabian Rothberger Male 30.5 15 18 34 17 17 19 22
20 Natascha Rott Female 29.5 12 18 32 19 20 21 26
21 Isabel Rudolf Female 27.5 9 17 34 16 19 19 21
22 Melina Sablotny Female 31 15 18 33 20 20 21 19
23 Alea Schleier Female 27 14 18 34 16 18 21.5 22
24 Flemming Schur Male 29.5 15 17 34 19 20 19 22
25 Marie Seeger Female 27.5 15 18 32 14 9 17 22
26 Lucy Thiele Female 27.5 15 18 27 20 17 19 18
27 Lara Troschke Female 28.5 14 17 28 13 19 21 25
28 Inga-Brit Turschner Female 25.5 14 18 34 20 16 19 22
29 Alea Unger Female 30 12 18 31 20 20 21 22
30 Marie Wallbaum Female 28.5 14 18 34 17 20 19 24
31 Katharina Walz Female 31 15 18 31 19 19 17 24
32 Xiaowei Wang Male 30.5 14 18 26 19 17 0 0
33 Lilly-Lu Warnken Female 30 15 18 30 14 17 19 14

BIN
assets/Student_list.xlsx Normal file

Binary file not shown.

42
assets/convert.py Normal file
View File

@ -0,0 +1,42 @@
import pandas as pd
import pprint
import sys
sys.path.append('..')
from model import *
df = pd.read_csv("Student_list.csv")
courses = {
'Tutorial 1': 31,
'Tutorial 2': 15,
'Extended Applications': 18,
'Numpy & MatPlotLib': 35,
'SciPy': 20,
'Monte Carlo': 20,
'Pandas & Seaborn': 22,
'Folium': 27
}
# Create Class
clas = Class.create(name='WiSe 24/25')
#print(clas.id)
# Create Courses
for k, v in courses.items():
Lecture.create(title=k, points=v, class_id=clas.id)
#print(l.title, l.points, l.class_id, l.id)
for index, row in df.iterrows():
s = Student.create(
prename=row["First Name"],
surname=row["Last Name"],
sex=row["Sex"],
class_id=clas.id
)
for title, points in list(row.to_dict().items())[3:]:
Submission.create(
student_id=s.id,
lecture_id=Lecture.select().where(Lecture.title == title),
points=points
)

BIN
assets/test.db Normal file

Binary file not shown.

View File

@ -6,12 +6,20 @@ class MainMenu:
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.new = False
self.new_text = str()
def __call__(self): def __call__(self):
if self.new:
self.create_new_file()
with imgui.begin_main_menu_bar() as main_menu_bar: with imgui.begin_main_menu_bar() as main_menu_bar:
if main_menu_bar: if main_menu_bar:
with imgui.begin_menu("File", True) as file_menu: with imgui.begin_menu("File", True) as file_menu:
if file_menu.opened: if file_menu.opened:
imgui.menu_item("New", " ", False, True) new, _ = imgui.menu_item("New", " ", False, True)
if new:
self.new = True
imgui.menu_item("Open", " ", False, True) imgui.menu_item("Open", " ", False, True)
imgui.menu_item("Save", " ", False, True) imgui.menu_item("Save", " ", False, True)
imgui.menu_item("Save as", " ", False, True) imgui.menu_item("Save as", " ", False, True)
@ -24,3 +32,6 @@ class MainMenu:
clicked, _ = imgui.menu_item(l.name.title(), None, False, True) clicked, _ = imgui.menu_item(l.name.title(), None, False, True)
if clicked: if clicked:
return l return l
def create_new_file(self):
pass

135
model.py
View File

@ -1,7 +1,11 @@
from peewee import * from peewee import *
from datetime import datetime from datetime import datetime
db = SqliteDatabase('test.db') import json
from typing import TextIO
from pathlib import Path
db = SqliteDatabase(None, autoconnect=False)
class BaseModel(Model): class BaseModel(Model):
class Meta: class Meta:
@ -30,39 +34,59 @@ class Submission(BaseModel):
points = FloatField() points = FloatField()
created_at = DateTimeField(default=datetime.now) created_at = DateTimeField(default=datetime.now)
db.connect() def load_from_json(fp: Path) -> None:
db.create_tables([Class, Student, Lecture, Submission]) '''
Rebuilding Database from a given json
if __name__ == "__main__": '''
'''import random with open(fp, "r") as file:
# Generate Test Data data = json.load(file)
class1 = Class.create(name="WiSe 22/23")
class2 = Class.create(name="WiSe 23/24")
class3 = Class.create(name="WiSe 24/25")
phil = Student.create(prename="Phil", surname="Keier", sex="Male", class_id=class1.id)
calvin = Student.create(prename="Calvin", surname="Brandt", sex="Male", class_id=class2.id)
nova = Student.create(prename="Nova", surname="Eib", sex="Female", class_id=class1.id)
kathi = Student.create(prename="Katharina", surname="Walz", sex="Female", class_id=class3.id)
victoria = Student.create(prename="Victoria", surname="Möller", sex="Female", class_id=class3.id)
lec1 = Lecture.create(title="Tutorial 1", points=30, class_id=class1.id)
lec2 = Lecture.create(title="Tutorial 1", points=30, class_id=class3.id)
lec3 = Lecture.create(title="Tutorial 2", points=20, class_id=class1.id)
lec4 = Lecture.create(title="Tutorial 2", points=20, class_id=class2.id)
lec5 = Lecture.create(title="Extended Applications", points=44, class_id=class1.id)
sub1_phil = Submission.create(student_id=phil.id, lecture_id=lec1.id, points=random.randint(0, lec1.points))
sub2_phil = Submission.create(student_id=phil.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub3_phil = Submission.create(student_id=phil.id, lecture_id=lec5.id, points=random.randint(0, lec5.points))
sub1_nova = Submission.create(student_id=nova.id, lecture_id=lec1.id, points=random.randint(0, lec1.points))
sub2_nova = Submission.create(student_id=nova.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub1_kathi = Submission.create(student_id=kathi.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub1_vici = Submission.create(student_id=victoria.id, lecture_id=lec2.id, points=random.randint(0, lec2.points))'''
for c_k, c_v in data.items():
Class.create(
name=c_k,
id=c_v["DB ID"],
created_at=c_v["Date"]
)
#print(f"KLASSE = {c.id} {c.name} ({c.created_at})")
for student in c_v["Students"]:
Student.create(
id=student["DB ID"],
created_at=student["Date"],
prename=student["First Name"],
surname=student["Last Name"],
sex=student["Sex"],
class_id=c_v["DB ID"]
)
#print(f"STUDENT = {s.id}. {s.prename} {s.surname} {s.sex} ({s.created_at}) Klasse: {s.class_id}")
for submission in student["Submissions"]:
Submission.create(
id=submission["DB ID"],
created_at=submission["Date"],
points=submission["Points"],
lecture_id=submission["Lecture ID"],
student_id=student["DB ID"]
)
#print(f"SUBMISSION = {sub.id}. {sub.points} Lecture: {sub.lecture_id} Student: {sub.student_id} ({sub.created_at})")
for lecture in c_v["Lectures"]:
Lecture.create(
id=lecture["DB ID"],
created_at=lecture["Date"],
title=lecture["Title"],
points=lecture["Points"],
class_id=c_v["DB ID"]
)
#print(f"LECTURE = {l.id}. {l.title} {l.points} ({l.created_at}) Klasse: {l.class_id}")
def dump_to_json(fp: Path, indent=None) -> None:
'''
Dump existing Database to Json
'''
classes = Class.select() classes = Class.select()
d = {c.name: { d = {c.name: {
"DB ID": c.id, "DB ID": int(c.id),
"Date": c.created_at.isoformat(), "Date": c.created_at.isoformat(),
"Students": [ "Students": [
{ {
@ -96,5 +120,50 @@ if __name__ == "__main__":
for c in classes for c in classes
} }
import json with open(fp, "w") as file:
print(json.dumps(d)) json.dump(d, file, indent=indent)
db.init('test.db')
db.connect()
db.create_tables([Class, Student, Lecture, Submission])
def main():
import random
# Generate Test Data
class1 = Class.create(name="WiSe 22/23")
class2 = Class.create(name="WiSe 23/24")
class3 = Class.create(name="WiSe 24/25")
phil = Student.create(prename="Phil", surname="Keier", sex="Male", class_id=class1.id)
calvin = Student.create(prename="Calvin", surname="Brandt", sex="Male", class_id=class2.id)
nova = Student.create(prename="Nova", surname="Eib", sex="Female", class_id=class1.id)
kathi = Student.create(prename="Katharina", surname="Walz", sex="Female", class_id=class3.id)
victoria = Student.create(prename="Victoria", surname="Möller", sex="Female", class_id=class3.id)
lec1 = Lecture.create(title="Tutorial 1", points=30, class_id=class1.id)
lec2 = Lecture.create(title="Tutorial 1", points=30, class_id=class3.id)
lec3 = Lecture.create(title="Tutorial 2", points=20, class_id=class1.id)
lec4 = Lecture.create(title="Tutorial 2", points=20, class_id=class2.id)
lec5 = Lecture.create(title="Extended Applications", points=44, class_id=class1.id)
sub1_phil = Submission.create(student_id=phil.id, lecture_id=lec1.id, points=random.randint(0, lec1.points))
sub2_phil = Submission.create(student_id=phil.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub3_phil = Submission.create(student_id=phil.id, lecture_id=lec5.id, points=random.randint(0, lec5.points))
sub1_nova = Submission.create(student_id=nova.id, lecture_id=lec1.id, points=random.randint(0, lec1.points))
sub2_nova = Submission.create(student_id=nova.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub1_kathi = Submission.create(student_id=kathi.id, lecture_id=lec3.id, points=random.randint(0, lec3.points))
sub1_vici = Submission.create(student_id=victoria.id, lecture_id=lec2.id, points=random.randint(0, lec2.points))
return
fp = Path().cwd()/"Test.json"
dump_to_json(fp)
db.close()
db.init("Test.db")
db.connect()
db.create_tables([Class, Student, Lecture, Submission])
load_from_json(fp)
if __name__ == "__main__":
# main()
dump_to_json(Path().cwd()/"TEST.json")

37
student_ranking.py Normal file
View File

@ -0,0 +1,37 @@
import imgui
import numpy as np
from model import *
class StudentRanking:
def __init__(self):
super().__init__()
def __call__(self):
students = Student.select().where(Student.class_id == 1)
lectures = Lecture.select().where(Lecture.class_id == 1)
overall_points = sum([l.points for l in lectures])
ranking = list()
avg = list()
for s in students:
rank = sum([sub.points for sub in Submission.select().where(Submission.student_id == s.id)])/overall_points
ranking.append((f"{s.prename} {s.surname}", rank))
avg.append(rank)
ranking = sorted(ranking, key=lambda x: x[1], reverse=True)
avg = sum(avg)/len(avg)
flag = True
with imgui.begin("Student Ranking", False, imgui.WINDOW_NO_MOVE | imgui.WINDOW_NO_RESIZE | imgui.WINDOW_NO_COLLAPSE):
for n, rank in enumerate(ranking, start=1):
if rank[1] < avg and flag:
imgui.separator()
flag = False
imgui.text(f"{n}. {rank[0]} {rank[1]:.1%}")
imgui.separator()
imgui.text(f"Average: {avg:.1%}")

BIN
test.db

Binary file not shown.

View File

@ -12,6 +12,7 @@ from lecture_editor import LectureEditor
from submission_editor import SubmissionEditor from submission_editor import SubmissionEditor
from student_graph import StudentGraph from student_graph import StudentGraph
from student_ranking import StudentRanking
def set_layout(size: tuple, pos: tuple) -> None: def set_layout(size: tuple, pos: tuple) -> None:
io = imgui.get_io() io = imgui.get_io()
@ -29,11 +30,15 @@ class GrapherLayout:
super().__init__() super().__init__()
self.student_graph = StudentGraph() self.student_graph = StudentGraph()
self.student_ranking = StudentRanking()
def __call__(self): def __call__(self):
set_layout((1, 0.4), (0, 0.02)) set_layout((1, 0.4), (0, 0.02))
self.student_graph() self.student_graph()
set_layout((0.3, 0.6), (0, 0.42))
self.student_ranking()
class EditorLayout: class EditorLayout:
def __init__(self): def __init__(self):
super().__init__() super().__init__()