Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Computing-Grade-Calculator/index.js
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
401 lines (297 sloc)
11.7 KB
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
'use strict' | |
function removeLowestCreditModules(list, noToRemove, creditAmount) { | |
let count = 0 | |
creditAmount = creditAmount !== undefined ? creditAmount : 20 | |
while (count < noToRemove) { | |
const lowestModule = list.reduce((before, item) => { | |
if (before === null && item.credits === creditAmount) { | |
return item | |
} else if (item.credits === creditAmount && before.grade >= item.grade) { | |
return item | |
} else { | |
return before | |
} | |
}, null) | |
list = list.filter((item) => { | |
return item !== lowestModule | |
}) | |
count += 1 | |
} | |
return list | |
} | |
function averageGrade(modules) { | |
let credits = 0 | |
let grade = 0 | |
modules.forEach(item => { | |
credits += item.credits | |
grade += item.grade * item.credits | |
}) | |
return grade/credits | |
} | |
function getEndString(grade) { | |
if (grade < 39.5) { | |
return "⚠️ This is a FAIL ⚠️".red | |
} else if (grade >= 39.5 && grade < 49.5) { | |
return "This is a third 😩".yellow | |
} else if (grade >= 49.5 && grade < 59.5) { | |
return "This is a 2:2 🙁".yellow | |
} else if (grade >= 59.5 && grade < 69.5) { | |
return "This is a 2:1 👍".green | |
} else { | |
return "✨✨✨ This is a FIRST ✨✨✨".green | |
} | |
} | |
function createTable(modules) { | |
const table = new Table({ | |
head: ['name', 'credits', 'grade'] | |
}) | |
modules.forEach(item => { | |
table.push([item.name, item.credits, item.grade]) | |
}) | |
return table.toString() | |
} | |
const gradeFileLocation = process.argv[2] !== undefined ? process.argv[2] : './grades.json' | |
const gradefile = require(gradeFileLocation) | |
const colors = require('colors') | |
const Table = require('cli-table') | |
console.log('\n') | |
console.log("Parsing grades file") | |
console.log("===================") | |
const secondYear = gradefile.second_year | |
const thirdYear = gradefile.third_year | |
console.log("Checking gradefile correctness") | |
const secondParseInfo = { | |
noOf40: 0, | |
noOf20: 0, | |
noOf10: 0, | |
noOfOther: 0, | |
totalCredits: 0 | |
} | |
secondYear.forEach(module => { | |
switch (module.credits) { | |
case 40: | |
secondParseInfo.noOf40 += 1 | |
break | |
case 20: | |
secondParseInfo.noOf20 += 1 | |
break | |
case 10: | |
secondParseInfo.noOf10 += 1 | |
break | |
default: | |
secondParseInfo.noOfOther += 1 | |
break | |
} | |
secondParseInfo.totalCredits += module.credits | |
}) | |
// Should only be two 10 credit modules | |
if (secondParseInfo.noOf10 !== 2) { | |
console.log("\n⚠️ Second year should have two '10' credit modules! ⚠️\n".red) | |
process.exit(1) | |
} | |
// Should only be 0 or 1 40 credit module | |
if (secondParseInfo.noOf40 > 1) { | |
console.log("\n⚠️ Second year can only have one '30' credit module! ⚠️\n".red) | |
process.exit(1) | |
} | |
// Modules should either be 10, 20 or 40 | |
if (secondParseInfo.noOfOther > 0) { | |
console.log("\n⚠️ Second year modules should only have the credit amounts: '10', '20', and '40'! ⚠️\n".red) | |
process.exit(1) | |
} | |
if (secondParseInfo.noOf40 > 0 && secondParseInfo.totalCredits !== 160) { | |
console.log("\n⚠️ Second year credits should add to '160' with a '40' credit module! ⚠️\n".red) | |
process.exit(1) | |
} else if (secondParseInfo.noOf40 === 0 && secondParseInfo.totalCredits !== 120) { | |
console.log("\n⚠️ Second year credits should add to '120' ('160' if you went on placement) ⚠️\n".red) | |
process.exit(1) | |
} | |
console.log("Second year looks good 😄") | |
const thirdParseInfo = { | |
noOf30: 0, | |
noOf20: 0, | |
noOf10: 0, | |
noOfOther: 0, | |
totalCredits: 0 | |
} | |
thirdYear.forEach(module => { | |
switch (module.credits) { | |
case 30: | |
thirdParseInfo.noOf30 += 1 | |
break | |
case 20: | |
thirdParseInfo.noOf20 += 1 | |
break | |
case 10: | |
thirdParseInfo.noOf10 += 1 | |
break | |
default: | |
thirdParseInfo.noOfOther += 1 | |
break | |
} | |
thirdParseInfo.totalCredits += module.credits | |
}) | |
if (thirdParseInfo.noOf10 !== 1) { | |
console.log("\n⚠️ Third year can only have one '10' credit module! ⚠️\n".red) | |
process.exit(1) | |
} | |
if (thirdParseInfo.noOf30 > 1) { | |
console.log("\n⚠️ Third year can only have one '30' credit module! ⚠️\n".red) | |
process.exit(1) | |
} | |
if (thirdParseInfo.noOfOther > 0) { | |
console.log("\n⚠️ Third year modules should only have the credit amounts: '10', '20', and '30'! ⚠️\n".red) | |
process.exit(1) | |
} | |
if (thirdParseInfo.totalCredits !== 120) { | |
console.log("\n⚠️ Third year credits should add to '120' ⚠️\n".red) | |
process.exit(1) | |
} | |
console.log("Third year looks good 😄") | |
console.log("✅ Checks passed!".green) | |
console.log('\n') | |
console.log("flattening second year '10' credit modules") | |
const second10CreditModules = secondYear.filter(item => { | |
return item.credits === 10 | |
}) | |
const combinedSecond10CreditModules = { | |
name: `${second10CreditModules[0].name} && ${second10CreditModules[1].name}`, | |
credits: 20, | |
grade: (second10CreditModules[0].grade + second10CreditModules[1].grade)/2 | |
} | |
const flattenedSecondYear = secondYear.filter(item => { | |
return item.credits !== 10 | |
}) | |
flattenedSecondYear.push(combinedSecond10CreditModules) | |
console.log("Preliminary bits done, time to start calculating averages 😝") | |
console.log('\n') | |
console.log("Starting second year calulations") | |
console.log("================================") | |
let noPlacementSecondYear = flattenedSecondYear.filter(item => item.credits !== 40) | |
let noPlacementSecondYearWith10 = secondYear.filter(item => item.credits !== 40) | |
console.log("Calculating second year '120' credits w/o placement") | |
const best120SecondYearWOPlacement = { modules: removeLowestCreditModules(noPlacementSecondYear, 0) } | |
best120SecondYearWOPlacement.avgGrade = averageGrade(best120SecondYearWOPlacement.modules) | |
console.log(`Second year w/o placement: ${best120SecondYearWOPlacement.avgGrade}%`) | |
console.log("Calculating second year '120' credits w/ placement") | |
const best120SecondYearWPlacement = { modules: removeLowestCreditModules(flattenedSecondYear, 2) } | |
best120SecondYearWPlacement.avgGrade = averageGrade(best120SecondYearWPlacement.modules) | |
console.log(`Second year w/ placement: ${best120SecondYearWPlacement.avgGrade}%`) | |
console.log("Calculating second year '110' credits w/o placement") | |
const best110SecondYearWOPlacement = { modules: removeLowestCreditModules(noPlacementSecondYearWith10, 0, 10) } | |
best110SecondYearWOPlacement.avgGrade = averageGrade(best110SecondYearWOPlacement.modules) | |
console.log(`Second year w/o placement: ${best110SecondYearWOPlacement.avgGrade}%`) | |
console.log("Calculating second year '110' credits w/ placement") | |
const best110SecondYearWPlacement = { modules: removeLowestCreditModules(removeLowestCreditModules(secondYear, 2), 1, 10) } | |
best110SecondYearWPlacement.avgGrade = averageGrade(best110SecondYearWPlacement.modules) | |
console.log(`Second year w/ placement: ${best110SecondYearWPlacement.avgGrade}%`) | |
console.log("Calculating second year '100' credits w/o placement") | |
const best100SecondYearWOPlacement = { modules: removeLowestCreditModules(noPlacementSecondYear, 1) } | |
best100SecondYearWOPlacement.avgGrade = averageGrade(best100SecondYearWOPlacement.modules) | |
console.log(`Second year w/o placement: ${best100SecondYearWOPlacement.avgGrade}%`) | |
console.log("Calculating second year '100' credits w/ placement") | |
const best100SecondYearWPlacement = { modules: removeLowestCreditModules(flattenedSecondYear, 3) } | |
best100SecondYearWPlacement.avgGrade = averageGrade(best100SecondYearWPlacement.modules) | |
console.log(`Second year w/ placement: ${best100SecondYearWPlacement.avgGrade}%`) | |
const best120SecondYear = [best120SecondYearWOPlacement, best120SecondYearWPlacement].reduce((before, item) => { | |
if (before === null) { | |
return item | |
} else { | |
if (item.avgGrade > before.avgGrade) { | |
return item | |
} else { | |
return before | |
} | |
} | |
}, null) | |
const best110SecondYear = [best110SecondYearWOPlacement, best110SecondYearWPlacement].reduce((before, item) => { | |
if (before === null) { | |
return item | |
} else { | |
if (item.avgGrade > before.avgGrade) { | |
return item | |
} else { | |
return before | |
} | |
} | |
}, null) | |
const best100SecondYear = [best100SecondYearWOPlacement, best100SecondYearWPlacement].reduce((before, item) => { | |
if (before === null) { | |
return item | |
} else { | |
if (item.avgGrade > before.avgGrade) { | |
return item | |
} else { | |
return before | |
} | |
} | |
}, null) | |
console.log('\n') | |
console.log(`The best '120' credits from second year is: ${best120SecondYear.avgGrade}%`) | |
console.log(`The best '110' credits from second year is: ${best110SecondYear.avgGrade}%`) | |
console.log(`The best '100' credits from second year is: ${best100SecondYear.avgGrade}%`) | |
console.log("✅ Second year calculated".green) | |
console.log('\n') | |
console.log("Starting third year calulations") | |
console.log("===============================") | |
console.log("Calculating third year '120' credits") | |
const best120ThirdYear = {modules: thirdYear, avgGrade: averageGrade(thirdYear)} | |
console.log(`Third year 120: ${best120ThirdYear.avgGrade}%`) | |
console.log("Calculating third year '110' credits") | |
const thirdWithWorst10Removed = removeLowestCreditModules(thirdYear, 1, 10) | |
const best110ThirdYear = {modules: thirdWithWorst10Removed, avgGrade: averageGrade(thirdWithWorst10Removed)} | |
console.log(`Third year 110: ${best110ThirdYear.avgGrade}%`) | |
console.log("Calculating third year '100' credits") | |
const thirdWithWorstRemoved = removeLowestCreditModules(thirdYear, 1) | |
const best100ThirdYear = {modules: thirdWithWorstRemoved, avgGrade: averageGrade(thirdWithWorstRemoved)} | |
console.log(`Third year 100: ${best100ThirdYear.avgGrade}%`) | |
console.log("✅ Third year calculated".green) | |
console.log('\n') | |
console.log("Trying grade combinations") | |
console.log("=========================") | |
const s120t100 = ((best120SecondYear.avgGrade*120) + (best100ThirdYear.avgGrade*100))/220 | |
console.log(`120 from second, 100 from third: ${s120t100}%`) | |
const s100t120 = ((best100SecondYear.avgGrade*100) + (best120ThirdYear.avgGrade*120))/220 | |
console.log(`100 from second, 120 from third: ${s100t120}%`) | |
const s110t110 = ((best110SecondYear.avgGrade*110) + (best110ThirdYear.avgGrade*110))/220 | |
console.log(`110 from both: ${s110t110}%`) | |
const t100 = best100ThirdYear.avgGrade | |
console.log(`100 from third: ${t100}%`) | |
console.log("✅ Grade combinations complete".green) | |
console.log('\n') | |
console.log("Final Results") | |
console.log("=============") | |
if (s120t100>s100t120 && s120t100>s110t110 && s120t100>t100) { | |
console.log("Your best grade is from 120 second year credits and 100 third year credits") | |
console.log("This is done by taking the following modules from second year:") | |
console.log(createTable(best120SecondYear.modules)) | |
console.log('\n') | |
console.log("and the following modules from third year:") | |
console.log(createTable(best100ThirdYear.modules)) | |
console.log('\n') | |
console.log(`Your percentage will be ${s120t100.toFixed(2)}%. ${getEndString(s120t100)}`) | |
} else if (s110t110>s100t120 && s110t110>t100) { | |
console.log("Your best grade is from 110 credits from both years") | |
console.log("This is done by taking the following modules from second year:") | |
console.log(createTable(best110SecondYear.modules)) | |
console.log('\n') | |
console.log("and the following modules from third year:") | |
console.log(createTable(best110ThirdYear.modules)) | |
console.log('\n') | |
console.log(`Your percentage will be ${s100t120.toFixed(2)}%. ${getEndString(s100t120)}`) | |
} else if (s100t120>t100) { | |
console.log("Your best grade is from 100 second year credits and 120 third year credits") | |
console.log("This is done by taking the following modules from second year:") | |
console.log(createTable(best100SecondYear.modules)) | |
console.log('\n') | |
console.log("and the following modules from third year:") | |
console.log(createTable(best120ThirdYear.modules)) | |
console.log('\n') | |
console.log(`Your percentage will be ${s100t120.toFixed(2)}%. ${getEndString(s100t120)}`) | |
} else { | |
console.log("Your best grade is from 100 third year credits") | |
console.log("This is done by taking the following modules from third year:") | |
console.log(createTable(best100ThirdYear.modules)) | |
console.log('\n') | |
console.log(`Your percentage will be ${t100.toFixed(2)}%. ${getEndString(t100)}`) | |
} |