mirror of
https://github.com/UniversityOfHelsinkiCS/oodikone.git
synced 2026-10-12 19:03:39 +03:00
[CourseStats][Attempts] Count attempts properly finally
This commit is contained in:
@@ -94,7 +94,32 @@ export class CourseYearlyStatsCounter {
|
||||
}
|
||||
}
|
||||
|
||||
public markCreditToGroup(
|
||||
/** Add student's credit to attempts, attempt-stats include possibly duplicate students */
|
||||
public markAttemptToGroup(
|
||||
studentNumber: string,
|
||||
passed: boolean,
|
||||
grade: string,
|
||||
groupCode: number,
|
||||
groupName: string | Name,
|
||||
courseCode: string,
|
||||
yearCode: number
|
||||
) {
|
||||
this.initGroup(groupCode, groupName, courseCode, yearCode)
|
||||
|
||||
const { grades, categories } = this.groups[groupCode].attempts
|
||||
|
||||
grades[grade] ??= []
|
||||
grades[grade].push(studentNumber)
|
||||
|
||||
if (passed) {
|
||||
categories.passed.push(studentNumber)
|
||||
} else {
|
||||
categories.failed.push(studentNumber)
|
||||
}
|
||||
}
|
||||
|
||||
/** Add student's credit to student-stats, student-stats include only unique students */
|
||||
public markStudentGradeToGroup(
|
||||
studentNumber: string,
|
||||
passed: boolean,
|
||||
grade: string,
|
||||
@@ -106,24 +131,11 @@ export class CourseYearlyStatsCounter {
|
||||
) {
|
||||
this.initGroup(groupCode, groupName, courseCode, yearCode)
|
||||
|
||||
// mark credit to attempts
|
||||
const { grades, categories } = this.groups[groupCode].attempts
|
||||
|
||||
grades[grade] ??= []
|
||||
grades[grade].push(studentNumber)
|
||||
|
||||
if (passed) {
|
||||
categories.passed.push(studentNumber)
|
||||
} else {
|
||||
categories.failed.push(studentNumber)
|
||||
}
|
||||
|
||||
// mark best effort grade
|
||||
const current = this.groups[groupCode].students.grades[studentNumber]
|
||||
|
||||
// Don't add students to student stats based on improved grades
|
||||
if (creditTypeCode === CreditTypeCode.IMPROVED) return
|
||||
|
||||
const current = this.groups[groupCode].students.grades[studentNumber]
|
||||
|
||||
if (current?.passed && !passed) return
|
||||
if (current?.passed && Number(grade) <= Number(current?.grade)) return
|
||||
this.groups[groupCode].students.grades[studentNumber] = { grade, passed }
|
||||
|
||||
@@ -220,9 +220,18 @@ export const getYearlyStatsOfNew = async (
|
||||
|
||||
const counter = new CourseYearlyStatsCounter()
|
||||
|
||||
// A single-course credit group can contain more than one real attempt for the same course code
|
||||
// (e.g. failed once and passed on a retry). parseCredit collapses a group into a single
|
||||
// attainment for student-stats (no student is counted twice), but attempt-stats (include all attempts for a course)
|
||||
// need every attempt counted in its own year/semester.
|
||||
// Substitution groups are left untouched
|
||||
const splitIntoAttempts = (group: Credit[]): Credit[][] =>
|
||||
isSingleCourse(group) && group.length > 1 ? group.map(credit => [credit]) : [group]
|
||||
|
||||
for (const creditGroup of creditGroups) {
|
||||
if (!creditGroup?.length) continue
|
||||
// if (creditGroup.every(credit => CreditModel.improved(credit))) continue
|
||||
|
||||
const studyRightElements = studentNumberToSrElementsMap[creditGroup.at(0)?.student_studentnumber ?? 0] ?? []
|
||||
|
||||
const {
|
||||
studentNumber,
|
||||
@@ -237,12 +246,7 @@ export const getYearlyStatsOfNew = async (
|
||||
courseCode: creditCourseCode,
|
||||
credits,
|
||||
creditTypeCode,
|
||||
} = parseCredit(
|
||||
creditGroup,
|
||||
anonymizationSalt,
|
||||
courseCode,
|
||||
studentNumberToSrElementsMap[creditGroup.at(0)?.student_studentnumber ?? 0] ?? []
|
||||
)
|
||||
} = parseCredit(creditGroup, anonymizationSalt, courseCode, studyRightElements)
|
||||
|
||||
counter.markStudyProgramme(
|
||||
studentNumber,
|
||||
@@ -258,7 +262,7 @@ export const getYearlyStatsOfNew = async (
|
||||
// Credits/attainments have quaranteed matching attainment_date and semesters/years
|
||||
const groupCode = separate ? semesterCode : yearCode
|
||||
const groupName = separate ? semesterName : yearName
|
||||
counter.markCreditToGroup(
|
||||
counter.markStudentGradeToGroup(
|
||||
studentNumber,
|
||||
passed,
|
||||
grade,
|
||||
@@ -270,10 +274,29 @@ export const getYearlyStatsOfNew = async (
|
||||
)
|
||||
|
||||
// Don't add students to student stats based on improved grades
|
||||
if (creditTypeCode === CreditTypeCode.IMPROVED) continue
|
||||
if (creditTypeCode !== CreditTypeCode.IMPROVED) {
|
||||
counter.markCreditToStudentCategories(studentNumber, attainmentDate, groupCode)
|
||||
}
|
||||
|
||||
// The same group can include a failed and a passed credit in which case the parseCredit
|
||||
// would return only the passed credit. Hence we split the failed and passed credit into
|
||||
// two separate groups
|
||||
for (const attemptCredits of splitIntoAttempts(creditGroup)) {
|
||||
const attempt = parseCredit(attemptCredits, anonymizationSalt, courseCode, studyRightElements)
|
||||
const attemptGroupCode = separate ? attempt.semesterCode : attempt.yearCode
|
||||
const attemptGroupName = separate ? attempt.semesterName : attempt.yearName
|
||||
counter.markAttemptToGroup(
|
||||
attempt.studentNumber,
|
||||
attempt.passed,
|
||||
attempt.grade,
|
||||
attemptGroupCode,
|
||||
attemptGroupName,
|
||||
attempt.courseCode,
|
||||
attempt.yearCode
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
for (const enrollments of enrollmentGroups) {
|
||||
if (!enrollments?.length) continue
|
||||
|
||||
|
||||
Reference in New Issue
Block a user