{
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;
}Lesson Path
course
Recommended path through the FreeCampus Python course.
How to use this chapter hands-on
This chapter is about the full course path. 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.
How to use this course
If you are new to programming, follow the lessons in order. If you already know some Python, use the quizzes, debugging corners, and challenges to decide where to start.
TipKey idea
Programming is not memorizing every command. Programming is learning how to break a problem into small steps, run experiments, read feedback, and improve.
Course map
1. Getting Started
Set up your learning environment and understand how Python runs before memorizing syntax.
2. Core Python
Learn the small building blocks that almost every Python program uses: values, names, decisions, and repetition.
3. Data Structures
Store, organize, search, and transform many values with the right container for the job.
4. Functions
Package useful steps behind names so code can be reused, tested, and explained.
5. Debugging
Read errors calmly, inspect state, and make small experiments instead of guessing.
6. FAQ and Common Issues
Find a familiar symptom, inspect one clue, and test a small fix without guessing.
7. Files and Data
Read, write, validate, and recover from problems when programs interact with data outside memory.
8. Projects and Environments
Organize code into files, install dependencies safely, and run programs as small projects.
9. Code Quality
Make code trustworthy with tests, style, formatting, linting, types, and automation.
10. Object-Oriented Python
Use classes when data and behavior belong together, while avoiding unnecessary complexity.
11. Advanced Python Patterns
Learn powerful Python patterns one at a time after core concepts are stable.
12. Scientific Python
Use Python’s scientific stack for arrays, simulation, plotting, symbolic math, and numerical methods.
13. Data Science
Turn questions and datasets into cleaned, analyzed, visualized, and communicated results.
14. Machine Learning and AI
Understand AI vocabulary, train simple models, evaluate them responsibly, and know where major libraries fit.
15. Capstone
Plan, build, test, document, and present a beginner-friendly Python project that integrates the course.
Lesson pattern
Lessons are intentionally cohesive, not microscopic. A topic like lists can include indexing, slicing, methods, and copying on one page because those ideas belong to one container. When a page has multiple sections, it can also include multiple OJS quizzes so students can check understanding before continuing.
Study routine for every lesson
- Read the analogy first.
- Predict what each short code example will do.
- Run it in Colab, Jupyter, or VS Code.
- Answer the section quiz.
- Review if needed before continuing.
- Change one small thing and run again.
- Explain the result in your own words.
Course checkpoint
This OJS quiz checks whether you understand how to study the course.