Last active
June 30, 2022 04:23
-
-
Save duongoku/a68efbf36ea3461d53f3233de939b0ae to your computer and use it in GitHub Desktop.
Script for calculating courses related stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name UET-Graduate-Course-List | |
// @namespace https://github.com/duongoku/ | |
// @version 1.5.2 | |
// @description Script for calculating courses related stuff | |
// @author duongoku | |
// @license GPL-3.0-or-later | |
// @match https://daotao.uet.vnu.edu.vn/* | |
// @icon https://www.google.com/s2/favicons?sz=64&domain=uet.vnu.edu.vn | |
// ==/UserScript== | |
function get_log_element() { | |
var log_element = document.getElementById("console-log"); | |
if (log_element == null) { | |
log_element = document.createElement("span"); | |
log_element.style = "color: white; display: block; font-size: 0.75rem;"; | |
log_element.id = "console-log"; | |
} | |
return log_element; | |
} | |
function clear_log() { | |
var log_element = get_log_element(); | |
log_element.innerHTML = ""; | |
} | |
function log(log_string) { | |
var log_element = get_log_element(); | |
log_element.innerHTML += `${log_string}<br>`; | |
} | |
function parseScore(score) { | |
score = parseFloat(String(score)); | |
if (score >= 9) { | |
return `A+`; | |
} else if (score >= 8.5) { | |
return `A`; | |
} else if (score >= 8) { | |
return `B+`; | |
} else if (score >= 7) { | |
return `B`; | |
} else if (score >= 6.5) { | |
return `C+`; | |
} else if (score >= 5.5) { | |
return `C`; | |
} else if (score >= 5) { | |
return `D+`; | |
} else if (score >= 4) { | |
return `D`; | |
} | |
return "F"; | |
} | |
function run() { | |
if ( | |
!window.location | |
.toString() | |
.startsWith(`https://daotao.uet.vnu.edu.vn/graduates/`) | |
) { | |
return; | |
} | |
if ( | |
document | |
.querySelector(".text-muted") | |
.innerText.toString() | |
.trim() | |
.toLowerCase() != | |
`các học phần sinh viên đã tích lũy trong ctđt đang xét` | |
) { | |
return; | |
} | |
document.querySelector(`.container-fluid`).appendChild(get_log_element()); | |
clear_log(); | |
var excluded_courses = [`FLF1108`, `FLF1107`]; | |
var excluded_opt_courses = [ | |
`MAT1101`, | |
`ELT2029`, | |
`INT3102`, | |
`INT3103`, | |
`BSA2002`, | |
`INT3131`, | |
`INT3132`, | |
]; | |
var score_to_gpa = { | |
"A+": 4.0, | |
A: 3.7, | |
"B+": 3.5, | |
B: 3.0, | |
"C+": 2.5, | |
C: 2.0, | |
"D+": 1.5, | |
D: 1.0, | |
F: 0.0, | |
}; | |
var courses = Array.from(document.querySelector("tbody").children); | |
courses = courses.filter( | |
(x) => | |
!excluded_courses.includes( | |
x.children[1].innerText.trim().toUpperCase() | |
) | |
); | |
var total_credits = courses.reduce( | |
(acc, cur) => acc + parseFloat(cur.children[4].innerText), | |
0 | |
); | |
var cp = courses.reduce( | |
(acc, cur) => | |
acc + | |
score_to_gpa[parseScore(cur.children[5].innerText)] * | |
parseFloat(cur.children[4].innerText), | |
0 | |
); | |
var cpa = Math.round((cp * 100) / total_credits) / 100; | |
var optional_courses = courses.filter( | |
(x) => x.children[3].innerText.trim().toLowerCase() == `tự chọn` | |
); | |
var max_cp = courses.reduce((acc, cur) => { | |
var score = parseScore(cur.children[5].innerText); | |
var credit = parseFloat(cur.children[4].innerText); | |
if (optional_courses.includes(cur)) { | |
return acc + score_to_gpa[`A+`] * credit; | |
} | |
return acc + score_to_gpa[score] * credit; | |
}, 0); | |
var max_cpa = Math.round((max_cp * 100) / total_credits) / 100; | |
optional_courses = optional_courses.filter( | |
(x) => | |
!excluded_opt_courses.includes( | |
x.children[1].innerText.trim().toUpperCase() | |
) | |
); | |
log(`Total accumulated credits: ${total_credits}`); | |
log(`CPA: ${cpa}`); | |
log(`Max CPA (With the same amount of credits): ${max_cpa}`); | |
log(`Optional course count: ${optional_courses.length}`); | |
log( | |
`Total optional courses credit: ${optional_courses.reduce( | |
(acc, cur) => acc + parseFloat(cur.children[4].innerText), | |
0 | |
)}/30 credits needed` | |
); | |
log(`Optional course list:`); | |
optional_courses = optional_courses.sort( | |
(x, y) => | |
parseFloat(x.children[5].innerText) - | |
parseFloat(y.children[5].innerText) | |
); | |
optional_courses.forEach((x) => { | |
log( | |
`Score: ${x.children[5].innerText}(${parseScore( | |
x.children[5].innerText | |
)}) | Course ${x.children[1].innerText}: ${ | |
x.children[2].innerText | |
} | ${x.children[4].innerText} credits` | |
); | |
}); | |
} | |
// Rerun every 1.5 seconds before starting the script | |
setInterval(run, 1500); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment