Last active
September 11, 2021 02:53
-
-
Save Tuanm/12311f90ac21cf25e4bd3501d7d3553e to your computer and use it in GitHub Desktop.
Script to calculate CPA, GPA on SIS of HUST
This file contains hidden or 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
/** | |
* Script to calculate CPA, GPA on SIS of HUST. | |
* | |
* Usage: | |
* 0. Copy the script below | |
* 1. Go to website for Student Marks of HUST: | |
* https://ctt-sis.hust.edu.vn/Students/StudentCourseMarks.aspx | |
* 2. Open DevTools by pressing F12 (Right-Click -> Inspect) | |
* 3. Choose tab Console then paste the script into it -> Enter | |
* | |
* Use at your own risk! | |
*/ | |
(() => { | |
console.clear(); | |
const URL = 'https://ctt-sis.hust.edu.vn/Students/StudentCourseMarks.aspx'; | |
if (window.location.href !== URL) { | |
console.log('Error: Use on Student Marks only!'); | |
console.log(`--> ${URL}`); | |
return false; | |
} | |
const BASE_MARK_ROW_ID = 'ctl00_ctl00_contentPane_MainPanel_MainContent_gvCourseMarks_DXDataRow'; | |
const loadMark = (rowIndex) => { | |
const markRow = document.getElementById(BASE_MARK_ROW_ID + rowIndex); | |
return { | |
semester: markRow.childNodes[1].textContent, | |
subjectId: markRow.childNodes[2].textContent, | |
subjectName: markRow.childNodes[3].textContent, | |
credits: markRow.childNodes[4].textContent, | |
classId: markRow.childNodes[5].textContent, | |
middleMark: markRow.childNodes[6].textContent, | |
finalMark: markRow.childNodes[7].textContent, | |
rank: markRow.childNodes[8].textContent | |
}; | |
}; | |
const convertRankToPoint = (rank) => { | |
if (rank === 'A+' || rank === 'A') return 4.0; | |
if (rank === 'B+') return 3.5; | |
if (rank === 'B') return 3.0; | |
if (rank === 'C+') return 2.5; | |
if (rank === 'C') return 2.0; | |
if (rank === 'D+') return 1.5; | |
if (rank === 'D') return 1.0; | |
return 0.0; | |
}; | |
const calculateGPA = (marks, semester) => { | |
let creditPointProduct = 0.0; | |
let totalCredits = 0.0; | |
for (const mark of marks) { | |
if (mark.semester === semester) { | |
const point = convertRankToPoint(mark.rank); | |
creditPointProduct += point * Number(mark.credits); | |
totalCredits += Number(mark.credits); | |
} | |
} | |
return { | |
point: creditPointProduct / totalCredits, | |
credits: totalCredits | |
}; | |
}; | |
const calculateCPA = (marks) => { | |
let creditPointProduct = 0.0; | |
let totalCredits = 0.0; | |
for (const mark of marks) { | |
const point = convertRankToPoint(mark.rank); | |
creditPointProduct += point * Number(mark.credits); | |
totalCredits += Number(mark.credits); | |
} | |
return { | |
point: creditPointProduct / totalCredits, | |
credits: totalCredits | |
}; | |
}; | |
const calculateAll = (marks) => { | |
const gpas = {}; | |
for (const mark of marks) { | |
if (!gpas[mark.semester]) { | |
const result = calculateGPA(marks, mark.semester); | |
gpas[mark.semester] = { | |
point: result.point, | |
credits: result.credits | |
}; | |
} | |
} | |
const cpa = calculateCPA(marks); | |
return { | |
gpas: gpas, | |
cpa: cpa | |
}; | |
}; | |
(() => { | |
const marks = []; | |
console.log('Loading...'); | |
while (true) { | |
try { | |
const mark = loadMark(marks.length); | |
marks.push(mark); | |
} catch (error) { | |
console.log('Loaded.') | |
break; | |
} | |
} | |
const result = calculateAll(marks); | |
console.log('---'); | |
for (const semester of Object.keys(result.gpas)) { | |
const gpa = result.gpas[semester]; | |
console.log(`${semester}:\t${gpa.credits}\t${gpa.point}`); | |
} | |
console.log('---'); | |
console.log(`CPA:\t${result.cpa.credits}\t${result.cpa.point}`); | |
console.log('--- by Tuanm'); | |
})(); | |
return true; | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I just found it makes no sense while the website has all information we need. 😆