Skip to content

Instantly share code, notes, and snippets.

@alvesvaren
Last active May 22, 2022 13:26
Show Gist options
  • Save alvesvaren/4daab5335d23d796ad52d0fd1d21be95 to your computer and use it in GitHub Desktop.
Save alvesvaren/4daab5335d23d796ad52d0fd1d21be95 to your computer and use it in GitHub Desktop.
Räkna ut jämförelsetal för uppskattade betyg i schoolsoft
// ==UserScript==
// @name Betygsak
// @namespace http://tampermonkey.net/
// @version 1.1
// @description Räknar ut faktiskt jämförelsetal efter uppskattade betyg i pågående kurser
// @author Alve Svarén
// @match https://sms.schoolsoft.se/nti/jsp/student/right_student_course.jsp?menu=course
// @icon https://www.google.com/s2/favicons?domain=schoolsoft.se
// @grant none
// ==/UserScript==
(function () {
"use strict";
let points = [];
let grades = [];
const calcAdjustedGrade = (grade, points) => grade * points;
const sum = values => values.reduce((a, b) => a + b, 0);
const zip = (a, b) => a.map((k, i) => [k, b[i]]);
const getAverage = (adjustedGrades, points) => sum(adjustedGrades) / sum(points);
const values = {
A: 20,
B: 17.5,
C: 15,
D: 12.5,
E: 10,
F: 0,
};
const updateStorage = (key, newGrade, newPoints, newIsActive) => {
const data = getStored();
data[key] = {grade: newGrade, active: newIsActive ?? true, points: newPoints};
localStorage.predictedGradeData = JSON.stringify(data);
}
const getStored = () => {
return JSON.parse(localStorage.predictedGradeData || "{}");
}
const q = s => document.querySelector(s);
const [currentCourses, finishedCourses, scoreArea] = [q("table.table:nth-child(2)"), q("table.table:nth-child(8)"), q("td:nth-child(1) > table:nth-child(1) > tbody:nth-child(1)")];
const createBottomScoreArea = () => {
const scoreContainer = document.createElement("tr");
const title = document.createElement("td");
const realValue = document.createElement("td");
title.textContent = "Jämförelsetal inkl pågående kurser";
realValue.id = "real-value";
realValue.align = "right";
scoreContainer.appendChild(title);
scoreContainer.appendChild(realValue);
scoreArea.appendChild(scoreContainer);
setScores(0);
}
function addOption(text, value, parent, selected) {
const option = document.createElement("option");
option.text = text;
option.value = value;
option.selected = selected;
parent.appendChild(option);
}
const setScores = score => {
document.querySelector("#real-value").textContent = score;
};
const addField = row => {
const field = document.createElement("select");
const [name, code, category, points, start, end, year, teacher, flags] = Array.from(row.querySelectorAll("td")).map(e => e.textContent);
if (code !== "GYARTE") {
Object.entries(values).forEach(([key, value]) => {
const oldData = getStored()[code];
if (!oldData) {
updateStorage(code, 0, parseInt(points));
}
const isActive = (oldData || {}).grade === value;
addOption(key, value, field, isActive)
});
row.querySelector("td:nth-child(10)").appendChild(field);
field.addEventListener("change", e => {
const grade = parseFloat(e.currentTarget.value);
updateStorage(code, grade, parseInt(points));
setScores(calculateCurrentCourses());
})
}
};
const calculateCurrentCourses = () => {
let [currentPoints, currentGrades] = [[],[]];
Object.entries(getStored()).forEach(([key, value]) => {
currentPoints.push(value.points);
currentGrades.push(value.grade);
});
currentPoints = currentPoints.concat(points);
currentGrades = currentGrades.concat(grades);
return Math.floor(getAverage(
zip(currentGrades, currentPoints).map(([grade, point]) => calcAdjustedGrade(grade, point)),
currentPoints
)*100)/100;
}
function parseGrades() {
Array.from(document.querySelectorAll("table.table")).map(table => {
const rows = Array.from(table.querySelectorAll("tr"))
.slice(1, -1)
.map(row => {
const [name, code, category, start, end, year, teacher, flags] = Array.from(row.querySelectorAll("td")).map(e => e.textContent);
});
// table.table:nth-child(2) > tbody:nth-child(1) > tr:nth-child(5) > td:nth-child(2)
});
}
parseGrades();
createBottomScoreArea();
Array.from(currentCourses.querySelectorAll("tr")).slice(1, -1).forEach(row => {
addField(row);
});
const rows = Array.from(finishedCourses.querySelectorAll("tr")).slice(1, -1);
grades = rows.map(row => values[row.querySelector("td:nth-child(9)").textContent.slice(0, 1)]);
points = rows.map(row => parseInt(row.querySelector("td:nth-child(4)").textContent));
setScores(calculateCurrentCourses());
})();
@alvesvaren
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment