work on step 6/clean error output

This commit is contained in:
SowinskiBraeden committed 2022-05-12 17:15:40 -07:00
1 parent 327f4f7d8d
commit 1c1f0ee6f0
2 files changed
+59 -32

No files matched your search

+46 -22
View File
@@ -194,7 +194,7 @@ def generateScheduleV3(
# if course exists, get first available class # if course exists, get first available class
for cname in emptyClasses[course]: for cname in emptyClasses[course]:
if cname in selectedCourses: if cname in selectedCourses:
if isAlt and emptyClasses[course][cname]["expectedLen"] > classCap: if isAlt and emptyClasses[course][cname]["expectedLen"] < classCap:
emptyClasses[course][cname]["expectedLen"] += 1 emptyClasses[course][cname]["expectedLen"] += 1
if len(selectedCourses[cname]["students"]) < emptyClasses[course][cname]["expectedLen"]: if len(selectedCourses[cname]["students"]) < emptyClasses[course][cname]["expectedLen"]:
# Class exists with room for student # Class exists with room for student
@@ -258,7 +258,7 @@ def generateScheduleV3(
else: return 6 else: return 6
# Return Error if code is altered to cause error # Return Error if code is altered to cause error
else: raise SystemExit("Invalid 'stepType' in func 'stepIndex' line 225") else: raise SystemExit(f"Invalid 'stepType' in func 'stepIndex' line {getLineNumber()}")
while len(allClassRunCounts) > 0: while len(allClassRunCounts) > 0:
# Get highest resource class (most times run) # Get highest resource class (most times run)
@@ -351,10 +351,9 @@ def generateScheduleV3(
acceptableConflictLogs = [] # Is minor error that is not an issue acceptableConflictLogs = [] # Is minor error that is not an issue
for student in students: for student in students:
conflicts = sum(1 for b in block if len(b)>1) initialBlocks = [student["schedule"][block] for block in student["schedule"]]
conflicts = sum(1 for b in initialBlocks if len(b)>1)
hasConflicts = True if conflicts > 0 else False hasConflicts = True if conflicts > 0 else False
# If there is no conflicts # If there is no conflicts
# and classes inserted to is equal to expectedClasses # and classes inserted to is equal to expectedClasses
# or classes the student is inserted do is missing # or classes the student is inserted do is missing
@@ -362,29 +361,26 @@ def generateScheduleV3(
# continue to next student # continue to next student
if ( if (
not hasConflicts and ( not hasConflicts and (
student["classes"] == student["expectedClasses"] or ( student["classes"] == student["expectedClasses"] or
student["classes"] < student["expectedClasses"] and (student["expectedClasses"]-2) <= student["classes"] < student["expectedClasses"]
student["classes"] >= (student["expectedClasses"]-2)
)
) )
): continue ): continue
while hasConflicts: while hasConflicts:
# Check if conflicts have been resolved # Check if conflicts have been resolved
conflicts = sum(1 for b in block if len(b)>1) blocks = [student["schedule"][block] for block in student["schedule"]]
conflicts = sum(1 for b in blocks if len(b)>1)
if conflicts == 0: hasConflicts = False if conflicts == 0: hasConflicts = False
elif conflicts > 0: elif conflicts > 0:
blocks = [student["scheudle"][block] for block in student["schedule"]]
blockLens = [len(block) for block in blocks] blockLens = [len(block) for block in blocks]
freeBlocks = [index for index in range(len(blocks)) if len(blocks[index]) == 0] freeBlocks = [index for index in range(len(blocks)) if len(blocks[index]) == 0]
clashIndex = blockLens.index(max(blockLens)) clashIndex = blockLens.index(max(blockLens))
blockOut = f"block{clashIndex+1}" blockOut = f"block{clashIndex+1}"
classIndex = 0 classIndex = 0
done = False done, advancedConflict = False, False
advancedConflict = False
while not done: while not done:
classOut = blocks[clashIndex][classIndex] classOut = blocks[clashIndex][classIndex]
@@ -393,18 +389,17 @@ def generateScheduleV3(
if found: break if found: break
if index != clashIndex: if index != clashIndex:
blockIn = list(running)[index] blockIn = list(running)[index]
for cname in running[block]: for cname in running[blockIn]:
if cname[:-2] == classOut[:-2] and len(running[blockIn][cname]["students"]) < classCap: if cname[:-2] == classOut[:-2] and len(running[blockIn][cname]["students"]) < classCap:
studentData = { studentData = {
"Pupil #": student["Pupil #"], "Pupil #": student["Pupil #"],
"index": student["studentIndex"] "index": student["studentIndex"]
} }
# Update current blocks # Update records
blocks[clashIndex].remove(classOut) student["schedule"][blockOut].remove(classOut)
blocks[index].append(cname) student["schedule"][blockIn].append(cname)
# Update final records
running[blockOut][classOut]["students"].remove(studentData) running[blockOut][classOut]["students"].remove(studentData)
running[blockIn][cname]["students"].append(studentData) running[blockIn][cname]["students"].append(studentData)
@@ -414,13 +409,37 @@ def generateScheduleV3(
if not found: if not found:
if classIndex < len(blocks[clashIndex])-1: classIndex += 1 if classIndex < len(blocks[clashIndex])-1: classIndex += 1
elif classIndex == len(blocks[clashIndex])-1: elif classIndex == len(blocks[clashIndex])-1:
classIndex = 0
advancedConflict = True advancedConflict = True
done = True done = True
else:
print(f"Fatal error ({getLineNumber()}): Impossible error")
continue
elif found: done = True elif found: done = True
if advancedConflict: if advancedConflict:
pass conflictLogs.append({
"Pupil #": student["Pupil #"],
"Email": "",
"Conflict": "Critical: Couldn't solve schedule"
})
hasConflicts = False
# classOut = blocks[clashIndex][classIndex]
# existsIn = []
# for blockIndex in range(len(running)):
# for cname in running[list(running)[blockIndex]]:
# if cname[:-2] == classOut[:-2]: existsIn.append(blockIndex)
# for blockIndex in existsIn:
# if blockIndex in freeBlocks:
# # If this was in a free block it should've been added
# # But just in case I'll do it again here
# pass
# elif len(blocks[blockIndex]) == 1:
# pass
# elif len(blocks[blockIndex]) > 1:
# print("How to solve")
else: else:
print(f"Fatal error ({getLineNumber()}): Impossible error") print(f"Fatal error ({getLineNumber()}): Impossible error")
@@ -440,14 +459,19 @@ def generateScheduleV3(
elif student["classes"] < (student["expectedClasses"] - 2): elif student["classes"] < (student["expectedClasses"] - 2):
# Difference between classes inserted to and # Difference between classes inserted to and
# expected classes is too great, attempt to fix # expected classes is too great, attempt to fix
pass conflictLogs.append({
"Pupil #": student["Pupil #"],
"Email": "",
"Conflict": "Critical: Missing too many classes"
})
metSelfRequirements = True
else: else:
print(f"Fatal error ({getLineNumber()}): Impossible error") print(f"Fatal error ({getLineNumber()}): Impossible error")
continue continue
finalConflictLogs = { finalConflictLogs = {
"Fatal": conflictLogs, "Critical": conflictLogs,
"Acceptable": acceptableConflictLogs "Acceptable": acceptableConflictLogs
} }
+13 -10
View File
@@ -1,4 +1,5 @@
#!/usr/bin/python3 #!/usr/bin/python3
from prettytable import PrettyTable
import json import json
import sys import sys
@@ -37,7 +38,7 @@ if __name__ == '__main__':
elif sys.argv[1].upper() == 'V3': elif sys.argv[1].upper() == 'V3':
print("Processing...") print("Processing...\n")
sampleStudents = getSampleStudents("./sample_data/course_selection_data.csv", True) sampleStudents = getSampleStudents("./sample_data/course_selection_data.csv", True)
samplemockCourses = getSampleCourses("./sample_data/course_selection_data.csv", True) samplemockCourses = getSampleCourses("./sample_data/course_selection_data.csv", True)
@@ -45,18 +46,20 @@ if __name__ == '__main__':
timetable["Version"] = 3 timetable["Version"] = 3
timetable["timetable"] = generateScheduleV3(sampleStudents, samplemockCourses, 40, "./output/students.json", "./output/conflicts.json") timetable["timetable"] = generateScheduleV3(sampleStudents, samplemockCourses, 40, "./output/students.json", "./output/conflicts.json")
# Error Table calulation / output
f = open('./output/conflicts.json') f = open('./output/conflicts.json')
conflicts = json.load(f) conflicts = json.load(f)
print(f"{len(conflicts['Fatal'])}/{len(sampleStudents)} have errors")
errors = round(len(conflicts["Fatal"]) / len(sampleStudents) * 100, 2)
success = round(100 - errors, 2)
print(f"{errors}% errors")
print(f"{success}% success")
f.close() f.close()
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)
else: else:
print("Invalid argument") print("Invalid argument")
exit() exit()
@@ -64,4 +67,4 @@ if __name__ == '__main__':
with open("./output/timetable.json", "w") as outfile: with open("./output/timetable.json", "w") as outfile:
json.dump(timetable, outfile, indent=2) json.dump(timetable, outfile, indent=2)
print("Done") print("\nDone")