update extracting grade scripts
This commit is contained in:
4 files changed
+38
-14
No files matched your search
+5
-4
@@ -4,7 +4,7 @@ import random
|
|||||||
from string import hexdigits
|
from string import hexdigits
|
||||||
|
|
||||||
from app.util.globals import flex, Error
|
from app.util.globals import flex, Error
|
||||||
from app.util.estimateGrade import getGradeFromCourseCode
|
from app.util.estimateGrade import getGrade
|
||||||
|
|
||||||
# Takes in information to create or add a new conflict
|
# Takes in information to create or add a new conflict
|
||||||
# Returns if the particular student has a previous error
|
# Returns if the particular student has a previous error
|
||||||
@@ -34,8 +34,8 @@ def insertConflictSolutions(pupilNum: str, logs: dict, data: dict) -> None:
|
|||||||
# Then it starts to attempt to fit all classes into a timetable, making corretions along
|
# Then it starts to attempt to fit all classes into a timetable, making corretions along
|
||||||
# the way. Corrections being moving a students class
|
# the way. Corrections being moving a students class
|
||||||
def generateScheduleV3(
|
def generateScheduleV3(
|
||||||
students: list, # Refer to /util/mockStudents.py to see the students list structure
|
students: list, # Refer to /util/students.py to see the students list structure
|
||||||
courses: dict, # Reger to /util/generateCourses.py to see the courses dictionary structure
|
courses: dict, # Refer to /util/courses.py to see the courses dictionary structure
|
||||||
minReq: int = 18, # minimum requests for a class to run
|
minReq: int = 18, # minimum requests for a class to run
|
||||||
classCap: int = 30, # maximum students per class
|
classCap: int = 30, # maximum students per class
|
||||||
blockClassLimit: int = 40, # Block class limit is the number of classrooms available per block. Default 40 classes per block
|
blockClassLimit: int = 40, # Block class limit is the number of classrooms available per block. Default 40 classes per block
|
||||||
@@ -469,7 +469,8 @@ def generateScheduleV3(
|
|||||||
for obj in missing:
|
for obj in missing:
|
||||||
blockSolution = { "CrsNo": obj["CrsNo"], "block": obj['block'], "solutions": [] }
|
blockSolution = { "CrsNo": obj["CrsNo"], "block": obj['block'], "solutions": [] }
|
||||||
for cname in running[obj['block']]:
|
for cname in running[obj['block']]:
|
||||||
courseGrade = getGradeFromCourseCode(cname[:-2])
|
courseInfo = running[obj['block']][cname]
|
||||||
|
courseGrade = getGrade(courseInfo['CrsNo'], courseInfo['Description'])
|
||||||
if courseGrade is None: continue
|
if courseGrade is None: continue
|
||||||
if (student["gradelevel"] == courseGrade) or (student["gradelevel"] == 12 and courseGrade == 11):
|
if (student["gradelevel"] == courseGrade) or (student["gradelevel"] == 12 and courseGrade == 11):
|
||||||
if len(running[obj['block']][cname]["students"]) < classCap:
|
if len(running[obj['block']][cname]["students"]) < classCap:
|
||||||
|
|||||||
+3
-2
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3.11
|
#!/usr/bin/env python3.11
|
||||||
import json
|
import json
|
||||||
import csv
|
import csv
|
||||||
from app.util.estimateGrade import getGradeFromCourseCode
|
from app.util.estimateGrade import getGrade
|
||||||
|
|
||||||
# Get all requested courses from data
|
# Get all requested courses from data
|
||||||
def getCourses(
|
def getCourses(
|
||||||
@@ -20,13 +20,14 @@ def getCourses(
|
|||||||
exists = True if courses[course]["CrsNo"] == row["CrsNo"] else False
|
exists = True if courses[course]["CrsNo"] == row["CrsNo"] else False
|
||||||
if exists: break
|
if exists: break
|
||||||
if not exists:
|
if not exists:
|
||||||
|
grade = getGrade(row["CrsNo"], row["Description"])
|
||||||
courses[row["CrsNo"]] = {
|
courses[row["CrsNo"]] = {
|
||||||
"CrsNo": row["CrsNo"],
|
"CrsNo": row["CrsNo"],
|
||||||
"Requests": 0,
|
"Requests": 0,
|
||||||
"Description": row["Description"],
|
"Description": row["Description"],
|
||||||
"Sem1": 0,
|
"Sem1": 0,
|
||||||
"Sem2":0,
|
"Sem2":0,
|
||||||
"Grade": getGradeFromCourseCode(row["CrsNo"])
|
"Grade": grade
|
||||||
}
|
}
|
||||||
|
|
||||||
if log:
|
if log:
|
||||||
|
|||||||
@@ -3,14 +3,36 @@ from app.util.globals import flex
|
|||||||
|
|
||||||
most_frequent = lambda l : max(set(l), key = l.count)
|
most_frequent = lambda l : max(set(l), key = l.count)
|
||||||
|
|
||||||
def getGradeFromCourseCode(code: str) -> int:
|
# extract a grade from a course code or description
|
||||||
grades = [int(s) for s in code.split("-") if s.isdigit()]
|
def extractGrade(string: str) -> int:
|
||||||
return None if len(grades) == 0 else most_frequent(grades)
|
if string in flex: return 12
|
||||||
|
|
||||||
def getEstimatedGrade(pupil: dict) -> int:
|
grade = None
|
||||||
|
for i in range(len(string)):
|
||||||
|
# If this is a digit like 1 and the next character is a digit like 2 we know the grade is 12
|
||||||
|
# or if this digit is 0 and the next digit is 9 we know the grade is 9
|
||||||
|
if i != len(string) - 1 and string[i].isdigit() and string[i+1].isdigit():
|
||||||
|
grade = int(f'{string[i]}{string[i+1]}')
|
||||||
|
if grade >= 8: break
|
||||||
|
|
||||||
|
# if the above condition is not met, and we know this is a single number, we can just return this single number as the grade
|
||||||
|
elif string[i].isdigit():
|
||||||
|
grade = int(string[i])
|
||||||
|
if grade >= 8: break
|
||||||
|
|
||||||
|
return grade if grade is not None and grade >= 8 else None
|
||||||
|
|
||||||
|
# Estimage students grade based off requests
|
||||||
|
def estimateStudentGrade(pupil: dict) -> int:
|
||||||
grades = [] # List of all possible grades
|
grades = [] # List of all possible grades
|
||||||
for request in (r for r in pupil["requests"] if r not in flex):
|
for request in (r for r in pupil["requests"] if r not in flex):
|
||||||
for extractedGrade in [int(s) for s in request["CrsNo"].split("-") if s.isdigit()]:
|
extractedGrade = getGrade(request["CrsNo"], request["Description"])
|
||||||
grades.append(extractedGrade)
|
if extractedGrade is not None: grades.append(extractedGrade)
|
||||||
|
|
||||||
return None if len(grades) == 0 else most_frequent(grades) # Final estimate of grade
|
return None if len(grades) == 0 else most_frequent(grades) # Final estimate of grade
|
||||||
|
|
||||||
|
# anlyse course code and description for best grade estimate
|
||||||
|
def getGrade(crsNo: str, crsDes: str) -> int:
|
||||||
|
grade = extractGrade(crsDes)
|
||||||
|
if grade is None: grade = extractGrade(crsNo)
|
||||||
|
return grade
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python3.11
|
#!/usr/bin/env python3.11
|
||||||
import json
|
import json
|
||||||
import csv
|
import csv
|
||||||
from app.util.estimateGrade import getEstimatedGrade
|
from app.util.estimateGrade import estimateStudentGrade
|
||||||
from app.util.globals import flex
|
from app.util.globals import flex
|
||||||
|
|
||||||
# sort data into usable dictionary
|
# sort data into usable dictionary
|
||||||
@@ -50,7 +50,7 @@ def getStudents(
|
|||||||
|
|
||||||
# Estimate student grades
|
# Estimate student grades
|
||||||
for student in students:
|
for student in students:
|
||||||
student["gradelevel"] = getEstimatedGrade(student)
|
student["gradelevel"] = estimateStudentGrade(student)
|
||||||
|
|
||||||
if log:
|
if log:
|
||||||
with open(log_dir, "w") as outfile:
|
with open(log_dir, "w") as outfile:
|
||||||
|
|||||||
Reference in new issue
Block a user