From 9ca3e18dd4feb741c3310c3ef9e47be836400b4b Mon Sep 17 00:00:00 2001 From: Paul Date: Tue, 15 Feb 2022 22:19:49 -0500 Subject: [PATCH] Remove grade-calc --- components/_gc.ts | 199 ------------------ pages/grade-calc/index.tsx | 99 --------- pages/grade-calc/readme.tsx | 16 -- public/grade-calc/README.md | 23 --- public/grade-calc/config/eee3307c.json | 25 --- public/grade-calc/config/eel4742c.json | 29 --- public/grade-calc/config/eel4781.json | 35 ---- public/grade-calc/config/map2302.json | 41 ---- public/grade-calc/vanilla.js | 268 ------------------------- public/pages.json | 1 - public/posts.json | 2 +- 11 files changed, 1 insertion(+), 737 deletions(-) delete mode 100644 components/_gc.ts delete mode 100644 pages/grade-calc/index.tsx delete mode 100644 pages/grade-calc/readme.tsx delete mode 100644 public/grade-calc/README.md delete mode 100644 public/grade-calc/config/eee3307c.json delete mode 100644 public/grade-calc/config/eel4742c.json delete mode 100644 public/grade-calc/config/eel4781.json delete mode 100644 public/grade-calc/config/map2302.json delete mode 100644 public/grade-calc/vanilla.js diff --git a/components/_gc.ts b/components/_gc.ts deleted file mode 100644 index 89e1cc1..0000000 --- a/components/_gc.ts +++ /dev/null @@ -1,199 +0,0 @@ -import React, { ReactElement } from 'react'; - -export default class GradeCalc { - maxscore = 0; - sections: Array = []; - inputSection: Array = [[]]; - outputSection: Array = []; - fields: Array = []; - grades: number[] = []; - ugrades: number[] = []; - both = false; - totalOutput: ReactElement; - config: any[]; - - constructor(config: {title: string, percentage: number}, outCallback: (arg: Array) => void) { - this.totalOutput = React.createElement('div'); - let dConfig = JSON.parse(JSON.stringify(config)); // dirty clone - let sanConfig = []; - for (let conf of dConfig) { - if (conf.percentage === undefined || conf.name === undefined) - continue; - if (conf.title === undefined) - conf.title = conf.name[0].toUpperCase() + conf.name.slice(1); - sanConfig.push(conf); - } - this.config = sanConfig; - for (let [i, conf] of this.config.entries()) { - this.maxscore += conf.percentage; - - this.inputSection[i] = []; - this.outputSection[i] = React.createElement('div'); - - if (conf.bothMethods) { - this.both = true; - } - - this.sections[i] = (this.createSection(i)); - } - - // for (let [k, v] of this.fields.entries()) { - // for (let field of v) { - // this.addInputEventListener(k, field); - // } - // } - - outCallback(this.sections); - } - - createSection(id: number): ReactElement { - - const conf = this.config[id]; - - const heading = React.createElement('h2', {}, `${conf.title} (${conf.percentage}%)`); - - let info = null - if (conf.info !== undefined) - info = (React.createElement('div', {}, conf.info)); - - - this.fields[id] = []; - let inputSection: Array | ReactElement = []; - if (conf.points !== undefined) { - for (let i = 0; i < conf.points.length; i++) { - inputSection[i] = this.createInputSection(id, i); - } - } - else { - inputSection = this.createInputSection(id, 0, true); - } - - const section = React.createElement('div', {className: conf.name}, heading, info, inputSection, - // this.outputSection[id] - ); - - return section; - } - - createInputSection(sectId: number, inputId: number, soleInput: boolean = false): ReactElement { - const conf = this.config[sectId]; - - let label = ''; - if (soleInput) - label = `${conf.title} Score: `; - else - label = `${conf.title} ${inputId + 1} Score: `; - - const field = React.createElement('input', { - className: `input ${conf.name}-score`, - onKeyUp: () => { - if (conf.output !== undefined && conf.output) - this.showSectionGrade(inputId); - this.showTotalGrade(); - } - }); - - this.fields[sectId][inputId] = field; - let suffix = (soleInput) ? '%' : ` / ${conf.points[inputId]} pts`; - - const inputSection = React.createElement('div', {className: 'input-section'}, label, field, suffix); - - this.inputSection[sectId][inputId] = inputSection; - return inputSection; - } - - calculateSectionGrade(id: number, unweighted = false): number { - // let conf = this.config[id]; - // let fields = this.fields[id]; - // if (fields === undefined) - // return 0; - // if (conf.points === undefined) { - // return parseFloat(fields[0].value); - // } - - // let total = 0; - - // if (unweighted) { - // let counter = 0; - // for (let [i, field] of fields.entries()) { - // let val = parseFloat(field.value); - // if (isNaN(val)) - // continue; - // total += val / conf.points[i]; - // counter++; - // } - - // return (total / counter * 100); - // } - - // total = fields.reduce((acc, cur) => { - // const c = parseFloat(cur.value); - - // return isNaN(c) ? acc : acc + c; - // }, 0); - - // let max_total = 0; - // for (const [i, field] of conf.points.entries()) { - // if (isNaN(parseFloat(fields[i].value))) - // continue; - // max_total += field; - // } - - // return (total / max_total * 100); - return 0; - } - - showSectionGrade(id: number) { - let conf = this.config[id]; - let grade = this.calculateSectionGrade(id); - let ugrade = this.calculateSectionGrade(id, true); - - - this.grades[id] = grade * parseFloat(conf.percentage) / 100; - this.ugrades[id] = ugrade * parseFloat(conf.percentage) / 100; - - const outGrade = !isNaN(grade) ? grade.toFixed(2) : "..."; - const outUgrade = !isNaN(ugrade) ? ugrade.toFixed(2) : "..."; - if (conf.bothMethods) { - this.outputSection[id].props.children - = `Score (weighted): ${outGrade}%
Score (unweighted): ${outUgrade}%`; - return; - } - - this.outputSection[id].props.value = `Score: ${grade}`; - } - - showTotalGrade() { - for (let [k, conf] of this.config.entries()) { - if (!conf.output) { - this.grades[k] = this.calculateSectionGrade(k) * parseFloat(conf.percentage) / 100; - this.ugrades[k] = this.calculateSectionGrade(k, true) * parseFloat(conf.percentage) / 100; - } - } - - let grade: number = this.grades.reduce((a, c) => { - if (isNaN(c)) - return a; - return a + c - }, 0); - let ugrade: number = this.ugrades.reduce((a, c) => { - if (isNaN(c)) - return a; - return a + c - }, 0); - - const outGrade = !isNaN(grade) ? grade.toFixed(2) : "..."; - const outUgrade = !isNaN(ugrade) ? ugrade.toFixed(2) : "..."; - if (this.both) { - // this.totalOutput.props.children - // = `Total Score (weighted): ${outGrade}%
Total Score (unweighted): ${outUgrade}%`; - return; - } - - // this.totalOutput.props.children = `Total Score: ${outGrade}%`; - } - - get elemTotal() { - return this.totalOutput; - } -} \ No newline at end of file diff --git a/pages/grade-calc/index.tsx b/pages/grade-calc/index.tsx deleted file mode 100644 index 0b36e7b..0000000 --- a/pages/grade-calc/index.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import React, { ReactElement, useEffect, useState } from 'react'; -import Layout from '../../components/layout'; -import Link from 'next/link'; -import GradeCalc from '../../components/_gc'; - -function GradeCalcPage() { - const [calculator, setCalculator] = useState(); - let [jsonInput, setJsonInput] = useState('[]'); - - function loadConfig(filename: string): void { - const client = new XMLHttpRequest(); - client.open('GET', filename); - client.onreadystatechange = () => { - setJsonInput(client.responseText); - } - client.send(); - } - - function generate() { - setCalculator(''); - let conf = null; - try { - conf = JSON.parse(jsonInput); - } - catch (e) { - console.log(e); - return; - } - let cb = (out: ReactElement[]) => { - setCalculator([... calculator, out]); - } - const gc = new GradeCalc(conf, cb); - if (calculator) - setCalculator([... calculator, React.createElement('div', {className: 'asf'}, gc.elemTotal)]); - } - - return ( - -
-
-

About

- Check out the README.md file - to learn more about the configuration structure. -

Usage

-
    -
  1. Either configure the calculator using the text box below or load one from the existing JSON files to - generate one.
  2. -
  3. Click Generate.
  4. -
  5. Enter the input values.
  6. -
-
- -
- {calculator} -
- -
-
- ) -} - -// export default GradeCalcPage; - -export default function WIP() { - useEffect(() => { - const script = document.createElement('script'); - - script.src = '/grade-calc/vanilla.js'; - script.async = true; - - document.body.appendChild(script); - - return () => { - document.body.removeChild(script); - } - }, []); - - return ( - -
- Check back later as the port of this page is a Work in Progress. -
-
); -} diff --git a/pages/grade-calc/readme.tsx b/pages/grade-calc/readme.tsx deleted file mode 100644 index e2a1583..0000000 --- a/pages/grade-calc/readme.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import ReactMarkdown from 'react-markdown'; -import Layout from '../../components/layout'; - -// @ts-ignore -import ReadmeMd from '../../public/grade-calc/README.md'; - - -function GCReadme() { - return ( -
- {ReadmeMd} -
-
); -} - -export default GCReadme; \ No newline at end of file diff --git a/public/grade-calc/README.md b/public/grade-calc/README.md deleted file mode 100644 index 3a99b3b..0000000 --- a/public/grade-calc/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Grade Calculator - -Some professors do not properly configure the Canvas grade percentages based on their syllabus. Instead, they opt to use Excel to calculate the final grades after everything. It can be hard to estimate how much effort I should allocate for those classes without making an Excel file. - -So I wrote this to quickly configure a calculator to see what I will end up getting in a class based on how much effort I put in. - -## Short Summary of the JSON structure - -The JSON is expected to have an array of section descriptions. - -`name : string` is used as the class name. They have to be unique for each section to work as expected. - -`title : string` is used as the heading for the sections. - -`percentage : number` is used to weigh the section for the final grade. - -`output : boolean` when true, it calculates the section score. - -`points : [number]` used for each assignment in the section. - -`bothMethods : boolean` when true, the weighted and unweighted scores are calculated. - -`info : string` used for section description. \ No newline at end of file diff --git a/public/grade-calc/config/eee3307c.json b/public/grade-calc/config/eee3307c.json deleted file mode 100644 index 09e6e3c..0000000 --- a/public/grade-calc/config/eee3307c.json +++ /dev/null @@ -1,25 +0,0 @@ -[ - { - "name": "final", - "title": "Final", - "percentage": 40, - "info": "" - }, - { - "name": "midterm", - "title": "Midterm", - "percentage": 30 - }, - { - "name": "homework", - "title": "Homework", - "percentage": 10, - "points": [100,100,100,100,100,100] - }, - { - "name": "lab", - "title": "Lab", - "percentage": 20, - "info": "Lab score is accurate and does not need any sub-calculation." - } -] \ No newline at end of file diff --git a/public/grade-calc/config/eel4742c.json b/public/grade-calc/config/eel4742c.json deleted file mode 100644 index a7c2457..0000000 --- a/public/grade-calc/config/eel4742c.json +++ /dev/null @@ -1,29 +0,0 @@ -[ - { - "name": "exams", - "percentage": 70, - "points": [ - 100, - 100, - 100 - ], - "title": "Exams" - }, - { - "name": "homework", - "percentage": 15, - "points": [ - 90, - 50, - 110, - 90 - ], - "title": "Homework" - }, - { - "info": "Lab score is accurate and does not need any sub-calculation.", - "name": "lab", - "percentage": 15, - "title": "Lab" - } -] \ No newline at end of file diff --git a/public/grade-calc/config/eel4781.json b/public/grade-calc/config/eel4781.json deleted file mode 100644 index f8cd9da..0000000 --- a/public/grade-calc/config/eel4781.json +++ /dev/null @@ -1,35 +0,0 @@ -[ - { - "name": "midterm", - "percentage": 25, - "info":"http://www.ece.ucf.edu/~yuksem/teaching/EEL-4781-Spring-2021.html" - }, - { - "name": "final", - "percentage": 25 - }, - { - "name": "project", - "percentage": 15, - "info":"Webserver project" - }, - { - "name": "homework", - "percentage": 20, - "points": [ - 100, - 100, - 100, - 100, - 100 - ] - }, - { - "name": "lab", - "percentage": 15, - "points": [ - 100, - 100 - ] - } -] \ No newline at end of file diff --git a/public/grade-calc/config/map2302.json b/public/grade-calc/config/map2302.json deleted file mode 100644 index abddd19..0000000 --- a/public/grade-calc/config/map2302.json +++ /dev/null @@ -1,41 +0,0 @@ -[ - { - "name": "final", - "title": "Final", - "percentage": 25, - "info": "" - }, - { - "name": "midterm", - "title": "Midterm", - "percentage": 50, - "points": [ - 20, - 20, - 20 - ], - "output": true - }, - { - "name": "quiz", - "title": "Quiz", - "percentage": 10, - "points": [ - 30, - 10, - 15 - ], - "output": true, - "bothMethods": true - }, - { - "name": "homework", - "title": "Homework", - "percentage": 10 - }, - { - "name": "attendance", - "title": "Attendance", - "percentage": 5 - } -] \ No newline at end of file diff --git a/public/grade-calc/vanilla.js b/public/grade-calc/vanilla.js deleted file mode 100644 index ecbb71a..0000000 --- a/public/grade-calc/vanilla.js +++ /dev/null @@ -1,268 +0,0 @@ -(()=>{ - const cont = ` -
-

About

- Check out the README.md file - to learn more about the configuration structure. -

Usage

-
    -
  1. Either configure the calculator using the text box below or load one from the existing JSON files to - generate one.
  2. -
  3. Click Generate.
  4. -
  5. Enter the input values.
  6. -
-
-
-
- `; - document.querySelector('.grade-calc').innerHTML = cont; -})(); // eh - -function generate() { - let calcSection = document.querySelector(".calculator-container"); - calcSection.innerHTML = ""; - try { - conf = JSON.parse(document.getElementById("json").value); - } - catch (e) { - console.log(e); - calcSection.innerHTML = e; - return; - } - let cb = (out) => { - for (let o of out) { - calcSection.appendChild(o); - } - } - gc = new __GradeCalc(conf, cb); - - calcSection.appendChild(gc.elemTotal); -} - -function loadConfig(filename) { - var client = new XMLHttpRequest(); - client.open('GET', filename); - client.onreadystatechange = function () { - document.getElementById("json").value = (client.responseText); - } - client.send(); -} - -class __GradeCalc { - maxscore = 0; - sections = []; - inputSection = []; - outputSection = []; - fields = []; - grades = []; - ugrades = []; - both = false; - totalOutput = null; - - constructor(config, outCallback) { - this.totalOutput = document.createElement("div"); - let dConfig = JSON.parse(JSON.stringify(config)); // dirty clone - let sanConfig = []; - for (let conf of dConfig) { - if (conf.percentage === undefined || conf.name === undefined) - continue; - if (conf.title === undefined) - conf.title = conf.name[0].toUpperCase() + conf.name.slice(1); - sanConfig.push(conf); - } - this.config = sanConfig; - for (let [i, conf] of this.config.entries()) { - this.maxscore += conf.percentage; - - this.inputSection[i] = []; - this.outputSection[i] = document.createElement("div"); - - if (conf.bothMethods) { - this.both = true; - } - - this.sections[i] = (this.createSection(i)); - } - - for (let [k, v] of this.fields.entries()) { - for (let field of v) { - this.addInputEventListener(k, field); - } - } - - outCallback(this.sections); - } - - createSection(id) { - let conf = this.config[id]; - - var section = document.createElement("div"); - section.classList.add(conf.name); - - var heading = document.createElement("h2"); - heading.innerHTML = `${conf.title} (${conf.percentage}%)`; - - section.appendChild(heading); - - if (conf.info !== undefined) - section.appendChild(document.createTextNode(conf.info)); - - this.fields[id] = []; - if (conf.points !== undefined) { - for (var i = 0; i < conf.points.length; i++) { - section.appendChild(this.createInputSection(id, i)); - } - } - else { - section.appendChild(this.createInputSection(id, 0, true)); - } - - - section.appendChild(this.outputSection[id]); - return section; - } - - createInputSection(sectId, inputId, soleInput = false) { - let conf = this.config[sectId]; - let inputSection = document.createElement("div"); - inputSection.classList.add("input-section"); - - let label = document.createElement("label"); - if (soleInput) - label.innerHTML = `${conf.title} Score: `; - else - label.innerHTML = `${conf.title} ${inputId + 1} Score: `; - - let field = document.createElement("input"); - field.classList.add(`input`); - field.classList.add(`${conf.name}-score`); - this.fields[sectId][inputId] = field; - - let suffix = (soleInput) ? "%" : ` / ${conf.points[inputId]} pts`; - - inputSection.appendChild(label); - inputSection.appendChild(field); - inputSection.appendChild(document.createTextNode(suffix)); - - this.inputSection[sectId][inputId] = inputSection; - return inputSection; - } - - addInputEventListener(id, field, event = "keyup") { - let conf = this.config[id]; - field.addEventListener(event, () => { - if (conf.output !== undefined && conf.output) - this.showSectionGrade(id); - this.showTotalGrade(); - }); - } - - calculateSectionGrade(id, unweighted = false) { - let conf = this.config[id]; - let fields = this.fields[id]; - if (fields === undefined) - return; - if (conf.points === undefined) { - return parseFloat(fields[0].value); - } - - let total = 0; - - if (unweighted) { - let counter = 0; - for (let [i, field] of fields.entries()) { - let val = parseFloat(field.value); - if (isNaN(val)) - continue; - total += val / conf.points[i]; - counter++; - } - - return (total / counter * 100); - } - - total = fields.reduce((acc, cur) => { - let c = parseFloat(cur.value); - if (isNaN(c)) - return acc; - return acc + parseFloat(c); - }, 0); - - let max_total = 0; - for (let [i, field] of conf.points.entries()) { - if (isNaN(parseFloat(fields[i].value))) - continue; - max_total += field; - } - - return (total / max_total * 100); - } - - showSectionGrade(id) { - let conf = this.config[id]; - let grade = this.calculateSectionGrade(id); - let ugrade = this.calculateSectionGrade(id, true); - - - this.grades[id] = grade * parseFloat(conf.percentage) / 100; - this.ugrades[id] = ugrade * parseFloat(conf.percentage) / 100; - - grade = !isNaN(grade) ? grade.toFixed(2) : "..."; - ugrade = !isNaN(ugrade) ? ugrade.toFixed(2) : "..."; - if (conf.bothMethods) { - this.outputSection[id].innerHTML - = `Score (weighted): ${grade}%
Score (unweighted): ${ugrade}%`; - return; - } - - this.outputSection[id].innerHTML = `Score: ${grade}`; - } - - showTotalGrade() { - for (let [k, conf] of this.config.entries()) { - if (!conf.output) { - this.grades[k] = this.calculateSectionGrade(k) * parseFloat(conf.percentage) / 100; - this.ugrades[k] = this.calculateSectionGrade(k, true) * parseFloat(conf.percentage) / 100; - } - } - - let grade = this.grades.reduce((a, c) => { - if (isNaN(c)) - return a; - return a + c - }, 0); - let ugrade = this.ugrades.reduce((a, c) => { - if (isNaN(c)) - return a; - return a + c - }, 0); - - grade = !isNaN(grade) ? grade.toFixed(2) : "..."; - ugrade = !isNaN(ugrade) ? ugrade.toFixed(2) : "..."; - if (this.both) { - this.totalOutput.innerHTML - = `Total Score (weighted): ${grade}%
Total Score (unweighted): ${ugrade}%`; - return; - } - - this.totalOutput.innerHTML = `Total Score: ${grade}%`; - } - - get elemTotal() { - return this.totalOutput; - } -} diff --git a/public/pages.json b/public/pages.json index c7d8738..cd88d01 100644 --- a/public/pages.json +++ b/public/pages.json @@ -2,7 +2,6 @@ {"title":"About", "link": "/about"}, {"title":"Resources", "link": "/resources"}, {"title":"Recommended", "link": "/recommended"}, - {"title":"Grade Calculator", "link": "/grade-calc"}, {"title":"GitHub", "link": "https://github.com/lambdapaul"}, {"title":"GitLab", "link": "https://gitlab.com/lambdapaul"}, {"title":"Twitter", "link": "https://twitter.com/lambda_paul"}, diff --git a/public/posts.json b/public/posts.json index 096e449..238787d 100644 --- a/public/posts.json +++ b/public/posts.json @@ -1 +1 @@ -[{"title":"Steam Info","slug":"steam-info","last_updated":"2022-02-14T09:18:29.604Z"},{"title":"Thoughts on Baba Is You","slug":"thoughts-on-baba-is-you","last_updated":"2021-10-29T04:00:00.000Z"}] \ No newline at end of file +[{"title":"Thoughts on Baba Is You","slug":"thoughts-on-baba-is-you","last_updated":"2021-10-30T00:43:00.000Z"}] \ No newline at end of file