Spaces:
Sleeping
Sleeping
import re | |
import requests | |
import nbformat | |
RAW_BASE = "https://raw.githubusercontent.com/Qiskit/textbook/main/notebooks/intro/" | |
README_URL = RAW_BASE + "README.md" | |
FALLBACK = [ | |
"what-is-quantum.ipynb", | |
"entangled-states.ipynb", | |
"superdense-coding.ipynb", | |
"teleportation.ipynb", | |
] | |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
# Internal helpers | |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
def _discover_notebooks() -> list[str]: | |
"""Scrape notebooks/intro/README.md for *.ipynb links; fallback if offline.""" | |
try: | |
md = requests.get(README_URL, timeout=10).text | |
found = re.findall(r"\(([^)]+?\.ipynb)\)", md) | |
if found: | |
return found | |
except requests.RequestException: | |
pass | |
return FALLBACK | |
def _pretty(name: str) -> str: | |
"""'superdense-coding.ipynb' β 'Superdense Coding'.""" | |
return name.replace("-", " ").replace(".ipynb", "").title() | |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
# Public API | |
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ | |
def get_theory_topics() -> dict[str, str]: | |
""" | |
Return a mapping of *friendly topic name* β *notebook filename*. | |
Example | |
------- | |
{'What Is Quantum?': 'what-is-quantum.ipynb', ...} | |
""" | |
return {_pretty(f): f for f in _discover_notebooks()} | |
def get_theory( | |
topic: str, | |
markdown_only: bool = True, | |
include_headers: bool = True, | |
) -> str: | |
""" | |
Download **one** intro notebook and return its content as text. | |
Parameters | |
---------- | |
topic | |
Accepts pretty title (βTeleportationβ), slug (βteleportationβ) | |
or exact filename (βteleportation.ipynbβ). | |
markdown_only | |
True (default) β keep only Markdown cells; | |
False β include code cells fenced as ```python. | |
include_headers | |
Prepend an H1 title for readability. | |
Raises | |
------ | |
ValueError | |
If *topic* cannot be resolved. | |
Returns | |
------- | |
str | |
Concatenated notebook text. | |
""" | |
topics = get_theory_topics() | |
# Build a lenient lookup table | |
lookup: dict[str, str] = {} | |
for pretty, fname in topics.items(): | |
slug = fname.removesuffix(".ipynb") | |
lookup[pretty.lower()] = fname | |
lookup[slug.lower()] = fname | |
lookup[fname.lower()] = fname | |
key = topic.lower() | |
if key not in lookup: | |
raise ValueError( | |
f"Unknown topic '{topic}'. " | |
f"Known: {', '.join(topics.keys())}." | |
) | |
fname = lookup[key] | |
raw_json = requests.get(RAW_BASE + fname, timeout=20).text | |
nb = nbformat.reads(raw_json, as_version=4) | |
parts: list[str] = [] | |
if include_headers: | |
parts.append(f"# {_pretty(fname)}\n") | |
for cell in nb.cells: | |
if cell.cell_type == "markdown": | |
parts.append(cell.source) | |
elif cell.cell_type == "code" and not markdown_only: | |
parts.append(f"```python\n{cell.source}\n```") | |
return "\n\n".join(parts) |