add student dataclass

This commit is contained in:
SowinskiBraeden committed 2022-11-30 19:14:02 -08:00
1 parent be766eb962
commit 283c5e72ff
6 files changed
+124 -98

No files matched your search

+56 -55
View File
@@ -5,6 +5,7 @@ from string import hexdigits
from app.util.globals import flex, Error from app.util.globals import flex, Error
from app.util.estimateGrade import getGrade from app.util.estimateGrade import getGrade
from app.util.students import Student, studentsToDict
# 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
@@ -44,12 +45,12 @@ def insertConflictSolutions(
# 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/students.py to see the students list structure students: list[Student], # Refer to /util/students.py to see the students list structure
courses: dict, # Refer to /util/courses.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
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 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", studentsDir: str = "../output/raw/students.json",
conflictsDir: str = "../output/raw/conflicts.json", conflictsDir: str = "../output/raw/conflicts.json",
coursesDir: str = "../output/raw/courses.json" coursesDir: str = "../output/raw/courses.json"
@@ -77,8 +78,8 @@ def generateScheduleV3(
activeCourses = {} activeCourses = {}
for student in students: for student in students:
# Tally class request # Tally class request
for request in (request for request in student["requests"] if not request["alt"] and request["CrsNo"] not in flex): for request in (request for request in student.Requests if not request.Alt and request.CrsNo not in flex):
code = request["CrsNo"] code = request.CrsNo
courses[code]["Requests"] += 1 courses[code]["Requests"] += 1
# Add course to active list if enough requests # Add course to active list if enough requests
if courses[code]["Requests"] > minReq and courses[code]["CrsNo"] not in activeCourses: if courses[code]["Requests"] > minReq and courses[code]["CrsNo"] not in activeCourses:
@@ -183,9 +184,9 @@ def generateScheduleV3(
# bias to students at the top of the list # bias to students at the top of the list
student = tempStudents[random.randint(0, len(tempStudents)-1)] student = tempStudents[random.randint(0, len(tempStudents)-1)]
alternates = [request for request in student["requests"] if request["alt"]] alternates = [request for request in student.Requests if request.Alt]
for request in (request for request in student["requests"] if not request["alt"] and request["CrsNo"] not in flex): for request in (request for request in student.Requests if not request.Alt and request.CrsNo not in flex):
course = request["CrsNo"] course = request.CrsNo
getAvailableCourse = True getAvailableCourse = True
isAlt = False isAlt = False
while getAvailableCourse: while getAvailableCourse:
@@ -198,8 +199,8 @@ def generateScheduleV3(
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
selectedCourses[cname]["students"].append({ selectedCourses[cname]["students"].append({
"Pupil #": student["Pupil #"], "Pupil #": student.PupilNum,
"index": student["studentIndex"] "index": student.StudentIndex
}) })
getAvailableCourse = False getAvailableCourse = False
break break
@@ -208,7 +209,7 @@ def generateScheduleV3(
if cname[len(cname)-1] == f"{len(emptyClasses[course])-1}": if cname[len(cname)-1] == f"{len(emptyClasses[course])-1}":
if len(alternates) > 0: if len(alternates) > 0:
# Use alternate # Use alternate
course = alternates[0]["CrsNo"] course = alternates[0].CrsNo
alternates.remove(alternates[0]) alternates.remove(alternates[0])
isAlt = True isAlt = True
break break
@@ -220,8 +221,8 @@ def generateScheduleV3(
elif cname not in selectedCourses: elif cname not in selectedCourses:
selectedCourses[cname] = { selectedCourses[cname] = {
"students": [{ "students": [{
"Pupil #": student["Pupil #"], "Pupil #": student.PupilNum,
"index": student["studentIndex"] "index": student.StudentIndex
}], }],
"CrsNo": course, "CrsNo": course,
"Description": courses[course]["Description"] "Description": courses[course]["Description"]
@@ -232,7 +233,7 @@ def generateScheduleV3(
elif course not in emptyClasses: elif course not in emptyClasses:
if len(alternates) > 0: if len(alternates) > 0:
# Use alternate # Use alternate
course = alternates[0]["CrsNo"] course = alternates[0].CrsNo
alternates.remove(alternates[0]) alternates.remove(alternates[0])
isAlt = True isAlt = True
else: else:
@@ -240,7 +241,7 @@ def generateScheduleV3(
# handle options to solve for missing class # handle options to solve for missing class
getAvailableCourse = False getAvailableCourse = False
students[student["studentIndex"]]["remainingAlts"] = alternates students[student.StudentIndex].RemainingAlts = alternates
tempStudents.remove(student) tempStudents.remove(student)
@@ -323,8 +324,8 @@ def generateScheduleV3(
for block in running: for block in running:
for cname in running[block]: for cname in running[block]:
for student in running[block][cname]["students"]: for student in running[block][cname]["students"]:
students[student["index"]]["schedule"][block].append(cname) students[student["index"]].Schedule[block].append(cname)
students[student["index"]]["classes"] += 1 students[student["index"]].Classes += 1
# Step 6 - Evaluate, move students to fix conflicts # Step 6 - Evaluate, move students to fix conflicts
@@ -334,7 +335,7 @@ def generateScheduleV3(
studentsCritical, studentsAcceptable = 0, 0 studentsCritical, studentsAcceptable = 0, 0
for student in students: for student in students:
blocks = [student["schedule"][block] for block in student["schedule"]] blocks = [student.Schedule[block] for block in student.Schedule]
hasConflicts = True if sum(1 for b in blocks if len(b)>1) > 0 else False hasConflicts = True if sum(1 for b in blocks if len(b)>1) > 0 else False
# If there is no conflicts # If there is no conflicts
@@ -342,26 +343,26 @@ def generateScheduleV3(
# or classes the student is inserted to is missing # or classes the student is inserted to is missing
# no more than two classes: # no more than two classes:
# continue to next student # continue to next student
if not hasConflicts and student["classes"] == student["expectedClasses"]: continue if not hasConflicts and student.Classes == student.ExpectedClasses: continue
elif not hasConflicts and (student["expectedClasses"]-2) <= student["classes"] < student["expectedClasses"]: elif not hasConflicts and (student.ExpectedClasses-2) <= student.Classes < student.ExpectedClasses:
# TODO: Insert alternates if available? # TODO: Insert alternates if available?
a_mc_count += 1 a_mc_count += 1
acceptableCount += 1 acceptableCount += 1
if not newConflict(student["Pupil #"], "", "Acceptable", "A-MC", "Missing 1-2 Classses", conflictLogs): studentsAcceptable += 1 if not newConflict(student.PupilNum, "", "Acceptable", "A-MC", "Missing 1-2 Classses", conflictLogs): studentsAcceptable += 1
continue continue
studentData = { studentData = {
"Pupil #": student["Pupil #"], "Pupil #": student.PupilNum,
"index": student["studentIndex"] "index": student.StudentIndex
} }
if hasConflicts: if hasConflicts:
student["classes"] = 0 student.Classes = 0
missing = [] missing = []
# Clear student schedule to restructure # Clear student schedule to restructure
for block in student["schedule"]: for block in student.Schedule:
[running[block][cname]["students"].remove(studentData) for cname in student["schedule"][block]] [running[block][cname]["students"].remove(studentData) for cname in student.Schedule[block]]
student["schedule"][block] = [] student.Schedule[block] = []
# Find class in student schedule that's run the least # Find class in student schedule that's run the least
classes, runCounts = [], [] classes, runCounts = [], []
@@ -382,9 +383,9 @@ def generateScheduleV3(
for cname in running[block]: for cname in running[block]:
if cname[:-2] == classes[index] and len(running[block][cname]["students"]) < classCap: if cname[:-2] == classes[index] and len(running[block][cname]["students"]) < classCap:
running[block][cname]["students"].append(studentData) running[block][cname]["students"].append(studentData)
student["schedule"][block].append(cname) student.Schedule[block].append(cname)
availableBlocks.remove(block) availableBlocks.remove(block)
student["classes"] += 1 student.Classes += 1
found = True found = True
break break
@@ -402,21 +403,21 @@ def generateScheduleV3(
if len(existsIn) > 0: if len(existsIn) > 0:
for i, existing in enumerate(existsIn): for i, existing in enumerate(existsIn):
if solution: break if solution: break
classOut = student["schedule"][existing][0] classOut = student.Schedule[existing][0]
for block in running: for block in running:
if solution: break if solution: break
if block == existing or block not in availableBlocks: continue if block == existing or block not in availableBlocks: continue
for cname in running[block]: for cname in running[block]:
if cname[:-2] == classOut[:-2] and len(running[block][cname]["students"]) < classCap: if cname[:-2] == classOut[:-2] and len(running[block][cname]["students"]) < classCap:
student["classes"] += 1 student.Classes += 1
# Move to existing class elsewhere # Move to existing class elsewhere
student["schedule"][block].append(cname) student.Schedule[block].append(cname)
running[block][cname]["students"].append(studentData) running[block][cname]["students"].append(studentData)
# Overwrite old class # Overwrite old class
running[existing][student["schedule"][existing][0]]["students"].remove(studentData) running[existing][student.Schedule[existing][0]]["students"].remove(studentData)
student["schedule"][existing][0] = existingClassNames[i] student.Schedule[existing][0] = existingClassNames[i]
running[existing][existingClassNames[i]]["students"].append(studentData) running[existing][existingClassNames[i]]["students"].append(studentData)
solution = True solution = True
@@ -424,7 +425,7 @@ def generateScheduleV3(
if not solution: if not solution:
# Try alternate # Try alternate
alternates = [alt["CrsNo"] for alt in students[student["studentIndex"]]["remainingAlts"] if alt["CrsNo"] not in flex and alt["CrsNo"] in courseRunInfoCopy] alternates = [alt.CrsNo for alt in students[student.StudentIndex].RemainingAlts if alt.CrsNo not in flex and alt.CrsNo in courseRunInfoCopy]
if len(alternates) == 0: # If no alternates, create critical error if len(alternates) == 0: # If no alternates, create critical error
c_cr_count += 1 c_cr_count += 1
criticalCount += 1 criticalCount += 1
@@ -435,7 +436,7 @@ def generateScheduleV3(
}) })
if not newConflict( if not newConflict(
student["Pupil #"], student.PupilNum,
"", # Student Email "", # Student Email
"Critical", # Err type "Critical", # Err type
"C-CR", # Err code "C-CR", # Err code
@@ -453,9 +454,9 @@ def generateScheduleV3(
runCounts.append(altRunCounts[altIndex]) runCounts.append(altRunCounts[altIndex])
# Remove alternate from remaining alternates # Remove alternate from remaining alternates
for remaining in students[student["studentIndex"]]["remainingAlts"]: for remaining in students[student.StudentIndex].RemainingAlts:
if remaining["CrsNo"] == alternates[altIndex]: if remaining.CrsNo == alternates[altIndex]:
students[student["studentIndex"]]["remainingAlts"].remove(remaining) students[student.StudentIndex].RemainingAlts.remove(remaining)
# Remove class after inserted or failed to insert # Remove class after inserted or failed to insert
classes.remove(classes[index]) classes.remove(classes[index])
@@ -466,7 +467,7 @@ def generateScheduleV3(
if len(missing) > 0: if len(missing) > 0:
data = [] data = []
if student["gradelevel"] is None: if student.Gradelevel is None:
for obj in missing: for obj in missing:
data["missing"].append({ data["missing"].append({
"CrsNo": obj["CrsNo"], "CrsNo": obj["CrsNo"],
@@ -482,7 +483,7 @@ def generateScheduleV3(
courseInfo = running[obj['block']][cname] courseInfo = running[obj['block']][cname]
courseGrade = getGrade(courseInfo['CrsNo'], courseInfo['Description']) 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:
blockSolution["solutions"].append({ blockSolution["solutions"].append({
"CrsNo": cname, "CrsNo": cname,
@@ -491,23 +492,23 @@ def generateScheduleV3(
data.append(blockSolution) data.append(blockSolution)
insertConflictSolutions(student["Pupil #"], conflictLogs, data) insertConflictSolutions(student.PupilNum, conflictLogs, data)
metSelfRequirements = True if student["classes"] == student["expectedClasses"] else False metSelfRequirements = True if student.Classes == student.ExpectedClasses else False
if not metSelfRequirements: if not metSelfRequirements:
if (student["expectedClasses"] - 2) <= student["classes"] < student["expectedClasses"]: if (student.ExpectedClasses - 2) <= student.Classes < student.ExpectedClasses:
a_mc_count += 1 a_mc_count += 1
acceptableCount += 1 acceptableCount += 1
if not newConflict(student["Pupil #"], "", "Acceptable", "A-MC", "Missing 1-2 Classses", conflictLogs): studentsAcceptable += 1 if not newConflict(student.PupilNum, "", "Acceptable", "A-MC", "Missing 1-2 Classses", conflictLogs): studentsAcceptable += 1
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 # expected classes is too great
if student["Pupil #"] in conflictLogs: if student.PupilNum in conflictLogs:
c_mc_count += 1 c_mc_count += 1
criticalCount += 1 criticalCount += 1
if not newConflict(student["Pupil #"], "", "Critical", "C-MC", "Missing too many Classses", conflictLogs): studentsCritical += 1 if not newConflict(student.PupilNum, "", "Critical", "C-MC", "Missing too many Classses", conflictLogs): studentsCritical += 1
finalConflictLogs = { finalConflictLogs = {
"Conflicts": conflictLogs, "Conflicts": conflictLogs,
@@ -541,10 +542,10 @@ def generateScheduleV3(
# Insert flex (spare) course codes to empty blocks # Insert flex (spare) course codes to empty blocks
for student in students: for student in students:
for block in student["schedule"]: for block in student.Schedule:
if len(student["schedule"][block]) == 0: if len(student.Schedule[block]) == 0:
i = 0 if int(block[5:]) <= blockPerSem else 1 i = 0 if int(block[5:]) <= blockPerSem else 1
student["schedule"][block].append(flex[i]) student.Schedule[block].append(flex[i])
# Read timetable and collect data on courses # Read timetable and collect data on courses
for block in running: for block in running:
@@ -559,7 +560,7 @@ def generateScheduleV3(
# Update/log new student records # Update/log new student records
with open(studentsDir, "w") as outfile: with open(studentsDir, "w") as outfile:
json.dump(students, outfile, indent=2) json.dump(studentsToDict(students), outfile, indent=2)
# Update/log new course records # Update/log new course records
with open(coursesDir, "w") as outfile: with open(coursesDir, "w") as outfile:
+4 -4
View File
@@ -44,7 +44,7 @@ def putScheduleToWord(
# create an instance of a word doc. # create an instance of a word doc.
doc = docx.Document() doc = docx.Document()
doc.add_heading(f'Schedule for Student {student["Pupil #"]}') doc.add_heading(f'Schedule for Student {student.PupilNum}')
# Create a table object # Create a table object
table = doc.add_table(rows=1, cols=3) table = doc.add_table(rows=1, cols=3)
@@ -62,12 +62,12 @@ def putScheduleToWord(
table.columns[2].width = Inches(0.75) table.columns[2].width = Inches(0.75)
for block in student['schedule']: for block in student['schedule']:
courseCode = student["schedule"][block][0] courseCode = student.Schedule[block][0]
if courseCode in flex: courseName = 'Study' if courseCode in flex: courseName = 'Study'
else: courseName = courses[courseCode[:-2]]["Description"] else: courseName = courses[courseCode[:-2]]["Description"]
blockNum = int(block.split('block')[1]) blockNum = int(block.split('block')[1])
semester = 2 if blockNum > 5 else 1 semester = 2 if blockNum > 5 else 1
if blockNum > (len(student["schedule"])/2): blockNum -= (len(student["schedule"])/2) if blockNum > (len(student.Schedule)/2): blockNum -= (len(student.Schedule)/2)
row = table.add_row().cells row = table.add_row().cells
row[0].text = f'{courseName}\n({courseCode})' row[0].text = f'{courseName}\n({courseCode})'
row[1].text = str(blockNum) row[1].text = str(blockNum)
@@ -76,4 +76,4 @@ def putScheduleToWord(
for row in table.rows: for row in table.rows:
row.height = Inches(0.75) row.height = Inches(0.75)
doc.save(f'{output_dir}/{student["Pupil #"]}_schedule.docx') doc.save(f'{output_dir}/{student.PupilNum}_schedule.docx')
+7
View File
@@ -1,8 +1,15 @@
#!/usr/bin/env python3.11 #!/usr/bin/env python3.11
import json import json
import csv import csv
from dataclasses import dataclass
from app.util.estimateGrade import getGrade from app.util.estimateGrade import getGrade
@dataclass
class Request:
CrsNo: str
Description: str
Alt: bool
# Get all requested courses from data # Get all requested courses from data
def getCourses( def getCourses(
data_dir: str, data_dir: str,
+3 -3
View File
@@ -23,10 +23,10 @@ def extractGrade(string: str) -> int:
return grade if grade is not None and grade >= 8 else None return grade if grade is not None and grade >= 8 else None
# Estimage students grade based off requests # Estimage students grade based off requests
def estimateStudentGrade(pupil: dict) -> int: def estimateStudentGrade(pupil) -> 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):
extractedGrade = getGrade(request["CrsNo"], request["Description"]) extractedGrade = getGrade(request.CrsNo, request.Description)
if extractedGrade is not None: 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
+48 -30
View File
@@ -3,6 +3,26 @@ import json
import csv import csv
from app.util.estimateGrade import estimateStudentGrade from app.util.estimateGrade import estimateStudentGrade
from app.util.globals import flex from app.util.globals import flex
from app.util.courses import Request
from dataclasses import dataclass, asdict
@dataclass
class Student:
PupilNum: str
Requests: list[Request]
Schedule: dict[str: list]
ExpectedClasses: int
Classes: int
RemainingAlts: list[Request]
StudentIndex: int
Gradelevel: int = None # set to None since don't pass gradelevel
# This function converst Student.Requests to an array of dictionaries from an array of Requests
def RequestsToDict(self) -> None: self.Requests = [asdict(r) for r in self.Requests]
def studentsToDict(students: list[Student]) -> list[dict]:
[s.RequestsToDict for s in students]
return [asdict(s) for s in students]
# sort data into usable dictionary # sort data into usable dictionary
def getStudents( def getStudents(
@@ -12,56 +32,54 @@ def getStudents(
log_dir: str = './output/raw/students.json' log_dir: str = './output/raw/students.json'
) -> list[ dict[ str: any ] ]: ) -> list[ dict[ str: any ] ]:
students: list[ dict[ str: any ] ] = [] students: list[Student] = []
with open(data_dir, newline='') as csvfile: with open(data_dir, newline='') as csvfile:
reader = csv.DictReader(csvfile) reader = csv.DictReader(csvfile)
for row in reader: for row in reader:
exists = False exists = False
for student in students: for student in students:
exists = True if student["Pupil #"] == row["Pupil #"] else False exists = True if student.PupilNum == row["Pupil #"] else False
if exists: break if exists: break
alternate = True if row["Alternate?"] == 'TRUE' else False alternate = True if str(row["Alternate?"]).upper() == 'TRUE' else False
if exists: if exists:
if len(students[student["studentIndex"]]["requests"]) >= totalBlocks and not alternate and row["CrsNo"] not in flex: alternate = True if len(students[student.StudentIndex].Requests) >= totalBlocks and not alternate and row["CrsNo"] not in flex: alternate = True
students[student["studentIndex"]]["requests"].append({ students[student.StudentIndex].Requests.append(
"CrsNo": row["CrsNo"], Request(
"Description": row["Description"], row["CrsNo"],
"alt": alternate row["Description"],
}) alternate
if row["CrsNo"] not in flex and not alternate and students[student["studentIndex"]]["expectedClasses"] < 10: ))
students[student["studentIndex"]]["expectedClasses"] += 1 if row["CrsNo"] not in flex and not alternate and students[student.StudentIndex].ExpectedClasses < 10:
students[student.StudentIndex].ExpectedClasses += 1
else: else:
newStudent = { newStudent: Student = Student(
"Pupil #": row["Pupil #"], row["Pupil #"],
"requests": [{ [Request(
"CrsNo": row["CrsNo"], row["CrsNo"],
"Description": row["Description"], row["Description"],
"alt": alternate alternate
}], )],
"schedule": {}, {}, 1, 0, [],
"expectedClasses": 1, len(students)
"classes": 0, )
"remainingAlts": [], newStudent.Gradelevel = row.get("Grade") if row.get("Grade") is not None else row.get("grade")
"studentIndex": len(students) for i in range(1, totalBlocks+1): newStudent.Schedule[f'block{i}'] = []
}
newStudent["gradelevel"] = row.get("Grade") if row.get("Grade") is not None else row.get("grade")
for i in range(1, totalBlocks+1): newStudent["schedule"][f'block{i}'] = []
students.append(newStudent) students.append(newStudent)
# Estimate student grades # Estimate student grades
for student in students: for student in students:
if student["gradelevel"] is None: student["gradelevel"] = estimateStudentGrade(student) if student.Gradelevel is None: student.Gradelevel = estimateStudentGrade(student)
if log: if log:
with open(log_dir, "w") as outfile: with open(log_dir, "w") as outfile:
json.dump(students, outfile, indent=2) json.dump(studentsToDict(students), outfile, indent=2)
return students return students
# Writes all students data to csv file # Writes all students data to csv file
def writeStudentsToCSV( def writeStudentsToCSV(
students: dict, students: list[Student],
output_dir: str = './output/raw/csv/students.csv' output_dir: str = './output/raw/csv/students.csv'
) -> None: ) -> None:
with open(output_dir, 'w') as file: with open(output_dir, 'w') as file:
@@ -71,5 +89,5 @@ def writeStudentsToCSV(
writer.writerow(data) writer.writerow(data)
for student in students: for student in students:
studentData = (student["Pupil #"], student["classes"], student["gradelevel"]) studentData = (student.PupilNum, student.Classes, student.Gradelevel)
writer.writerow(studentData) writer.writerow(studentData)
+6 -6
View File
@@ -7,7 +7,7 @@ from app.util.convertRawData import putScheduleToWord, putMasterTimetable
from app.generator import generateScheduleV3 from app.generator import generateScheduleV3
from app.util.globals import Error from app.util.globals import Error
from app.util.courses import getCourses, writeCoursesToCSV from app.util.courses import getCourses, writeCoursesToCSV
from app.util.students import getStudents, writeStudentsToCSV from app.util.students import getStudents, writeStudentsToCSV, Student
from app.util.errorCalculator import writeErrorsToCSV from app.util.errorCalculator import writeErrorsToCSV
from app.util.validator import validateInputData from app.util.validator import validateInputData
@@ -58,7 +58,7 @@ def start(
eel.post_data('Collecting student information...') eel.post_data('Collecting student information...')
students = getStudents( students = getStudents(
raw_data_dir, raw_data_dir,
log = True, log = False,
totalBlocks = total_blocks, totalBlocks = total_blocks,
log_dir = './output/raw/json/students.json' log_dir = './output/raw/json/students.json'
) )
@@ -89,13 +89,13 @@ def start(
# Get updated students # Get updated students
eel.post_data('Gathering latest data...') eel.post_data('Gathering latest data...')
with open(f'{raw_json_dir}/students.json', 'r') as studentFile: students = json.load(studentFile) with open(f'{raw_json_dir}/students.json', 'r') as studentFile:
# Unpack dictionary to Student dataclass
students = [Student(**s) for s in json.load(studentFile)]
with open(f'{raw_json_dir}/courses.json', 'r') as cFile: courses = json.load(cFile)
# call post-algorithm functions to present sorted data # call post-algorithm functions to present sorted data
eel.post_data('Writing data to .csv files...') eel.post_data('Writing data to .csv files...')
# get updated raw data
with open(f'{raw_json_dir}/students.json', 'r') as sFile: students = json.load(sFile)
with open(f'{raw_json_dir}/courses.json', 'r') as cFile: courses = json.load(cFile)
writeStudentsToCSV(students, output_dir='./output/raw/csv/students.csv') writeStudentsToCSV(students, output_dir='./output/raw/csv/students.csv')
writeCoursesToCSV(courses, output_dir='./output/raw/csv/courses.csv') writeCoursesToCSV(courses, output_dir='./output/raw/csv/courses.csv')
writeErrorsToCSV(len(students), conflictsDir='./output/raw/json/conflicts.json', outputDir='./output/raw/csv/error_tracker.csv') writeErrorsToCSV(len(students), conflictsDir='./output/raw/json/conflicts.json', outputDir='./output/raw/csv/error_tracker.csv')