feat: grades by professor (#225)
* feat: grades by professor * chore(pr-review): extract into Distributions type --------- Co-authored-by: doprz <52579214+doprz@users.noreply.github.com>
This commit is contained in:
@@ -3,27 +3,26 @@ 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
|
||||
* @returns a Distribution object containing the distribution of grades for the course, and
|
||||
* an array of semesters that we have the distribution for
|
||||
*/
|
||||
export async function queryAggregateDistribution(course: Course): Promise<[Distribution, Semester[]]> {
|
||||
export async function queryAggregateDistribution(course: Course): Promise<[Distribution, Semester[], boolean]> {
|
||||
const db = await initializeDB();
|
||||
const query = generateQuery(course, null);
|
||||
const query = generateQuery(course, null, true);
|
||||
|
||||
const res = db.exec(query)?.[0];
|
||||
let res = db.exec(query)?.[0];
|
||||
let instructorIncluded = true;
|
||||
if (!res?.columns?.length) {
|
||||
throw new NoDataError(course);
|
||||
instructorIncluded = false;
|
||||
const queryWithoutInstructor = generateQuery(course, null, false);
|
||||
res = db.exec(queryWithoutInstructor)?.[0];
|
||||
|
||||
if (!res?.columns?.length) {
|
||||
throw new NoDataError(course);
|
||||
}
|
||||
}
|
||||
|
||||
const row: Required<CourseSQLRow> = {} as Required<CourseSQLRow>;
|
||||
@@ -79,7 +78,7 @@ export async function queryAggregateDistribution(course: Course): Promise<[Distr
|
||||
semesters.push({ year: parseInt(year, 10), season: season as Semester['season'] });
|
||||
});
|
||||
|
||||
return [distribution, semesters];
|
||||
return [distribution, semesters, instructorIncluded];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,18 +87,19 @@ export async function queryAggregateDistribution(course: Course): Promise<[Distr
|
||||
* @param semester the semester to fetch the distribution for OR null if we want the aggregate distribution
|
||||
* @returns a SQL query string
|
||||
*/
|
||||
function generateQuery(course: Course, semester: Semester | null): string {
|
||||
// const profName = course.instructors[0]?.fullName;
|
||||
// eslint-disable-next-line no-nested-ternary
|
||||
const yearDelta = semester ? (semester.season === 'Fall' ? 0 : -1) : 0;
|
||||
function generateQuery(course: Course, semester: Semester | null, includeInstructor: boolean): string {
|
||||
const profName = course.instructors[0]?.lastName;
|
||||
|
||||
const query = `
|
||||
select * from ${semester ? `grade_distributions_${semester.year + yearDelta}_${semester.year + yearDelta + 1}` : `(select * from ${allTables.join(' union all select * from ')})`}
|
||||
select * from grade_distributions
|
||||
where Department_Code = '${course.department}'
|
||||
and Course_Number = '${course.number}'
|
||||
${includeInstructor ? `and Instructor_Last = '${profName}' collate nocase` : ''}
|
||||
${semester ? `and Semester = '${semester.season} ${semester.year}'` : ''}
|
||||
`;
|
||||
|
||||
console.log(includeInstructor, { query });
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
@@ -109,13 +109,19 @@ function generateQuery(course: Course, semester: Semester | null): string {
|
||||
* @param semester the semester to fetch the distribution for
|
||||
* @returns a Distribution object containing the distribution of grades for the course
|
||||
*/
|
||||
export async function querySemesterDistribution(course: Course, semester: Semester): Promise<Distribution> {
|
||||
export async function querySemesterDistribution(course: Course, semester: Semester): Promise<[Distribution, boolean]> {
|
||||
const db = await initializeDB();
|
||||
const query = generateQuery(course, semester);
|
||||
const query = generateQuery(course, semester, true);
|
||||
|
||||
const res = db.exec(query)?.[0];
|
||||
let res = db.exec(query)?.[0];
|
||||
let instructorIncluded = true;
|
||||
if (!res?.columns?.length) {
|
||||
throw new NoDataError(course);
|
||||
instructorIncluded = false;
|
||||
const queryWithoutInstructor = generateQuery(course, semester, false);
|
||||
res = db.exec(queryWithoutInstructor)?.[0];
|
||||
if (!res?.columns?.length) {
|
||||
throw new NoDataError(course);
|
||||
}
|
||||
}
|
||||
|
||||
const row: Required<CourseSQLRow> = {} as Required<CourseSQLRow>;
|
||||
@@ -142,21 +148,24 @@ export async function querySemesterDistribution(course: Course, semester: Semest
|
||||
}
|
||||
}
|
||||
|
||||
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 [
|
||||
{
|
||||
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,
|
||||
},
|
||||
instructorIncluded,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user