from __future__ import annotations from dataclasses import dataclass from pathlib import Path from .config import project_root from .curriculum import load_curriculum BUNDLE_ORDER = ("lecture", "lab", "problems", "studio") LEGACY_SINGLE_NOTEBOOKS = ( "00_circuit_literacy.ipynb", "01_statevectors.ipynb", "02_measurement_and_counts.ipynb", "03_transpilation_and_backend_reality.ipynb", "04_noise_and_robustness.ipynb", "05_design_patterns_and_subcircuits.ipynb", "06_reversible_logic_and_oracles.ipynb", "07_synthesis_and_parametric_design.ipynb", "08_hardware_aware_design_studio.ipynb", "09_verification_and_noise_debugging.ipynb", "10_capstone_circuit_design_review.ipynb", ) @dataclass(frozen=True) class CourseStep: identifier: str title: str path: str stage: str notebook_kind: str required: bool = True @property def absolute_path(self) -> Path: return project_root() / self.path def notebooks_root() -> Path: return project_root() / "notebooks" def entry_notebook_path() -> Path: return notebooks_root() / "START_HERE.ipynb" def completion_notebook_path() -> Path: return notebooks_root() / "COURSE_COMPLETE.ipynb" def legacy_archive_dir() -> Path: return notebooks_root() / ".legacy_single_notebook_path" def visible_notebook_root_names() -> tuple[str, ...]: return ( "START_HERE.ipynb", "COURSE_BLUEPRINT.ipynb", "COURSE_COMPLETE.ipynb", "foundations", "qiskit_engineering", "algorithms", "professional", ) def canonical_course_steps() -> tuple[CourseStep, ...]: curriculum = load_curriculum() steps = [ CourseStep( identifier="entry-start-here", title="Start Here", path="notebooks/START_HERE.ipynb", stage="entry", notebook_kind="entry", ) ] for module in curriculum.modules: if module.identifier == "00-course-blueprint": steps.append( CourseStep( identifier=module.identifier, title=module.title, path=module.notebook, stage=module.stage, notebook_kind="orientation", ) ) continue if module.status != "ready": continue ready_bundle = {notebook.kind: notebook for notebook in module.ready_bundle_notebooks} for kind in BUNDLE_ORDER: notebook = ready_bundle.get(kind) if notebook is None: continue steps.append( CourseStep( identifier=f"{module.identifier}-{kind}", title=notebook.title, path=notebook.path, stage=module.stage, notebook_kind=kind, ) ) steps.append( CourseStep( identifier="course-complete", title="Course Complete", path="notebooks/COURSE_COMPLETE.ipynb", stage="completion", notebook_kind="completion", ) ) return tuple(steps)