Added: Student Ranking
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
# ---> ImGUI
 | 
			
		||||
imgui.ini
 | 
			
		||||
*.ini
 | 
			
		||||
 | 
			
		||||
# ---> Python
 | 
			
		||||
# 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):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
 | 
			
		||||
        self.new = False
 | 
			
		||||
        self.new_text = str()
 | 
			
		||||
 | 
			
		||||
    def __call__(self):
 | 
			
		||||
        if self.new:
 | 
			
		||||
            self.create_new_file()
 | 
			
		||||
 | 
			
		||||
        with imgui.begin_main_menu_bar() as main_menu_bar:
 | 
			
		||||
            if main_menu_bar:
 | 
			
		||||
                with imgui.begin_menu("File", True) as file_menu:
 | 
			
		||||
                    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("Save", " ", 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)
 | 
			
		||||
                                    if clicked:
 | 
			
		||||
                                        return l
 | 
			
		||||
 | 
			
		||||
    def create_new_file(self):
 | 
			
		||||
        pass
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										135
									
								
								model.py
									
									
									
									
									
								
							
							
						
						
									
										135
									
								
								model.py
									
									
									
									
									
								
							@@ -1,7 +1,11 @@
 | 
			
		||||
from peewee import *
 | 
			
		||||
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 Meta:
 | 
			
		||||
@@ -30,39 +34,59 @@ class Submission(BaseModel):
 | 
			
		||||
    points = FloatField()
 | 
			
		||||
    created_at = DateTimeField(default=datetime.now)
 | 
			
		||||
 | 
			
		||||
db.connect()
 | 
			
		||||
db.create_tables([Class, Student, Lecture, Submission])
 | 
			
		||||
 | 
			
		||||
if __name__ == "__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))'''
 | 
			
		||||
def load_from_json(fp: Path) -> None:
 | 
			
		||||
    '''
 | 
			
		||||
    Rebuilding Database from a given json
 | 
			
		||||
    '''
 | 
			
		||||
    with open(fp, "r") as file:
 | 
			
		||||
        data = json.load(file)
 | 
			
		||||
    
 | 
			
		||||
    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()
 | 
			
		||||
    d = {c.name: {
 | 
			
		||||
            "DB ID": c.id,
 | 
			
		||||
            "DB ID": int(c.id),
 | 
			
		||||
            "Date": c.created_at.isoformat(),
 | 
			
		||||
            "Students": [
 | 
			
		||||
                    {
 | 
			
		||||
@@ -96,5 +120,50 @@ if __name__ == "__main__":
 | 
			
		||||
        for c in classes
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    import json
 | 
			
		||||
    print(json.dumps(d))
 | 
			
		||||
    with open(fp, "w") as file:
 | 
			
		||||
        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 student_graph import StudentGraph
 | 
			
		||||
from student_ranking import StudentRanking
 | 
			
		||||
 | 
			
		||||
def set_layout(size: tuple, pos: tuple) -> None:
 | 
			
		||||
    io = imgui.get_io()
 | 
			
		||||
@@ -29,11 +30,15 @@ class GrapherLayout:
 | 
			
		||||
        super().__init__()
 | 
			
		||||
 | 
			
		||||
        self.student_graph = StudentGraph()
 | 
			
		||||
        self.student_ranking = StudentRanking()
 | 
			
		||||
 | 
			
		||||
    def __call__(self):
 | 
			
		||||
        set_layout((1, 0.4), (0, 0.02))
 | 
			
		||||
        self.student_graph()
 | 
			
		||||
 | 
			
		||||
        set_layout((0.3, 0.6), (0, 0.42))
 | 
			
		||||
        self.student_ranking()
 | 
			
		||||
 | 
			
		||||
class EditorLayout:
 | 
			
		||||
    def __init__(self):
 | 
			
		||||
        super().__init__()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user