Added: Student Ranking
This commit is contained in:
parent
0cc4ed243d
commit
70ea8899e2
2
.gitignore
vendored
2
.gitignore
vendored
@ -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
33
assets/Student_list.csv
Normal 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
|
|
BIN
assets/Student_list.xlsx
Normal file
BIN
assets/Student_list.xlsx
Normal file
Binary file not shown.
42
assets/convert.py
Normal file
42
assets/convert.py
Normal 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
BIN
assets/test.db
Normal file
Binary file not shown.
13
main_menu.py
13
main_menu.py
@ -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
135
model.py
@ -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
37
student_ranking.py
Normal 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%}")
|
||||||
|
|
5
view.py
5
view.py
@ -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__()
|
||||||
|
Loading…
Reference in New Issue
Block a user