Modified by www.SourceFiles.app

This commit is contained in:
2026-08-07 04:12:40 +00:00
parent c4ced91e16
commit 95c0961ea8
-36
View File
@@ -1,36 +0,0 @@
// Weighted-category grade calculation shared by the gradebook and the grade views.
export type Cat = { id: string; name: string; weight: number };
export type Scale = { letter: string; min_percent: number };
export type Assn = { id: string; category_id: string | null; max_points: number };
export type Grd = { assignment_id: string; student_id: string; points: number | null };
// Overall percent for a student: weighted average across categories that have graded work.
export function studentPercent(studentId: string, assignments: Assn[], grades: Grd[], categories: Cat[]): number | null {
const byCat: Record<string, { earned: number; possible: number }> = {};
for (const a of assignments) {
if (!a.category_id) continue;
const g = grades.find((x) => x.assignment_id === a.id && x.student_id === studentId && x.points != null);
if (!g) continue;
const b = byCat[a.category_id] ?? { earned: 0, possible: 0 };
b.earned += Number(g.points);
b.possible += Number(a.max_points);
byCat[a.category_id] = b;
}
let weighted = 0, totalW = 0;
for (const c of categories) {
const b = byCat[c.id];
if (!b || b.possible === 0) continue;
weighted += (b.earned / b.possible) * 100 * Number(c.weight);
totalW += Number(c.weight);
}
return totalW === 0 ? null : weighted / totalW;
}
export function letterFor(pct: number | null, scale: Scale[]): string {
if (pct == null) return "—";
const s = [...scale].sort((a, b) => Number(b.min_percent) - Number(a.min_percent));
for (const r of s) if (pct >= Number(r.min_percent)) return r.letter;
return s.length ? s[s.length - 1].letter : "—";
}
export const fmtPct = (pct: number | null) => (pct == null ? "—" : `${pct.toFixed(1)}%`);