Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion community-contributions/JonasThamane

This file was deleted.

227 changes: 227 additions & 0 deletions community-contributions/JonasThamane.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "d006b2ea-9dfe-49c7-88a9-a5a0775185fd",
"metadata": {},
"source": [
"# Additional End of week Exercise - week 2\n",
"\n",
"Now use everything you've learned from Week 2 to build a full prototype for the technical question/answerer you built in Week 1 Exercise.\n",
"\n",
"This should include a Gradio UI, streaming, use of the system prompt to add expertise, and the ability to switch between models. Bonus points if you can demonstrate use of a tool!\n",
"\n",
"If you feel bold, see if you can add audio input so you can talk to it, and have it respond with audio. ChatGPT or Claude can help you, or email me if you have questions.\n",
"\n",
"I will publish a full solution here soon - unless someone beats me to it...\n",
"\n",
"There are so many commercial applications for this, from a language tutor, to a company onboarding solution, to a companion AI to a course (like this one!) I can't wait to see your results."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a07e7793-b8f5-44f4-aded-5562f633271a",
"metadata": {},
"outputs": [],
"source": [
"\n",
"import ast\n",
"\n",
"\n",
"def analyze_python_code(code: str) -> str:\n",
" \"\"\"\n",
" Analyze Python code structure using AST.\n",
" Returns a summary of node types used.\n",
" \"\"\"\n",
"\n",
" try:\n",
" tree = ast.parse(code)\n",
" node_types = {type(node).__name__ for node in ast.walk(tree)}\n",
" return f\"AST Node Types Found:\\n{sorted(node_types)}\"\n",
" except Exception as e:\n",
" return f\"Error analyzing code: {e}\"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ab621326",
"metadata": {},
"outputs": [],
"source": [
"\n",
"\n",
"from openai import OpenAI\n",
"from tools import analyze_python_code\n",
"import json\n",
"\n",
"\n",
"SYSTEM_PROMPT = \"\"\"\n",
"You are a senior software engineer and technical tutor.\n",
"Explain concepts clearly and deeply.\n",
"When appropriate, suggest edge cases and performance considerations.\n",
"If the user provides Python code, you may call the code analysis tool.\n",
"\"\"\"\n",
"\n",
"\n",
"class TechnicalTutor:\n",
"\n",
" def __init__(self, provider=\"openai\", model=\"gpt-5-nano\"):\n",
" self.provider = provider\n",
" self.model = model\n",
"\n",
" if provider == \"openai\":\n",
" self.client = OpenAI()\n",
"\n",
" elif provider == \"ollama\":\n",
" self.client = OpenAI(\n",
" base_url=\"http://localhost:11434/v1\",\n",
" api_key=\"ollama\"\n",
" )\n",
" else:\n",
" raise ValueError(\"Provider must be 'openai' or 'ollama'.\")\n",
"\n",
" def ask(self, question):\n",
"\n",
" messages = [\n",
" {\"role\": \"system\", \"content\": SYSTEM_PROMPT},\n",
" {\"role\": \"user\", \"content\": question}\n",
" ]\n",
"\n",
" stream = self.client.chat.completions.create(\n",
" model=self.model,\n",
" messages=messages,\n",
" stream=True\n",
" )\n",
"\n",
" full_response = \"\"\n",
"\n",
" for chunk in stream:\n",
" delta = chunk.choices[0].delta.content\n",
" if delta:\n",
" full_response += delta\n",
" yield full_response\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "37b6b739",
"metadata": {},
"outputs": [],
"source": [
"\n",
"\n",
"import gradio as gr\n",
"from tutor import TechnicalTutor\n",
"\n",
"\n",
"def chat_interface(message, provider, model):\n",
" tutor = TechnicalTutor(provider=provider, model=model)\n",
"\n",
" for partial in tutor.ask(message):\n",
" yield partial\n",
"\n",
"\n",
"with gr.Blocks() as demo:\n",
"\n",
" gr.Markdown(\"# 🧠 Technical Tutor Prototype\")\n",
"\n",
" with gr.Row():\n",
" provider = gr.Dropdown(\n",
" choices=[\"openai\", \"ollama\"],\n",
" value=\"openai\",\n",
" label=\"Provider\"\n",
" )\n",
"\n",
" model = gr.Textbox(\n",
" value=\"gpt-5-nano\",\n",
" label=\"Model Name\"\n",
" )\n",
"\n",
" chatbot = gr.Chatbot()\n",
" msg = gr.Textbox(label=\"Ask a technical question\")\n",
"\n",
" def respond(message, chat_history, provider, model):\n",
" tutor = TechnicalTutor(provider=provider, model=model)\n",
" chat_history = chat_history or []\n",
"\n",
" response = \"\"\n",
" for partial in tutor.ask(message):\n",
" response = partial\n",
" yield \"\", chat_history + [(message, response)]\n",
"\n",
" msg.submit(\n",
" respond,\n",
" [msg, chatbot, provider, model],\n",
" [msg, chatbot],\n",
" )\n",
"\n",
"demo.launch()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "fc27d0c7",
"metadata": {},
"outputs": [],
"source": [
"audio_input = gr.Audio(type=\"filepath\")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c7250b37",
"metadata": {},
"outputs": [],
"source": [
"import whisper\n",
"\n",
"model_whisper = whisper.load_model(\"base\")\n",
"\n",
"def transcribe(audio_path):\n",
" result = model_whisper.transcribe(audio_path)\n",
" return result[\"text\"]\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cf9e9e6c",
"metadata": {},
"outputs": [],
"source": [
"import pyttsx3\n",
"\n",
"engine = pyttsx3.init()\n",
"engine.save_to_file(response, \"response.mp3\")\n",
"engine.runAndWait()\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}