feat: add new db powered by UT_Grade_Parser (#163)

* feat: add new db powered by UT_Grade_Parser

* Merge branch 'main' of https://github.com/Longhorn-Developers/UT-Registration-Plus into feature/update-db

* feat: update db

* feat: update db handlers and types

Co-authored-by: Samuel Gunter <sgunter@utexas.edu>

* fix: type errors

* fix: add Other to grade dist

* fix: db with proper insertion order

* Merge branch 'main' of https://github.com/Longhorn-Developers/UT-Registration-Plus into feature/update-db

* chore: address PR comments

Co-Authored-By: Samuel Gunter <sgunter@utexas.edu>
This commit is contained in:
doprz
2024-03-24 00:21:18 -05:00
committed by GitHub
parent ee2b7c40b9
commit 60d1f48bd9
8 changed files with 152 additions and 113 deletions

View File

@@ -3,6 +3,14 @@ import type { CourseSQLRow, Distribution } from '@shared/types/Distribution';
import { initializeDB } from './initializeDB';
// TODO: in the future let's maybe refactor this to be reactive to the items in the db rather than being explicit
const allTables = [
'grade_distributions_2019_2020',
'grade_distributions_2020_2021',
'grade_distributions_2021_2022',
'grade_distributions_2022_2023',
] as const;
/**
* fetches the aggregate distribution of grades for a given course from the course db, and the semesters that we have data for
* @param course the course to fetch the distribution for
@@ -18,31 +26,48 @@ export async function queryAggregateDistribution(course: Course): Promise<[Distr
throw new NoDataError(course);
}
let row: Required<CourseSQLRow> = {} as Required<CourseSQLRow>;
res.columns.forEach((col, i) => {
row[col as keyof CourseSQLRow] = res.values[0]![i]! as never;
});
const row: Required<CourseSQLRow> = {} as Required<CourseSQLRow>;
for (let i = 0; i < res.columns.length; i++) {
const col = res.columns[i] as keyof CourseSQLRow;
switch (col) {
case 'A':
case 'A_Minus':
case 'B_Plus':
case 'B':
case 'B_Minus':
case 'C_Plus':
case 'C':
case 'C_Minus':
case 'D_Plus':
case 'D':
case 'D_Minus':
case 'F':
case 'Other':
row[col] = res.values.reduce((acc, cur) => acc + (cur[i] as number), 0) as never;
break;
default:
row[col] = res.columns[i]![0]! as never;
}
}
const distribution: Distribution = {
A: row.a2,
'A-': row.a3,
'B+': row.b1,
B: row.b2,
'B-': row.b3,
'C+': row.c1,
C: row.c2,
'C-': row.c3,
'D+': row.d1,
D: row.d2,
'D-': row.d3,
F: row.f,
A: row.A,
'A-': row.A_Minus,
'B+': row.B_Plus,
B: row.B,
'B-': row.B_Minus,
'C+': row.C_Plus,
C: row.C,
'C-': row.C_Minus,
'D+': row.D_Plus,
D: row.D,
'D-': row.D_Minus,
F: row.F,
Other: row.Other,
};
// the db file for some reason has duplicate semesters, so we use a set to remove duplicates
const rawSemesters = new Set<string>();
row.semesters.split(',').forEach((sem: string) => {
rawSemesters.add(sem);
});
// get unique semesters from the data
const rawSemesters = res.values.reduce((acc, cur) => acc.add(cur[0] as string), new Set<string>());
const semesters: Semester[] = [];
@@ -64,15 +89,15 @@ export async function queryAggregateDistribution(course: Course): Promise<[Distr
* @returns a SQL query string
*/
function generateQuery(course: Course, semester: Semester | null): string {
const profName = course.instructors[0]?.fullName;
// const profName = course.instructors[0]?.fullName;
// eslint-disable-next-line no-nested-ternary
const yearDelta = semester ? (semester.season === 'Fall' ? 0 : -1) : 0;
const query = `
select * from ${semester ? 'grades' : 'agg'}
where dept like '%${course.department}%'
${profName ? `and prof like '%${profName}%'` : ''}
and course_nbr like '%${course.number}%'
${semester ? `and sem like '%${semester.season} ${semester.year}%'` : ''}
order by a1+a2+a3+b1+b2+b3+c1+c2+c3+d1+d2+d3+f desc
select * from ${semester ? `grade_distributions_${semester.year + yearDelta}_${semester.year + yearDelta + 1}` : `(select * from ${allTables.join(' union all select * from ')})`}
where Department_Code = '${course.department}'
and Course_Number = '${course.number}'
${semester ? `and Semester = '${semester.season} ${semester.year}'` : ''}
`;
return query;
@@ -98,22 +123,21 @@ export async function querySemesterDistribution(course: Course, semester: Semest
row[col as keyof CourseSQLRow] = res.values[0]![i]! as never;
});
const distribution: Distribution = {
A: row.a2,
'A-': row.a3,
'B+': row.b1,
B: row.b2,
'B-': row.b3,
'C+': row.c1,
C: row.c2,
'C-': row.c3,
'D+': row.d1,
D: row.d2,
'D-': row.d3,
F: row.f,
return {
A: row.A,
'A-': row.A_Minus,
'B+': row.B_Plus,
B: row.B,
'B-': row.B_Minus,
'C+': row.C_Plus,
C: row.C,
'C-': row.C_Minus,
'D+': row.D_Plus,
D: row.D,
'D-': row.D_Minus,
F: row.F,
Other: row.Other,
};
return distribution;
}
/**