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,
|
studentNumber: string,
|
||||||
passed: boolean,
|
passed: boolean,
|
||||||
grade: string,
|
grade: string,
|
||||||
@@ -106,24 +131,11 @@ export class CourseYearlyStatsCounter {
|
|||||||
) {
|
) {
|
||||||
this.initGroup(groupCode, groupName, courseCode, yearCode)
|
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
|
// Don't add students to student stats based on improved grades
|
||||||
if (creditTypeCode === CreditTypeCode.IMPROVED) return
|
if (creditTypeCode === CreditTypeCode.IMPROVED) return
|
||||||
|
|
||||||
|
const current = this.groups[groupCode].students.grades[studentNumber]
|
||||||
|
|
||||||
if (current?.passed && !passed) return
|
if (current?.passed && !passed) return
|
||||||
if (current?.passed && Number(grade) <= Number(current?.grade)) return
|
if (current?.passed && Number(grade) <= Number(current?.grade)) return
|
||||||
this.groups[groupCode].students.grades[studentNumber] = { grade, passed }
|
this.groups[groupCode].students.grades[studentNumber] = { grade, passed }
|
||||||
|
|||||||
@@ -220,9 +220,18 @@ export const getYearlyStatsOfNew = async (
|
|||||||
|
|
||||||
const counter = new CourseYearlyStatsCounter()
|
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) {
|
for (const creditGroup of creditGroups) {
|
||||||
if (!creditGroup?.length) continue
|
if (!creditGroup?.length) continue
|
||||||
// if (creditGroup.every(credit => CreditModel.improved(credit))) continue
|
|
||||||
|
const studyRightElements = studentNumberToSrElementsMap[creditGroup.at(0)?.student_studentnumber ?? 0] ?? []
|
||||||
|
|
||||||
const {
|
const {
|
||||||
studentNumber,
|
studentNumber,
|
||||||
@@ -237,12 +246,7 @@ export const getYearlyStatsOfNew = async (
|
|||||||
courseCode: creditCourseCode,
|
courseCode: creditCourseCode,
|
||||||
credits,
|
credits,
|
||||||
creditTypeCode,
|
creditTypeCode,
|
||||||
} = parseCredit(
|
} = parseCredit(creditGroup, anonymizationSalt, courseCode, studyRightElements)
|
||||||
creditGroup,
|
|
||||||
anonymizationSalt,
|
|
||||||
courseCode,
|
|
||||||
studentNumberToSrElementsMap[creditGroup.at(0)?.student_studentnumber ?? 0] ?? []
|
|
||||||
)
|
|
||||||
|
|
||||||
counter.markStudyProgramme(
|
counter.markStudyProgramme(
|
||||||
studentNumber,
|
studentNumber,
|
||||||
@@ -258,7 +262,7 @@ export const getYearlyStatsOfNew = async (
|
|||||||
// Credits/attainments have quaranteed matching attainment_date and semesters/years
|
// Credits/attainments have quaranteed matching attainment_date and semesters/years
|
||||||
const groupCode = separate ? semesterCode : yearCode
|
const groupCode = separate ? semesterCode : yearCode
|
||||||
const groupName = separate ? semesterName : yearName
|
const groupName = separate ? semesterName : yearName
|
||||||
counter.markCreditToGroup(
|
counter.markStudentGradeToGroup(
|
||||||
studentNumber,
|
studentNumber,
|
||||||
passed,
|
passed,
|
||||||
grade,
|
grade,
|
||||||
@@ -270,8 +274,27 @@ export const getYearlyStatsOfNew = async (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// Don't add students to student stats based on improved grades
|
// 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)
|
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) {
|
for (const enrollments of enrollmentGroups) {
|
||||||
|
|||||||
Reference in New Issue
Block a user