Spaces:
Sleeping
Sleeping
Ludek Matyska
commited on
Commit
Β·
eba4c06
1
Parent(s):
cc9f055
feat: get_theory tools
Browse files- app.py +30 -19
- theory_tools.py +109 -0
app.py
CHANGED
@@ -1,24 +1,35 @@
|
|
1 |
import gradio as gr
|
|
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
|
|
|
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
-
# Launch the interface
|
23 |
if __name__ == "__main__":
|
24 |
-
demo.launch(
|
|
|
1 |
import gradio as gr
|
2 |
+
from theory_tools import get_theory, get_theory_topics
|
3 |
|
4 |
+
# Get available topics for dropdown
|
5 |
+
try:
|
6 |
+
topics = get_theory_topics()
|
7 |
+
topic_choices = list(topics.keys())
|
8 |
+
except Exception as e:
|
9 |
+
topic_choices = ["Error loading topics"]
|
10 |
+
|
11 |
+
# Create the Gradio interface with tabs
|
12 |
+
with gr.Blocks(title="Quantum Circuits Learning Programme") as demo:
|
13 |
+
gr.Markdown("# Quantum Circuits Learning Programme")
|
14 |
+
gr.Markdown("Learn about quantum circuits through interactive content from the Qiskit textbook.")
|
15 |
|
16 |
+
with gr.Tabs():
|
17 |
+
with gr.TabItem("Browse Topics"):
|
18 |
+
topics_input = gr.Textbox(label="Enter query (or leave empty)", placeholder="Optional: enter a search term")
|
19 |
+
topics_output = gr.JSON(label="Available Topics")
|
20 |
+
topics_btn = gr.Button("Load Available Topics")
|
21 |
+
topics_btn.click(fn=get_theory_topics, inputs=topics_input, outputs=topics_output)
|
22 |
+
|
23 |
+
with gr.TabItem("Learn Theory"):
|
24 |
+
topic_input = gr.Textbox(
|
25 |
+
label="Enter a Quantum Topic",
|
26 |
+
placeholder="e.g., teleportation, superdense coding, what is quantum",
|
27 |
+
info="Enter the name of a quantum topic to learn about"
|
28 |
+
)
|
29 |
+
theory_output = gr.Markdown(label="Theory Content")
|
30 |
+
theory_btn = gr.Button("Get Theory Content")
|
31 |
+
theory_btn.click(fn=get_theory, inputs=topic_input, outputs=theory_output)
|
32 |
|
33 |
+
# Launch the interface
|
34 |
if __name__ == "__main__":
|
35 |
+
demo.launch()
|
theory_tools.py
ADDED
@@ -0,0 +1,109 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import re
|
2 |
+
import requests
|
3 |
+
import nbformat
|
4 |
+
|
5 |
+
RAW_BASE = "https://raw.githubusercontent.com/Qiskit/textbook/main/notebooks/intro/"
|
6 |
+
README_URL = RAW_BASE + "README.md"
|
7 |
+
FALLBACK = [
|
8 |
+
"what-is-quantum.ipynb",
|
9 |
+
"entangled-states.ipynb",
|
10 |
+
"superdense-coding.ipynb",
|
11 |
+
"teleportation.ipynb",
|
12 |
+
]
|
13 |
+
|
14 |
+
|
15 |
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
16 |
+
# Internal helpers
|
17 |
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
18 |
+
def _discover_notebooks() -> list[str]:
|
19 |
+
"""Scrape notebooks/intro/README.md for *.ipynb links; fallback if offline."""
|
20 |
+
try:
|
21 |
+
md = requests.get(README_URL, timeout=10).text
|
22 |
+
found = re.findall(r"\(([^)]+?\.ipynb)\)", md)
|
23 |
+
if found:
|
24 |
+
return found
|
25 |
+
except requests.RequestException:
|
26 |
+
pass
|
27 |
+
return FALLBACK
|
28 |
+
|
29 |
+
|
30 |
+
def _pretty(name: str) -> str:
|
31 |
+
"""'superdense-coding.ipynb' β 'Superdense Coding'."""
|
32 |
+
return name.replace("-", " ").replace(".ipynb", "").title()
|
33 |
+
|
34 |
+
|
35 |
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
36 |
+
# Public API
|
37 |
+
# ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
38 |
+
def get_theory_topics() -> dict[str, str]:
|
39 |
+
"""
|
40 |
+
Return a mapping of *friendly topic name* β *notebook filename*.
|
41 |
+
|
42 |
+
Example
|
43 |
+
-------
|
44 |
+
{'What Is Quantum?': 'what-is-quantum.ipynb', ...}
|
45 |
+
"""
|
46 |
+
return {_pretty(f): f for f in _discover_notebooks()}
|
47 |
+
|
48 |
+
|
49 |
+
def get_theory(
|
50 |
+
topic: str,
|
51 |
+
markdown_only: bool = True,
|
52 |
+
include_headers: bool = True,
|
53 |
+
) -> str:
|
54 |
+
"""
|
55 |
+
Download **one** intro notebook and return its content as text.
|
56 |
+
|
57 |
+
Parameters
|
58 |
+
----------
|
59 |
+
topic
|
60 |
+
Accepts pretty title (βTeleportationβ), slug (βteleportationβ)
|
61 |
+
or exact filename (βteleportation.ipynbβ).
|
62 |
+
markdown_only
|
63 |
+
True (default) β keep only Markdown cells;
|
64 |
+
False β include code cells fenced as ```python.
|
65 |
+
include_headers
|
66 |
+
Prepend an H1 title for readability.
|
67 |
+
|
68 |
+
Raises
|
69 |
+
------
|
70 |
+
ValueError
|
71 |
+
If *topic* cannot be resolved.
|
72 |
+
|
73 |
+
Returns
|
74 |
+
-------
|
75 |
+
str
|
76 |
+
Concatenated notebook text.
|
77 |
+
"""
|
78 |
+
topics = get_theory_topics()
|
79 |
+
|
80 |
+
# Build a lenient lookup table
|
81 |
+
lookup: dict[str, str] = {}
|
82 |
+
for pretty, fname in topics.items():
|
83 |
+
slug = fname.removesuffix(".ipynb")
|
84 |
+
lookup[pretty.lower()] = fname
|
85 |
+
lookup[slug.lower()] = fname
|
86 |
+
lookup[fname.lower()] = fname
|
87 |
+
|
88 |
+
key = topic.lower()
|
89 |
+
if key not in lookup:
|
90 |
+
raise ValueError(
|
91 |
+
f"Unknown topic '{topic}'. "
|
92 |
+
f"Known: {', '.join(topics.keys())}."
|
93 |
+
)
|
94 |
+
|
95 |
+
fname = lookup[key]
|
96 |
+
raw_json = requests.get(RAW_BASE + fname, timeout=20).text
|
97 |
+
nb = nbformat.reads(raw_json, as_version=4)
|
98 |
+
|
99 |
+
parts: list[str] = []
|
100 |
+
if include_headers:
|
101 |
+
parts.append(f"# {_pretty(fname)}\n")
|
102 |
+
|
103 |
+
for cell in nb.cells:
|
104 |
+
if cell.cell_type == "markdown":
|
105 |
+
parts.append(cell.source)
|
106 |
+
elif cell.cell_type == "code" and not markdown_only:
|
107 |
+
parts.append(f"```python\n{cell.source}\n```")
|
108 |
+
|
109 |
+
return "\n\n".join(parts)
|