Files
encoach_frontend/src/utils/score.ts

220 lines
4.0 KiB
TypeScript

import {Module, Step} from "@/interfaces";
import {Stat, User} from "@/interfaces/user";
type Type = "academic" | "general";
export const writingReverseMarking: {[key: number]: number} = {
9: 90,
8.5: 85,
8: 80,
7.5: 75,
7: 70,
6.5: 65,
6: 60,
5.5: 55,
5: 50,
4.5: 45,
4: 40,
3.5: 35,
3: 30,
2.5: 25,
2: 20,
1.5: 15,
1: 10,
0.5: 5,
0: 0,
};
export const speakingReverseMarking: {[key: number]: number} = {
9: 90,
8.5: 85,
8: 80,
7.5: 75,
7: 70,
6.5: 65,
6: 60,
5.5: 55,
5: 50,
4.5: 45,
4: 40,
3.5: 35,
3: 30,
2.5: 25,
2: 20,
1.5: 15,
1: 10,
0.5: 5,
0: 0,
};
export const writingMarking: {[key: number]: number} = {
90: 9,
80: 8,
70: 7,
60: 6,
50: 5,
40: 4,
30: 3,
20: 2,
10: 1,
0: 0,
};
const readingGeneralMarking: {[key: number]: number} = {
100: 9,
97.5: 8.5,
92.5: 8,
90: 7.5,
85: 7,
80: 6.5,
75: 6,
67.5: 5.5,
57.5: 5,
45.5: 4.5,
37.5: 4,
30: 3.5,
22.5: 3,
15: 2.5,
};
const academicMarking: {[key: number]: number} = {
97.5: 9,
92.5: 8.5,
87.5: 8,
80: 7.5,
75: 7,
65: 6.5,
57.5: 6,
45: 5.5,
40: 5,
32.5: 4.5,
25: 4,
20: 3.5,
15: 3,
10: 2.5,
};
const levelMarking: {[key: number]: number} = {
88: 9, // Advanced
64: 8, // Upper-Intermediate
52: 6, // Intermediate
32: 4, // Pre-Intermediate
16: 2, // Elementary
0: 0, // Beginner
};
const moduleMarkings: {[key in Module | "overall"]: {[key in Type]: {[key: number]: number}}} = {
reading: {
academic: academicMarking,
general: readingGeneralMarking,
},
listening: {
academic: academicMarking,
general: academicMarking,
},
writing: {
academic: writingMarking,
general: writingMarking,
},
speaking: {
academic: writingMarking,
general: writingMarking,
},
level: {
academic: levelMarking,
general: levelMarking,
},
overall: {
academic: levelMarking,
general: levelMarking,
},
};
export const calculateBandScore = (correct: number, total: number, module: Module | "overall", type: Type) => {
const marking = moduleMarkings[module][type];
const percentage = (correct * 100) / total;
if (module === "level") return percentage;
for (const value of Object.keys(marking)
.map((x) => parseFloat(x))
.sort((a, b) => b - a)) {
if (percentage >= value) {
return marking[value];
}
}
return 0;
};
export const calculateAverageLevel = (levels: {[key in Module]: number}) => {
return (
Object.keys(levels)
.filter((x) => x !== "level")
.reduce((accumulator, current) => levels[current as Module] + accumulator, 0) / 4
);
};
export const getLevelScore = (level: number) => {
switch (level) {
case 0:
return ["Beginner", "Low A1"];
case 2:
return ["Elementary", "High A1/Low A2"];
case 4:
return ["Pre-Intermediate", "High A2/Low B1"];
case 6:
return ["Intermediate", "High B1/Low B2"];
case 8:
return ["Upper-Intermediate", "High B2/Low C1"];
case 9:
return ["Advanced", "C1"];
default:
return [];
}
};
export const getLevelLabel = (level: number) => {
if (level < 2) return ["Foundation", "Pre-A1"];
if (level < 4) return ["Elementary", "A1"];
if (level < 5) return ["Pre-intermediate", "A2"];
if (level < 6) return ["Intermediate", "B1"];
if (level < 7) return ["Upper Intermediate", "B2"];
if (level < 8) return ["Advanced", "C1"];
return ["Proficiency", "C2"];
};
export const getGradingLabel = (score: number, grading: Step[]) => {
for (const step of grading) {
if (score >= step.min && score <= step.max) return step.label;
}
return "N/A";
};
export const averageLevelCalculator = (users: User[], studentStats: Stat[]) => {
const formattedStats = studentStats
.map((s) => ({
focus: users.find((u) => u.id === s.user)?.focus,
score: s.score,
module: s.module,
}))
.filter((f) => !!f.focus);
const bandScores = formattedStats.map((s) => ({
module: s.module,
level: calculateBandScore(s.score.correct, s.score.total, s.module, s.focus!),
}));
const levels: {[key in Module]: number} = {
reading: 0,
listening: 0,
writing: 0,
speaking: 0,
level: 0,
};
bandScores.forEach((b) => (levels[b.module] += b.level));
return calculateAverageLevel(levels);
};