{
const scripts = Array.from(
document.querySelectorAll("script.fcpython-ojs-quiz-config")
);
const script = scripts.find(
(node) => node.dataset.fcpythonRendered !== "true"
);
if (!script) {
return html`<div class="fcpython-quiz fcpython-quiz-warning">
Quiz configuration was not found.
</div>`;
}
script.dataset.fcpythonRendered = "true";
const quiz = JSON.parse(script.textContent);
const container = html`<div class="fcpython-quiz"></div>`;
const title = document.createElement("h3");
title.textContent = quiz.title;
container.appendChild(title);
const instructions = document.createElement("p");
instructions.textContent = quiz.instructions;
container.appendChild(instructions);
const feedbackNodes = [];
quiz.questions.forEach((question, questionIndex) => {
const fieldset = document.createElement("fieldset");
fieldset.className = "fcpython-quiz-question";
const legend = document.createElement("legend");
legend.textContent = `${questionIndex + 1}. ${question.prompt}`;
fieldset.appendChild(legend);
question.options.forEach((option, optionIndex) => {
const label = document.createElement("label");
label.className = "fcpython-quiz-option";
const input = document.createElement("input");
input.type = "radio";
input.name = `${quiz.id}-${question.id}`;
input.value = String(optionIndex);
const text = document.createElement("span");
text.textContent = option;
label.appendChild(input);
label.appendChild(text);
fieldset.appendChild(label);
});
const feedback = document.createElement("p");
feedback.className = "fcpython-quiz-feedback";
feedback.setAttribute("aria-live", "polite");
feedbackNodes.push(feedback);
fieldset.appendChild(feedback);
container.appendChild(fieldset);
});
const actions = document.createElement("div");
actions.className = "fcpython-quiz-actions";
const check = document.createElement("button");
check.type = "button";
check.textContent = "Check answers";
const reset = document.createElement("button");
reset.type = "button";
reset.textContent = "Reset";
const score = document.createElement("p");
score.className = "fcpython-quiz-score";
score.setAttribute("aria-live", "polite");
check.addEventListener("click", () => {
let correctCount = 0;
quiz.questions.forEach((question, questionIndex) => {
const selected = container.querySelector(
`input[name="${quiz.id}-${question.id}"]:checked`
);
const feedback = feedbackNodes[questionIndex];
if (!selected) {
feedback.textContent = "Choose an answer before checking.";
feedback.className = "fcpython-quiz-feedback";
return;
}
const selectedIndex = Number(selected.value);
if (selectedIndex === question.answer_index) {
correctCount += 1;
feedback.textContent = `✅ Correct. ${question.explanation}`;
feedback.className = "fcpython-quiz-feedback is-correct";
} else {
const answer = question.options[question.answer_index];
feedback.textContent = `❌ Not yet. Correct answer: ${answer}. ${question.explanation}`;
feedback.className = "fcpython-quiz-feedback is-incorrect";
}
});
score.textContent = `Score: ${correctCount}/${quiz.questions.length}`;
});
reset.addEventListener("click", () => {
container.querySelectorAll("input[type='radio']").forEach((input) => {
input.checked = false;
});
feedbackNodes.forEach((feedback) => {
feedback.textContent = "";
feedback.className = "fcpython-quiz-feedback";
});
score.textContent = "";
});
actions.appendChild(check);
actions.appendChild(reset);
container.appendChild(actions);
container.appendChild(score);
return container;
}Scientific Python
scientific-python
Use Python’s scientific stack for arrays, simulation, plotting, symbolic math, and numerical methods.
How to use this chapter hands-on
This chapter is about Scientific Python. Do not read it like a reference manual. Use it as a sequence of short labs. For each lesson, open the Colab notebook from the button above, run Example 1, write a prediction, and then change one small part of the code.
By the end of the chapter, you should have one small artifact: a notebook, a script, a trace table, or a project note. The artifact should show one working example, one controlled variation, and one error or surprising result that you investigated calmly.
If time is short, study one lesson deeply instead of skimming all of them. A deeply understood example is one you can run again, explain in plain language, modify safely, and debug when it breaks.
Why this chapter matters
Use Python’s scientific stack for arrays, simulation, plotting, symbolic math, and numerical methods.
Lessons are now grouped by coherent learner topics. A page may contain multiple short quizzes when the page has multiple sections, so students can check one idea before moving to the next.
NoteGuiding questions
- Which lessons belong in this chapter?
- What should I review before moving on?
- How do the lesson sections build one practical skill?
Lesson path
- NumPy — Use arrays, shapes, indexing, and vectorized operations for numerical data.
- Random Simulation — Use random numbers to model uncertainty and repeated experiments.
- Matplotlib Basics — Create simple line plots and scatter plots.
- SymPy Symbolic Math — Use SymPy for algebraic expressions and exact symbolic manipulation.
- SciPy Overview — Meet scientific algorithms for statistics, optimization, signal processing, and more.
Chapter checkpoint
Use this short checkpoint before starting the chapter.