Init www
This commit is contained in:
commit
53fb800236
89
index.html
Normal file
89
index.html
Normal file
@ -0,0 +1,89 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>PaulW.XYZ /</title>
|
||||
<meta name="description" content="Paul's Homepage. I do things. Sporadically.">
|
||||
<link rel="stylesheet" href="/stylesheets/persia.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<svg class="m-icon"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
id="svg4546"
|
||||
version="1.1"
|
||||
viewBox="0 0 67.733332 67.733331"
|
||||
height="256"
|
||||
width="256">
|
||||
<defs
|
||||
id="defs4550" />
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
transform="translate(0,-229.26668)"
|
||||
id="layer1">
|
||||
<path
|
||||
id="rect4524-2"
|
||||
d="M -3.5234382e-6,249.58668 9.0311079,263.13335 -3.5234382e-6,276.68002 v 13.54667 L 18.06222,263.13335 -3.5234382e-6,236.04001 Z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:0.2;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="rect4524-1-7"
|
||||
d="M 4.5155513,229.26668 27.093332,263.13335 4.5155524,297.00002 h 9.0311116 l 22.57778,-33.86667 -22.57778,-33.86667 z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:0.73333333;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="rect4524-1-8"
|
||||
d="m 13.546665,229.26668 22.57778,33.86667 -22.57778,33.86667 h 9.031111 l 18.062225,-27.09334 18.062224,27.09334 h 9.031113 L 45.155557,263.13335 22.577776,229.26668 Z"
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:0.73333333;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 36.124444,276.68002 13.546667,20.32 h 9.031113 L 40.64,269.90668 Z"
|
||||
id="path4779" />
|
||||
<path
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:0.46666667;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="M -3.5234382e-6,236.04001 18.06222,263.13335 -3.5234382e-6,290.22669 v 6.77333 H 4.5155524 L 27.093333,263.13335 4.5155524,229.26668 H -3.5234382e-6 Z"
|
||||
id="path4781" />
|
||||
<path
|
||||
id="path4783"
|
||||
d="m 31.608889,283.45335 9.03111,13.54667 h 9.031112 l -13.546667,-20.32 z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:0.46666667;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
<path
|
||||
id="path4783-1"
|
||||
d="m 27.093332,290.22669 4.515557,6.77333 H 40.64 l -9.031111,-13.54667 z"
|
||||
style="opacity:1;fill:#ffffff;fill-opacity:0.2;stroke:none;stroke-width:0.28266668;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
<nav>
|
||||
|
||||
<h1 class="title">PaulW.XYZ</h1>
|
||||
<div class="fuzzynav">
|
||||
<input class="search" type="text" id="search" placeholder="Navigate to ...">
|
||||
<div id="results" class="results"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
<footer>
|
||||
<a href="https://github.com/lambdapaul/">Hosted on GitHub</a>
|
||||
© 2021 Paul W.
|
||||
</footer>
|
||||
<script src="/scripts/fuzzynav.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
6
pages.json
Normal file
6
pages.json
Normal file
@ -0,0 +1,6 @@
|
||||
[
|
||||
["Pages", "/pages/"],
|
||||
["Resources", "/pages/resources"],
|
||||
["Recommended", "/pages/recommended"],
|
||||
["Grade Calculator", "/pages/grade-calc/"]
|
||||
]
|
23
pages/grade-calc/README.md
Normal file
23
pages/grade-calc/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# 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.
|
25
pages/grade-calc/config/eee3307c.json
Normal file
25
pages/grade-calc/config/eee3307c.json
Normal file
@ -0,0 +1,25 @@
|
||||
[
|
||||
{
|
||||
"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."
|
||||
}
|
||||
]
|
29
pages/grade-calc/config/eel4742c.json
Normal file
29
pages/grade-calc/config/eel4742c.json
Normal file
@ -0,0 +1,29 @@
|
||||
[
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
35
pages/grade-calc/config/eel4781.json
Normal file
35
pages/grade-calc/config/eel4781.json
Normal file
@ -0,0 +1,35 @@
|
||||
[
|
||||
{
|
||||
"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
|
||||
]
|
||||
}
|
||||
]
|
41
pages/grade-calc/config/map2302.json
Normal file
41
pages/grade-calc/config/map2302.json
Normal file
@ -0,0 +1,41 @@
|
||||
[
|
||||
{
|
||||
"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
|
||||
}
|
||||
]
|
203
pages/grade-calc/gc_client.js
Normal file
203
pages/grade-calc/gc_client.js
Normal file
@ -0,0 +1,203 @@
|
||||
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(`${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}%<br> 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}%<br> Total Score (unweighted): ${ugrade}%`;
|
||||
return;
|
||||
}
|
||||
|
||||
this.totalOutput.innerHTML = `Total Score: ${grade}%`;
|
||||
}
|
||||
|
||||
get elemTotal() {
|
||||
return this.totalOutput;
|
||||
}
|
||||
}
|
127
pages/grade-calc/index.html
Normal file
127
pages/grade-calc/index.html
Normal file
@ -0,0 +1,127 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta name="Grade Calculator" content="School grade calculation">
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Grade Calc</title>
|
||||
</head>
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.about-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.json-textarea,
|
||||
.calculator-container {
|
||||
width: 50%;
|
||||
padding: 1rem;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.json-textarea textarea {
|
||||
max-width: 100%;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.button-container button {
|
||||
border: 1px solid black;
|
||||
border-radius: 0;
|
||||
font-size: 1em;
|
||||
text-align: center;
|
||||
margin: .5rem 0;
|
||||
width: 100%;
|
||||
padding: 0.5rem 1rem;
|
||||
background-color: #90c541;
|
||||
color: #FFF;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 900px) {
|
||||
|
||||
.json-textarea,
|
||||
.calculator-container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<div class="about-container">
|
||||
<h1><a href="/">PaulW.XYZ</a> / <a href="/pages/">Pages</a> / Grade Calculator</h1>
|
||||
<hr>
|
||||
<h2>About</h2>
|
||||
Check out the <a href="https://github.com/lambdapaul/pages/blob/master/grade-calc/README.md">README.md</a> file
|
||||
to learn more about the configuration structure.
|
||||
<h3>Usage</h3>
|
||||
<ol>
|
||||
<li>Either configure the calculator using the text box below or load one from the existing JSON files to
|
||||
generate one.</li>
|
||||
<li>Click <code>Generate</code>.</li>
|
||||
<li>Enter the input values.</li>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="json-textarea">
|
||||
<h2>Configuration</h2>
|
||||
<h3>Load config from file</h3>
|
||||
<ul>
|
||||
<li><a href="javascript:void(0)" onclick="loadConfig('./config/map2302.json')">MAP2302 - ODE I Fall 2019</a>
|
||||
</li>
|
||||
<li><a href="javascript:void(0)" onclick="loadConfig('./config/eee3307c.json')">EEE3307C - Electronics I
|
||||
Spring 2021</a></li>
|
||||
</ul>
|
||||
<div class="button-container">
|
||||
<button onclick="generate()">Generate →</button>
|
||||
</div>
|
||||
<textarea id="json" id="" rows="30"></textarea>
|
||||
|
||||
</div>
|
||||
<div class="calculator-container">
|
||||
</div>
|
||||
<script type="text/javascript" src="gc_client.js"></script>
|
||||
<script>
|
||||
function generate() {
|
||||
var let;
|
||||
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();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
20
pages/index.html
Normal file
20
pages/index.html
Normal file
@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>PaulW.XYZ / Pages</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<h1><a href="/">PaulW.XYZ</a> / Pages</h1>
|
||||
<ul>
|
||||
<li><a href="/pages/grade-calc/">Grade Calculator</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<ul type="none">
|
||||
<li><a href="resources">Resources</a></li>
|
||||
<li><a href="https://github.com/lambdapaul/pages">GitHub</a></li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
97
pages/recommended.html
Normal file
97
pages/recommended.html
Normal file
@ -0,0 +1,97 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Pages / Recommended</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<!-- This page is really for me to not forget/revisit the good things I have read, seen, heard, and/or experienced. This list may change, just as my opinions. -->
|
||||
<h1><a href="/">PaulW.XYZ</a> / <a href="/pages/">Pages</a> / Recommended</h1>
|
||||
<p>If the one you're looking for is not on this list, it is most likely I haven't had the chance to read it yet or I may have put it on the Resources page, if it is freely available.</p>
|
||||
<hr>
|
||||
<h2>Books</h2>
|
||||
<h3>Technology</h3>
|
||||
<h4>C programming</h4>
|
||||
<ul>
|
||||
<li><a href="https://en.wikipedia.org/wiki/The_C_Programming_Language">The C Programming Language [K&R]</a> duh</li>
|
||||
<li>Expert C Programming by Peter van der Linden</li>
|
||||
<li>Practical C Programming by Steve Oualline (kind of outdated but still good)</li>
|
||||
</ul>
|
||||
<h4>Operating Systems</h4>
|
||||
<ul>
|
||||
<li>Advanced Programming in the Unix Environment by W. Richard Stevens</li>
|
||||
<li>Operating Systems: Design and Implementation by Andrew S. Tanenbaum (I haven't had a chance to read his other books on OS. I am not a fan of his networking book though.)</li>
|
||||
</ul>
|
||||
|
||||
<!-- <h4>Networking</h4>
|
||||
<ul>
|
||||
<li></li>
|
||||
</ul> -->
|
||||
|
||||
<h4>Computer Engineering</h4>
|
||||
<ul>
|
||||
<li>Making Embedded Systems: Design Patterns for Great Software by Elecia White</li>
|
||||
<!-- <li>Computer Organization and Design: the Hardware/Software Interface [Patterson Hennessy]</li>
|
||||
<li>Computer Architecture: A Quantitative Approach [Hennessy Patterson]</li> -->
|
||||
</ul>
|
||||
|
||||
<!-- <h4>Electronics</h4> -->
|
||||
|
||||
<h4>Compilers</h4>
|
||||
<ul>
|
||||
<li>Compilers: Principles, Techniques, and Tools [Dragon Book] (discusses theory in detail so it is kind of hard to read)</li>
|
||||
</ul>
|
||||
|
||||
<h4>Other</h4>
|
||||
<ul>
|
||||
<li>Definitive Guide to sed: Tutorial and Reference</li>
|
||||
</ul>
|
||||
|
||||
<h3>Classics</h3>
|
||||
<p>Only the English ones for now.</p>
|
||||
<ul>
|
||||
<li>A Tale of Two Cities</li>
|
||||
<li>The Mayor of Casterbridge</li>
|
||||
<li>The Citadel</li>
|
||||
<li>Oliver Twist</li>
|
||||
<li>Macbeth</li>
|
||||
<li>Othello</li>
|
||||
<li>Adventures of Huckleberry Finn</li>
|
||||
</ul>
|
||||
|
||||
<h3>Languages</h3>
|
||||
<ul>
|
||||
<li>Lingua Latina per se Illustrata (Both parts)</li>
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
<h2>Movies</h2>
|
||||
<ul>
|
||||
<li>Blade Runner 2049</li>
|
||||
<li>The Hateful Eight</li>
|
||||
<li>Goodfellas</li>
|
||||
<li>Inception</li>
|
||||
<li>Memento</li>
|
||||
<li>The Grand Budapest Hotel</li>
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
<h2>Music</h2>
|
||||
<ul>
|
||||
<li>Große Fuge Op. 133</li>
|
||||
<li>KV 387</li>
|
||||
<li>KV 448</li>
|
||||
<li>BWV 1048</li>
|
||||
<li>Prelude in G Minor (Op. 23 No. 5)</li>
|
||||
<li>String Quartet, Op. 20 No. 2 (Haydn)</li>
|
||||
</ul>
|
||||
<hr>
|
||||
|
||||
<h2>Video Games</h2>
|
||||
<ul>
|
||||
<li>The Legend of Zelda: Breath of the Wild</li>
|
||||
<li>Portal 2</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
41
pages/resources.html
Normal file
41
pages/resources.html
Normal file
@ -0,0 +1,41 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Pages / Resources</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<h1><a href="/">PaulW.XYZ</a> / <a href="/pages/">Pages</a> / Resources</h1>
|
||||
<hr>
|
||||
<h2>Programming</h2>
|
||||
<ul>
|
||||
<li><a href="http://aggregate.org/MAGIC/">The Aggregate Magic Algorithms</a></li>
|
||||
<li><a href="https://3fx.ch/typing-is-hard.html">Typing is Hard</a></li>
|
||||
<li><a href="https://www.atlassian.com/git/">Atlassian's Git Guide</a></li>
|
||||
<li><a href="https://learnopengl.com/">LearnOpenGL.com</a></li>
|
||||
<li><a href="http://ctan.math.utah.edu/ctan/tex-archive/info/symbols/comprehensive/symbols-letter.pdf">[PDF] LaTeX Symbols</a></li>
|
||||
<li><a href="https://tobi.oetiker.ch/lshort/lshort.pdf">[PDF] The Not So Short
|
||||
Introduction to LATEX 2ε</a></li>
|
||||
<li><a href="https://writing.kemitchell.com/2016/09/21/MIT-License-Line-by-Line.html">
|
||||
The MIT License, Line by Line by Kyle E. Mitchell</a></li>
|
||||
</ul>
|
||||
<h3>Posts</h3>
|
||||
<ul>
|
||||
<li><a href="https://mtlynch.io/code-review-love/">How to Make Your Code Reviewer Fall in Love with You by Michael Lynch</a></li>
|
||||
<li><a href="https://fasterthanli.me/articles/whats-in-the-box">What's in the box? by @fasterthanlime</a></li>
|
||||
</ul>
|
||||
<h3>Talks</h3>
|
||||
<ul>
|
||||
<li><a href="https://talks.golang.org/2012/waza.slide">Concurrency is not Parallelism by Rob Pike</a></li>
|
||||
</ul>
|
||||
<h2>Electrical</h2>
|
||||
<ul>
|
||||
<li><a href="http://www.mattmillman.com/info/crimpconnectors/">Common Wire-To-Board, Wire-To-Wire Connectors, And Crimp Tools</a></li>
|
||||
</ul>
|
||||
<h2>Other Topics</h2>
|
||||
<ul>
|
||||
<li><a href="https://sightreading.training/">Sight Reading Trainer</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
77
scripts/fuzzynav.js
Normal file
77
scripts/fuzzynav.js
Normal file
@ -0,0 +1,77 @@
|
||||
(function () {
|
||||
var client = new XMLHttpRequest();
|
||||
client.open("GET", "pages.json");
|
||||
client.onreadystatechange = function () {
|
||||
initFuzzy(client.responseText);
|
||||
}
|
||||
client.send();
|
||||
})();
|
||||
|
||||
function initFuzzy(text) {
|
||||
if (text == "")
|
||||
return;
|
||||
|
||||
var pages;
|
||||
try {
|
||||
pages = JSON.parse(text);
|
||||
} catch (e) {
|
||||
return;
|
||||
}
|
||||
|
||||
pages.sort();
|
||||
|
||||
let output = "";
|
||||
|
||||
for (const [name, rlink] of pages) {
|
||||
output += `<a class="hyperlink" href="${rlink}"><div class="name">${name}</div><div class="link">${rlink}</div></a>`;
|
||||
}
|
||||
|
||||
document.querySelector("#results").innerHTML = output;
|
||||
|
||||
document.querySelector("#search")
|
||||
.addEventListener("keyup", (e) => {
|
||||
|
||||
let results = [];
|
||||
for (const [i, [title, page]] of pages.entries()) {
|
||||
ret = hotFuzz(title, document.querySelector("#search").value);
|
||||
if (ret == false)
|
||||
continue;
|
||||
results.push([ret, page]);
|
||||
}
|
||||
|
||||
results.sort((x, y) => {return x[0].second - y[0].second});
|
||||
|
||||
let output = "";
|
||||
for (const [hfRet, rlink] of results) {
|
||||
output += `<a class="hyperlink" href="${rlink}"><div class="name">${hfRet.first}</div><div class="link">${rlink}</div></a>`;
|
||||
}
|
||||
|
||||
if (output == "")
|
||||
output = "No matches found."
|
||||
|
||||
document.querySelector("#results").innerHTML = output;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function hotFuzz(list, input) {
|
||||
let search = input.replace(/\s/g, "");
|
||||
search = search.toLowerCase();
|
||||
let tokens = list.split('');
|
||||
let pc = 0;
|
||||
let score = 0;
|
||||
|
||||
for (const [i, ch] of tokens.entries()) {
|
||||
if (ch.toLowerCase() == search[pc]) {
|
||||
score += i - pc;
|
||||
tokens[i] = `<span class="highlight">${ch}</span>`;
|
||||
pc++;
|
||||
if (search.length < pc)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (search.length != pc)
|
||||
return false;
|
||||
|
||||
return {first: tokens.join(''), second: (score / search.length)};
|
||||
}
|
237
stylesheets/persia.css
Normal file
237
stylesheets/persia.css
Normal file
@ -0,0 +1,237 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
line-height: 1.15;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
||||
background: linear-gradient(to bottom right, #64a95a, #388c73) no-repeat
|
||||
center center fixed;
|
||||
background-size: cover;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
article,
|
||||
aside,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
hgroup,
|
||||
main,
|
||||
nav,
|
||||
section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
font-size: 16px;
|
||||
font-weight: 400;
|
||||
line-height: 1.5;
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
[tabindex="-1"]:focus {
|
||||
outline: 0 !important;
|
||||
}
|
||||
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
h1,
|
||||
.h1 {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
h2,
|
||||
.h2 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
h3,
|
||||
.h3 {
|
||||
font-size: 1.75rem;
|
||||
}
|
||||
|
||||
h4,
|
||||
.h4 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
h5,
|
||||
.h5 {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
h6,
|
||||
.h6 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #b0e1ff;
|
||||
text-decoration: underline;
|
||||
background-color: transparent;
|
||||
outline: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
a:focus {
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
|
||||
.button {
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
background-color: transparent;
|
||||
border: 1px solid transparent;
|
||||
text-decoration: none;
|
||||
padding: 0.25rem 1rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
border: none;
|
||||
border-radius: 0.25rem;
|
||||
transition: filter 250ms ease;
|
||||
color: #fff;
|
||||
background: linear-gradient(#90c541, #388c73);
|
||||
margin: 0.25rem;
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 2px 3px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
filter: brightness(115%);
|
||||
color: #fff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.button:focus {
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 2px 3px 0 rgba(0, 0, 0, 0.1),
|
||||
0 0 0 0.2rem rgb(89, 149, 0);
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: none;
|
||||
|
||||
text-align: center;
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.fuzzynav {
|
||||
margin: 2rem;
|
||||
}
|
||||
|
||||
.fuzzynav input.search {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 2rem;
|
||||
background: linear-gradient(rgba(116, 116, 116, 0.2),rgba(65, 65, 65, 0.2));
|
||||
box-shadow: inset 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
padding: 0.5rem;
|
||||
color: rgb(255, 255, 255);
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.fuzzynav input.search::placeholder {
|
||||
color: rgb(214, 214, 214);
|
||||
/* font-style: italic; */
|
||||
}
|
||||
|
||||
.fuzzynav input.search::after {
|
||||
content: "";
|
||||
/* padding: 0.5rem;
|
||||
display: block;
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgaWQ9InN2ZzgiCiAgIHZlcnNpb249IjEuMSIKICAgdmlld0JveD0iMCAwIDMyIDMyIgogICA+CiAgPGRlZnMKICAgICBpZD0iZGVmczIiIC8+CiAgPG1ldGFkYXRhCiAgICAgaWQ9Im1ldGFkYXRhNSI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPHBhdGgKICAgICBpZD0icGF0aDQ3NjIiCiAgICAgZD0iTSAyMCAwIEEgMTIgMTIgMCAwIDAgOCAxMiBBIDEyIDEyIDAgMCAwIDEwLjg0NTcwMyAxOS43NDAyMzQgTCAwIDMwLjU4NTkzOCBMIDEuNDE0MDYyNSAzMiBMIDEyLjI1MTk1MyAyMS4xNjIxMDkgQSAxMiAxMiAwIDAgMCAyMCAyNCBBIDEyIDEyIDAgMCAwIDMyIDEyIEEgMTIgMTIgMCAwIDAgMjAgMCB6IE0gMjAgMiBBIDEwIDEwIDAgMCAxIDMwIDEyIEEgMTAgMTAgMCAwIDEgMjAgMjIgQSAxMCAxMCAwIDAgMSAxMCAxMiBBIDEwIDEwIDAgMCAxIDIwIDIgeiAiCiAgICAgc3R5bGU9Im9wYWNpdHk6MTtmaWxsOiNmZmZmZmY7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOm5vbmU7IiAvPgo8L3N2Zz4K); */
|
||||
}
|
||||
|
||||
.fuzzynav div.results {
|
||||
margin: 1rem;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
|
||||
.fuzzynav div.results .hyperlink {
|
||||
color: #009dff;
|
||||
background-color: rgba(34, 34, 34, 0.616);
|
||||
display: block;
|
||||
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
|
||||
padding: 0.5rem;
|
||||
width: 100%;
|
||||
margin: 0.5rem auto;
|
||||
font-size: 1.4rem;
|
||||
transition: 300ms cubic-bezier(0.075, 0.82, 0.165, 1);
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
|
||||
.fuzzynav div.results .hyperlink:hover {
|
||||
text-decoration: none;
|
||||
transform: scale(1.01);
|
||||
}
|
||||
|
||||
.fuzzynav div.results .hyperlink:focus {
|
||||
box-shadow: 0 0 1px 1px rgb(255, 255, 255);
|
||||
}
|
||||
|
||||
.fuzzynav div.results .hyperlink .name {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.fuzzynav div.results .hyperlink .link {
|
||||
text-align: right;
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.fuzzynav div.results .hyperlink .highlight {
|
||||
color: rgb(175, 175, 175)
|
||||
}
|
||||
|
||||
footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
color: #fff;
|
||||
background: linear-gradient(#90c541, #388c73);
|
||||
padding: 0.25rem;
|
||||
box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 2px 3px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.m-icon {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
}
|
Loading…
Reference in New Issue
Block a user