A free, browser-based Python and data analysis course — no installs required until you're ready to graduate to the real thing.
- Section 1: Python 101 (5 weeks) — fundamentals, with a Normal track and a Hard track (build a tiny language model from scratch, pure Python, deliberately no numpy).
- Section 2: Pandas & Data Analysis (5 weeks) — pandas basics reproducing a Kaggle-style notebook, with a Hard track doing a full exploratory data analysis project with visualizations.
- Real-World Projects — install Python locally for real with
uvand build something the in-browser playground never could. New projects are added whenever a trending tool or framework is worth a hands-on write-up (e.g. building an AI agent with LangChain'sdeepagents, fine-tuning a small LLM with Unsloth) — browsable any time, not gated behind finishing the course.
Run entirely in the browser via self-hosted JupyterLite: a lightweight Python console (Python 101) and a full notebook (Data Analysis), both powered by Pyodide — click the floating button on any page to start coding immediately, no account and no local install needed until you try one of the real-world projects. Since it's self-hosted (not a third-party embed), it also works offline once you've visited a page. The site itself is installable (a real PWA) — a homepage button offers "Install the course app" on supported browsers.
See plan/ for the full design plan and rationale behind every major decision.
| Homepage | Lesson + playground | Progress & badges | Mobile |
|---|---|---|---|
![]() |
![]() |
![]() |
![]() |
By the end of the course, a student can:
- Write Python programs using variables, control flow, data structures (lists, dicts, tuples, sets), and functions — without relying on classes or external libraries.
- Explain, from first principles, how a simple language model predicts text (tokenization → frequency counts → conditional probability → weighted sampling) by building one from scratch in pure Python (Hard track).
- Load, clean, filter, group, and aggregate real tabular data with pandas, and explain why vectorized tools exist by having personally measured pure Python's performance limits first.
- Run a complete, honest exploratory data analysis project — framing questions before charting, visualizing distributions and relationships appropriately, and stating a finding's confidence and caveats rather than overclaiming causation (Hard track).
- Install Python locally, manage a project with
uv, and build a real project outside the browser playground (Real-World Projects — e.g. a minimal tool-calling AI agent, handling an API key as a secret).
-
Math-first framing. The audience is math/data-analysis students, so new concepts are introduced in the notation they already know — a
forloop via summation notation before syntax, a function as$f(x)$ beforedef, list comprehensions via set-builder notation — before showing the Python code. - Build, don't just read. Both Hard tracks are project-based: a tiny language model built from nothing but the standard library, and a full EDA report on a real-shaped dataset. Struggling with plain Python's speed limits in Week 5 of Python 101 is the intentional setup for why pandas exists in Section 2.
- Challenge + Socratic pattern, every week. Each lesson pairs 🧩 Challenges (a concrete task with a collapsible answer you can self-check) with 🤔 Socratic Questions (open-ended, no answer provided — designed to make you reason about edge cases and why, not just how).
- Optional gamification, not required motivation. Badges, unlock toasts, and quiz-gated bonus content (try/except, classes) are all opt-in — a Classical mode renders the exact same underlying progress as a plain checklist, and switching between modes any time never loses data.
- Honest, not hyped. The EDA track explicitly teaches correlation-vs-causation and chart-honesty practices (truncated axes, cherry-picked ranges) as core material, not a footnote — and the completion certificate is labeled a lightweight spot-check, not a verifiable credential, because that's actually true of a backend-free static site.
- Zero-install first, real install as a reward. Every core week runs in-browser (JupyterLite via Pyodide). Installing Python for real is saved for the real-world projects, once fundamentals are solid enough to make that step feel like graduation rather than a chore.
npm install
npm start # local dev server
npm run build # production build
npm run serve # preview the production build
npm run typecheck # TypeScript check
npm run test:e2e # Playwright smoke tests (run npm run build && npm run serve first, or let it start its own server)The Data Analysis playground (JupyterLite) is built separately with uv:
cd jupyterlite-config
uv run --with jupyterlite-core --with jupyterlite-pyodide-kernel --with jupyterlab_server \
jupyter lite build --config jupyter_lite_config.jsonThis step runs automatically in CI (see .github/workflows/deploy.yml) and its output is merged into the deployed site under /lite/.
The badge above opens a ready-to-go GitHub Codespace (Node + Python + uv preinstalled, via .devcontainer/devcontainer.json) — no local setup needed to start contributing.
examples/ai-agent/ is a real, runnable copy of the agent built in the Build an AI Agent project — see its own README for how to run it (locally with uv run python agent.py, or directly in Codespaces). Each project gets its own examples/<slug>/ folder.
Most projects also ship a notebook.ipynb alongside their example code, with one-click Colab/Kaggle/Binder badges on the project's own page ("Where to run this") — a lower-setup way to try a project before committing to a local uv install. The root-level requirements.txt pre-installs the packages these notebooks need so MyBinder launches build a shared, cached environment instead of reinstalling from scratch every time.
examples/finetune-llm-unsloth/ is the local companion to the Fine-tune a Small Language Model project — dataset prep and local inference scripts; the fine-tuning step itself runs on a free Colab/Kaggle GPU notebook, linked from the project.
examples/rag-notes/ is the companion to the Build a RAG App project — local embeddings with sentence-transformers, a NumPy similarity search, and a free-tier LLM call for the final answer.
examples/mcp-server/ is the companion to the Build an MCP Server project — a FastMCP server exposing two tools, ready to connect to Claude Desktop or another MCP client.
examples/scrape-analyze/ is the companion to the Scrape and Analyze a Website project — scrapes a real, scraping-friendly site with requests/BeautifulSoup, then cleans and charts the results with pandas/matplotlib. No API key needed.
examples/ml-classifier/ is the companion to the Train an ML Classifier project — trains and compares two scikit-learn classifiers on the course's own Titanic dataset.
examples/student-projects/ is a gallery of real-world projects students have built — its README walks complete git beginners through forking, branching, and opening a PR to add their own.
Every change — a lesson, a component, a bug fix, a translation — goes through the same flow:
- Open an issue describing the change, labeled by type (
type:feature,type:bug,type:content,type:infra,type:i18n) and area (area:python-101,area:data-analysis,area:playground,area:gamification,area:design). - Branch off
main(issue-<number>-<short-slug>) and do the work there. - Open a PR referencing the issue (
Closes #N), withnpm run build(andnpm run test:e2efor anything touching interactive components) passing. - CI runs automatically on the PR — typecheck, build, and the Playwright smoke suite.
- Once checks pass, the PR merges into
mainand the deploy workflow publishes the update.
Found a typo or a broken example while going through a lesson? Every doc page has an "Edit this page" link (bottom of the page) that opens a PR directly against that file — the fastest way to fix something small.
Ways to contribute:
- Content: write or improve a week's lesson, challenges, or socratic questions — see
plan/content-pattern.mdandplan/content-style-guide.mdfor the expected structure and tone. - Translations: lesson content and UI chrome are fully translated for Arabic, Spanish, and French (see
i18n/) — atype:i18nPR fixing or improving an existing translation is welcome. - Components/infra: bug fixes, accessibility improvements, and performance work on the playground, gamification, or sharing features.
Please don't open a PR without a linked issue first for anything non-trivial — it avoids duplicated or conflicting work.
Code is MIT-licensed (see LICENSE); course content is additionally available under CC-BY 4.0. Third-party datasets and tools are credited on the site's Credits page.
Created by Abderrahim Adrabi.



