Skip to content

Instantly share code, notes, and snippets.

@maxlevy-rakuten
Created October 16, 2024 11:18
Show Gist options
  • Save maxlevy-rakuten/73c9ccf00a9a06974074f14dc8ab8619 to your computer and use it in GitHub Desktop.
Save maxlevy-rakuten/73c9ccf00a9a06974074f14dc8ab8619 to your computer and use it in GitHub Desktop.
Math quiz for kids
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Math Quiz</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
#problem {
font-size: 24px;
margin-bottom: 10px;
}
#feedback {
margin-top: 10px;
}
#progress-container {
margin-top: 20px;
width: 100%;
background-color: #e0e0e0;
height: 20px;
border-radius: 10px;
overflow: hidden;
}
#progress-bar {
height: 100%;
width: 0;
background-color: green;
transition: width 0.1s ease;
}
#statistics {
margin-top: 20px;
}
</style>
</head>
<body>
<h1>Math Quiz</h1>
<div id="problem"></div>
<input type="text" id="answer" placeholder="Enter your answer" />
<button id="submit">Submit</button>
<div id="feedback"></div>
<!-- Progress bar -->
<div id="progress-container">
<div id="progress-bar"></div>
</div>
<!-- Statistics section -->
<div id="statistics"></div>
<script>
function generateProblemAndSolution() {
// Random number generator function for a range [min, max]
function randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Generate random numbers for the arithmetic problem
const num1 = randomInt(1, 50);
const num2 = randomInt(1, 20);
const divisor = randomInt(9, 33); // Choose divisor
const num3 = divisor * randomInt(13, 35); // Make num3 a multiple of divisor to ensure integer division
const num4 = randomInt(1, 10);
const num5 = randomInt(1, 10);
// Choose random operations
const operations = ["+", "-", "*"]; // "/"];
const op1 = operations[randomInt(0, operations.length - 1)];
const op2 = operations[randomInt(0, operations.length - 1)];
const op3 = operations[randomInt(0, operations.length - 1)];
// Form the problem string
const problem = `${num1} ${op1} ${num2} * (${num3} / ${divisor} ${op2} ${num4} ${op3} ${num5})`;
// Evaluate the solution using eval() and rounding to ensure a natural number result
let solution;
try {
solution = Math.round(eval(problem)); // Round in case of edge cases
} catch (error) {
console.error("Error evaluating the problem:", error);
}
return { problem, solution };
}
// Example usage
const generated = generateProblemAndSolution();
console.log(`Problem: ${generated.problem}`);
console.log(`Solution: ${generated.solution}`);
const problems = [...new Array(3)].map(generateProblemAndSolution);
let currentProblem = 0;
let startTime;
let maxTime = 120; // Maximum time allowed for each question in seconds
let timerInterval;
let totalCorrect = 0;
let totalTime = 0;
function showProblem() {
document.getElementById(
"problem"
).textContent = `Problem: ${problems[currentProblem].problem}`;
document.getElementById("answer").value = "";
document.getElementById("feedback").textContent = "";
resetProgressBar();
startTimer();
}
function checkAnswer() {
const userAnswer = parseInt(
document.getElementById("answer").value,
10
);
const endTime = new Date();
const timeTaken = (endTime - startTime) / 1000; // Time in seconds
clearInterval(timerInterval); // Stop timer when user submits answer
problems[currentProblem].userAnswer = userAnswer;
if (userAnswer === problems[currentProblem].solution) {
document.getElementById("feedback").textContent = "Correct!";
totalCorrect++;
} else {
document.getElementById(
"feedback"
).textContent = `Incorrect! The answer is ${problems[currentProblem].solution}`;
}
problems[currentProblem].timeTaken = timeTaken;
totalTime += timeTaken;
currentProblem++;
if (currentProblem < problems.length) {
setTimeout(showProblem, 7000);
} else {
showStatistics(); // Quiz complete, show stats
}
}
function startTimer() {
startTime = new Date();
let timeElapsed = 0;
timerInterval = setInterval(function () {
timeElapsed = (new Date() - startTime) / 1000; // Time elapsed in seconds
updateProgressBar(timeElapsed);
if (timeElapsed >= maxTime) {
clearInterval(timerInterval);
}
}, 100); // Update every 100 milliseconds
}
function updateProgressBar(timeElapsed) {
const progressPercentage = Math.min((timeElapsed / maxTime) * 100, 100);
const progressBar = document.getElementById("progress-bar");
// Change the width of the progress bar
progressBar.style.width = `${progressPercentage}%`;
// Gradually change color from green (start) to red (end)
const red = Math.min(Math.round((timeElapsed / maxTime) * 255), 255);
const green = Math.max(
Math.round(255 - (timeElapsed / maxTime) * 255),
0
);
progressBar.style.backgroundColor = `rgb(${red},${green},0)`;
}
function resetProgressBar() {
document.getElementById("progress-bar").style.width = "0%"; // Reset the bar
}
function showStatistics() {
const statsDiv = document.getElementById("statistics");
statsDiv.innerHTML = `
<h2>Quiz Complete!</h2>
<p>Correct answers: ${totalCorrect} out of ${
problems.length
}</p>
<p>Total time: ${totalTime.toFixed(2)} seconds</p>
<h3>Time taken for each problem:</h3>
<ul>
${problems
.map(
(p, i) =>
`<li class="report">#${i + 1}: <b>${
p.problem
} = ${p.solution} (${
p.userAnswer
}) </b>${p.timeTaken.toFixed(2)} seconds</li>`
)
.join("")}
</ul>
<br/>
Average time for correct answer: ${
problems.filter((p) => p.solution === p.userAnswer).length
? problems
.filter((p) => p.solution === p.userAnswer)
.reduce((a, c) => a + c.timeTaken) /
problems.filter((p) => p.solution === p.userAnswer)
.length
: "♾️"
} seconds
`;
}
document.getElementById("submit").addEventListener("click", checkAnswer);
// Start the quiz by showing the first problem
showProblem();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment