update extracting grade scripts

This commit is contained in:
SowinskiBraeden committed 2022-11-15 16:37:58 -08:00
1 parent c481cbc245
commit 5c75ee10a2
4 files changed
+51 -27

No files matched your search

+12 -11
View File
@@ -4,7 +4,7 @@ import random
from string import hexdigits
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
# Returns if the particular student has a previous error
@@ -34,15 +34,15 @@ def insertConflictSolutions(pupilNum: str, logs: dict, data: dict) -> None:
# Then it starts to attempt to fit all classes into a timetable, making corretions along
# the way. Corrections being moving a students class
def generateScheduleV3(
students: list, # Refer to /util/mockStudents.py to see the students list structure
courses: dict, # Reger to /util/generateCourses.py to see the courses dictionary structure
minReq: int=18, # minimum requests for a class to run
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
totalBlocks: int=10, # total blocks between two semesters -> default is 10 for 5 per semester... or this can be 8 for 4 blocks per semester
studentsDir: str="../output/raw/students.json",
conflictsDir: str="../output/raw/conflicts.json",
coursesDir: str="../output/raw/courses.json"
students: list, # Refer to /util/students.py to see the students list structure
courses: dict, # Refer to /util/courses.py to see the courses dictionary structure
minReq: int = 18, # minimum requests for a class to run
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
totalBlocks: int = 10, # total blocks between two semesters -> default is 10 for 5 per semester... or this can be 8 for 4 blocks per semester
studentsDir: str = "../output/raw/students.json",
conflictsDir: str = "../output/raw/conflicts.json",
coursesDir: str = "../output/raw/courses.json"
) -> tuple[dict, Error]: # Returns the completed 'running' dictionary from above
# Return error that totalBlocks is invalid
@@ -469,7 +469,8 @@ def generateScheduleV3(
for obj in missing:
blockSolution = { "CrsNo": obj["CrsNo"], "block": obj['block'], "solutions": [] }
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 (student["gradelevel"] == courseGrade) or (student["gradelevel"] == 12 and courseGrade == 11):
if len(running[obj['block']][cname]["students"]) < classCap:
+5 -4
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env python3.11
import json
import csv
from app.util.estimateGrade import getGradeFromCourseCode
from app.util.estimateGrade import getGrade
# Get all requested courses from data
def getCourses(
data_dir: str,
log: int=False,
log_dir: str='./output/raw/courses.json',
log: int = False,
log_dir: str = './output/raw/courses.json',
) -> dict[dict[str: any]]:
courses = {}
@@ -20,13 +20,14 @@ def getCourses(
exists = True if courses[course]["CrsNo"] == row["CrsNo"] else False
if exists: break
if not exists:
grade = getGrade(row["CrsNo"], row["Description"])
courses[row["CrsNo"]] = {
"CrsNo": row["CrsNo"],
"Requests": 0,
"Description": row["Description"],
"Sem1": 0,
"Sem2":0,
"Grade": getGradeFromCourseCode(row["CrsNo"])
"Grade": grade
}
if log:
+28 -6
View File
@@ -3,14 +3,36 @@ from app.util.globals import flex
most_frequent = lambda l : max(set(l), key = l.count)
def getGradeFromCourseCode(code: str) -> int:
grades = [int(s) for s in code.split("-") if s.isdigit()]
return None if len(grades) == 0 else most_frequent(grades)
# extract a grade from a course code or description
def extractGrade(string: str) -> int:
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
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()]:
grades.append(extractedGrade)
extractedGrade = getGrade(request["CrsNo"], request["Description"])
if extractedGrade is not None: grades.append(extractedGrade)
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
+6 -6
View File
@@ -1,15 +1,15 @@
#!/usr/bin/env python3.11
import json
import csv
from app.util.estimateGrade import getEstimatedGrade
from app.util.estimateGrade import estimateStudentGrade
from app.util.globals import flex
# sort data into usable dictionary
def getStudents(
data_dir: str,
log: bool=False,
totalBlocks: int=10,
log_dir: str='./output/raw/students.json'
data_dir: str,
log: bool = False,
totalBlocks: int = 10,
log_dir: str = './output/raw/students.json'
) -> list[ dict[ str: any ] ]:
students: list[ dict[ str: any ] ] = []
@@ -50,7 +50,7 @@ def getStudents(
# Estimate student grades
for student in students:
student["gradelevel"] = getEstimatedGrade(student)
student["gradelevel"] = estimateStudentGrade(student)
if log:
with open(log_dir, "w") as outfile: