From a2d365625e2286de2fe6e2ad3fb5d0aadee45fa4 Mon Sep 17 00:00:00 2001 From: Braeden Sowinski Date: Thu, 12 May 2022 18:28:42 -0700 Subject: [PATCH] detail errors output --- test/scheduleGenerator/generator_v3.py | 23 ++++++---- test/tinker.py | 60 ++++++++++++++++++++------ 2 files changed, 62 insertions(+), 21 deletions(-) diff --git a/test/scheduleGenerator/generator_v3.py b/test/scheduleGenerator/generator_v3.py index 52e46c4..464bbd9 100644 --- a/test/scheduleGenerator/generator_v3.py +++ b/test/scheduleGenerator/generator_v3.py @@ -346,9 +346,8 @@ def generateScheduleV3( students[student["index"]]["classes"] += 1 - # Step 6 | Part A - Evaluate, move students to fix conflicts - conflictLogs = [] # Counts as an error that is an issue - acceptableConflictLogs = [] # Is minor error that is not an issue + # Step 6 - Evaluate, move students to fix conflicts + conflictLogs = [] for student in students: initialBlocks = [student["schedule"][block] for block in student["schedule"]] @@ -421,7 +420,9 @@ def generateScheduleV3( conflictLogs.append({ "Pupil #": student["Pupil #"], "Email": "", - "Conflict": "Critical: Couldn't solve schedule" + "Type": "Critical", + "Code": "C-CSS", + "Conflict": "Couldn't solve schedule" }) hasConflicts = False # classOut = blocks[clashIndex][classIndex] @@ -449,10 +450,12 @@ def generateScheduleV3( while not metSelfRequirements: if (student["expectedClasses"] - 2) <= student["classes"] < student["expectedClasses"]: - acceptableConflictLogs.append({ + conflictLogs.append({ "Pupil #": student["Pupil #"], "Email": "", - "Conflict": "Acceptable: Missing 1-2 classes" + "Type": "Acceptable", + "Code": "A-MC", + "Conflict": "Missing 1-2 classes" }) metSelfRequirements = True @@ -462,7 +465,9 @@ def generateScheduleV3( conflictLogs.append({ "Pupil #": student["Pupil #"], "Email": "", - "Conflict": "Critical: Missing too many classes" + "Type": "Critical", + "Code": "C-MC", + "Conflict": "Missing too many classes" }) metSelfRequirements = True @@ -471,8 +476,8 @@ def generateScheduleV3( continue finalConflictLogs = { - "Critical": conflictLogs, - "Acceptable": acceptableConflictLogs + "Critical": [conflict for conflict in conflictLogs if conflict["Type"] == "Critical"], + "Acceptable": [conflict for conflict in conflictLogs if conflict["Type"] == "Acceptable"] } # Update Student records diff --git a/test/tinker.py b/test/tinker.py index 76fc280..fd0665f 100644 --- a/test/tinker.py +++ b/test/tinker.py @@ -1,5 +1,6 @@ #!/usr/bin/python3 from prettytable import PrettyTable +from typing import Tuple import json import sys @@ -13,6 +14,24 @@ from scheduleGenerator.generator_v1 import generateScheduleV1 from scheduleGenerator.generator_v2 import generateScheduleV2 from scheduleGenerator.generator_v3 import generateScheduleV3 +def errorOutput(students) -> Tuple[PrettyTable, dict, dict]: + # Error Table calulation / output + f = open('./output/conflicts.json') + conflicts = json.load(f) + f.close() + + t = PrettyTable(['Type', 'Error %', 'Success %', 'Error Ratio']) + + errorsC = round(len(conflicts["Critical"]) / len(students) * 100, 2) + successC = round(100 - errorsC, 2) + errorsA = round(len(conflicts["Acceptable"]) / len(students) * 100, 2) + successA = round(100 - errorsA, 2) + + t.add_row(['Critical', f"{errorsC} %", f"{successC} %", f"{len(conflicts['Critical'])}/{len(students)}"]) + t.add_row(['Acceptable', f"{errorsA} %", f"{successA} %", f"{len(conflicts['Acceptable'])}/{len(students)}"]) + + return t, conflicts["Critical"], conflicts["Acceptable"] + if __name__ == '__main__': if len(sys.argv) == 1: @@ -46,19 +65,36 @@ if __name__ == '__main__': timetable["Version"] = 3 timetable["timetable"] = generateScheduleV3(sampleStudents, samplemockCourses, 40, "./output/students.json", "./output/conflicts.json") - # Error Table calulation / output - f = open('./output/conflicts.json') - conflicts = json.load(f) - f.close() + errors, _, _ = errorOutput(sampleStudents) + print(errors) - t = PrettyTable(['Type', 'Error %', 'Success %', 'Error Ratio']) - errors = round(len(conflicts["Critical"]) / len(sampleStudents) * 100, 2) - success = round(100 - errors, 2) - t.add_row(['Critical', f"{errors} %", f"{success} %", f"{len(conflicts['Critical'])}/{len(sampleStudents)}"]) - errors = round(len(conflicts["Acceptable"]) / len(sampleStudents) * 100, 2) - success = round(100 - errors, 2) - t.add_row(['Acceptable', f"{errors} %", f"{success} %", f"{len(conflicts['Acceptable'])}/{len(sampleStudents)}"]) - print(t) + elif sys.argv[1].upper() == "ERRORS": + sampleStudents = getSampleStudents("./sample_data/course_selection_data.csv", True) + errors, critical, acceptable = errorOutput(sampleStudents) + print() + print(errors) + + print(f"\n{len(critical)} critical errors") + c1, c2, co = 0, 0, 0 + for error in critical: + if error["Code"] == "C-MC": c1 +=1 + elif error["Code"] == "C-CSS": c2 += 1 + else: co += 1 + + print(f"x{c1} C-MC Errors: Critical - Missing Classes") + print(f"x{c2} C-CSS Errors: Critical - Couldn't Solve Schedule") + print(f"x{co} Other/Undefined Critical Errors") + + print(f"\n{len(acceptable)} acceptable errors") + a1, ao = 0, 0 + for error in acceptable: + if error["Code"] == "A-MC": a1 +=1 + else: ao += 1 + + print(f"x{a1} A-MC Errors: Acceptable - Missing 1-2 Classes") + print(f"x{ao} Other/Undefined Acceptable Errors") + + exit() else: print("Invalid argument")