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); };