Ludek Matyska commited on
Commit
eba4c06
Β·
1 Parent(s): cc9f055

feat: get_theory tools

Browse files
Files changed (2) hide show
  1. app.py +30 -19
  2. theory_tools.py +109 -0
app.py CHANGED
@@ -1,24 +1,35 @@
1
  import gradio as gr
 
2
 
3
- def get_theory(topic: str) -> dict:
4
- """
5
- This function is a placeholder for the actual logic that would analyze the input text
6
- and return relevant information about quantum circuits.
7
- """
8
- return {
9
- "message": "This is a placeholder response. Implement your logic here.",
10
- "status": "success"
11
- }
 
 
12
 
13
- # Create the Gradio interface
14
- demo = gr.Interface(
15
- fn=get_theory,
16
- inputs=gr.Textbox(placeholder="Enter text to analyze..."),
17
- outputs=gr.JSON(),
18
- title="Quantum circuits learning programme",
19
- description="Learn about quantum circuits through this interactive chatbot.",
20
- )
 
 
 
 
 
 
 
 
21
 
22
- # Launch the interface and MCP server
23
  if __name__ == "__main__":
24
- demo.launch(mcp_server=True)
 
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)