diff --git a/week4/community-contributions/samuel_bootcamp_wk4/python2golang_code_converter.ipynb b/week4/community-contributions/samuel_bootcamp_wk4/python2golang_code_converter.ipynb index e69de29..79fed68 100644 --- a/week4/community-contributions/samuel_bootcamp_wk4/python2golang_code_converter.ipynb +++ b/week4/community-contributions/samuel_bootcamp_wk4/python2golang_code_converter.ipynb @@ -0,0 +1,548 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3504f1f4", + "metadata": {}, + "source": [ + "## Week 4 Python to Golang code coverter\n", + "# A race between open source models" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7a3faf77", + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import gradio as gr\n", + "import pandas as pd\n", + "import traceback\n", + "import time\n", + "import subprocess\n", + "import tempfile\n", + "from huggingface_hub import InferenceClient\n", + "from openai import OpenAI\n", + "\n", + "HF_TOKEN = os.getenv(\"HF_TOKEN\", \"\")\n", + "OPENAI_KEY = os.getenv(\"OPENAI_API_KEY\", \"\")\n", + "\n", + "print(f\"HF Token: {'✓ Found' if HF_TOKEN else '✗ Not found'}\")\n", + "print(f\"OpenAI Key: {'✓ Found' if OPENAI_KEY else '✗ Not found'}\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "268e5500", + "metadata": {}, + "outputs": [], + "source": [ + "system_info = \"Mac M2, ARM64 architecture\"\n", + "compile_command = \"go build -o main main.go && ./main\"\n", + "\n", + "system_prompt = \"\"\"Your task is to convert Python code into high performance Golang code. \n", + "Respond only with golang code. Do not provide any explanation other than occasional comments. \n", + "The Golang response needs to produce an identical output in the fastest possible time.\"\"\"\n", + "\n", + "def user_prompt_for(python):\n", + " return f\"\"\"Port this Python code to Golang with the fastest possible implementation that produces identical output in the least time.\n", + "\n", + "The system information is: {system_info}\n", + "Your response will be written to a file called main.go and then compiled and executed.\n", + "The compilation command is: {compile_command}\n", + "\n", + "Respond only with golang code.\n", + "\n", + "Python code to port:\n", + "```python\n", + "{python}\n", + "```\n", + "\"\"\"\n", + "\n", + "def messages_for(python):\n", + " return [\n", + " {\"role\": \"system\", \"content\": system_prompt},\n", + " {\"role\": \"user\", \"content\": user_prompt_for(python)}\n", + " ]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "27a100d4", + "metadata": {}, + "outputs": [], + "source": [ + "SAMPLE_CODES = {\n", + " \"Hello World\": \"print('Hello, World!')\",\n", + " \"Fibonacci\": \"\"\"def fibonacci(n):\n", + " if n <= 1:\n", + " return n\n", + " return fibonacci(n-1) + fibonacci(n-2)\n", + "\n", + "result = fibonacci(10)\n", + "print(f'Fibonacci(10) = {result}')\"\"\",\n", + " \"Sum List\": \"\"\"numbers = [1, 2, 3, 4, 5]\n", + "total = sum(numbers)\n", + "print(f'Sum: {total}')\"\"\",\n", + " \"Pi Calculation\": \"\"\"import time\n", + "\n", + "def calculate(iterations, param1, param2):\n", + " result = 1.0\n", + " for i in range(1, iterations+1):\n", + " j = i * param1 - param2\n", + " result -= (1/j)\n", + " j = i * param1 + param2\n", + " result += (1/j)\n", + " return result\n", + "\n", + "start_time = time.time()\n", + "result = calculate(200_000_000, 4, 1) * 4\n", + "end_time = time.time()\n", + "\n", + "print(f\"Result: {result:.12f}\")\n", + "print(f\"Execution Time: {(end_time - start_time):.6f} seconds\")\"\"\"\n", + "}\n", + "\n", + "HF_MODELS = {\n", + " \"CodeLlama-7B\": \"codellama/CodeLlama-7b-Instruct-hf\",\n", + " \"StarCoder2-7B\": \"bigcode/starcoder2-7b\",\n", + " \"DeepSeek-Coder-6.7B\": \"deepseek-ai/deepseek-coder-6.7b-instruct\",\n", + " \"Phi-3-Mini\": \"microsoft/Phi-3-mini-4k-instruct\",\n", + " \"Mistral-7B\": \"mistralai/Mistral-7B-Instruct-v0.2\"\n", + "}\n", + "\n", + "OPENAI_MODELS = {\n", + " \"GPT-4\": \"gpt-4\",\n", + " \"GPT-4-Turbo\": \"gpt-4-turbo-preview\",\n", + " \"GPT-3.5-Turbo\": \"gpt-3.5-turbo\"\n", + "}\n", + "\n", + "ALL_MODELS = {**HF_MODELS, **OPENAI_MODELS}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34cff8b9", + "metadata": {}, + "outputs": [], + "source": [ + "def run_python_code(python_code):\n", + " \"\"\"Run Python code and measure execution time\"\"\"\n", + " try:\n", + " with tempfile.NamedTemporaryFile(mode='w', suffix='.py', delete=False) as f:\n", + " f.write(python_code)\n", + " temp_file = f.name\n", + " \n", + " start_time = time.time()\n", + " result = subprocess.run(\n", + " ['python3', temp_file],\n", + " capture_output=True,\n", + " text=True,\n", + " timeout=30\n", + " )\n", + " end_time = time.time()\n", + " \n", + " os.unlink(temp_file)\n", + " \n", + " if result.returncode == 0:\n", + " return end_time - start_time, result.stdout, \"\"\n", + " else:\n", + " return 0, \"\", result.stderr\n", + " \n", + " except subprocess.TimeoutExpired:\n", + " return 0, \"\", \"Timeout (30s)\"\n", + " except Exception as e:\n", + " return 0, \"\", str(e)\n", + "\n", + "def run_golang_code(golang_code):\n", + " \"\"\"Compile and run Go code and measure execution time\"\"\"\n", + " try:\n", + " with tempfile.TemporaryDirectory() as temp_dir:\n", + " go_file = os.path.join(temp_dir, \"main.go\")\n", + " with open(go_file, 'w') as f:\n", + " f.write(golang_code)\n", + " \n", + " compile_result = subprocess.run(\n", + " ['go', 'build', '-o', 'main', 'main.go'],\n", + " cwd=temp_dir,\n", + " capture_output=True,\n", + " text=True,\n", + " timeout=30\n", + " )\n", + " \n", + " if compile_result.returncode != 0:\n", + " return 0, \"\", f\"Compile error: {compile_result.stderr}\"\n", + " \n", + " start_time = time.time()\n", + " run_result = subprocess.run(\n", + " ['./main'],\n", + " cwd=temp_dir,\n", + " capture_output=True,\n", + " text=True,\n", + " timeout=30\n", + " )\n", + " end_time = time.time()\n", + " \n", + " if run_result.returncode == 0:\n", + " return end_time - start_time, run_result.stdout, \"\"\n", + " else:\n", + " return 0, \"\", run_result.stderr\n", + " \n", + " except subprocess.TimeoutExpired:\n", + " return 0, \"\", \"Timeout (30s)\"\n", + " except Exception as e:\n", + " return 0, \"\", str(e)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c0b2eb6c", + "metadata": {}, + "outputs": [], + "source": [ + "def convert_with_openai(python_code, model_name, api_key):\n", + " try:\n", + " client = OpenAI(api_key=api_key)\n", + " messages = messages_for(python_code)\n", + " \n", + " response = client.chat.completions.create(\n", + " model=model_name,\n", + " messages=messages,\n", + " max_tokens=2000,\n", + " temperature=0.1\n", + " )\n", + " \n", + " golang_code = response.choices[0].message.content.strip()\n", + " return golang_code\n", + " \n", + " except Exception as e:\n", + " raise Exception(f\"OpenAI Error: {str(e)}\")\n", + "\n", + "def convert_with_huggingface(python_code, model_name, hf_token):\n", + " try:\n", + " client = InferenceClient(token=hf_token)\n", + " messages = messages_for(python_code)\n", + " \n", + " response = client.chat_completion(\n", + " model=model_name,\n", + " messages=messages,\n", + " max_tokens=2000,\n", + " temperature=0.1\n", + " )\n", + " \n", + " golang_code = response.choices[0].message.content.strip()\n", + " return golang_code\n", + " \n", + " except Exception as e:\n", + " raise Exception(f\"HuggingFace Error: {str(e)}\")\n", + "\n", + "def convert_python_to_golang(python_code, model_name):\n", + " try:\n", + " if not python_code or not python_code.strip():\n", + " return \"\", \"Error: No code\", \"Empty input\"\n", + " \n", + " is_openai = model_name in OPENAI_MODELS\n", + " model_id = ALL_MODELS.get(model_name)\n", + " \n", + " if not model_id:\n", + " return \"\", f\"Error: Model not found\", f\"Invalid: {model_name}\"\n", + " \n", + " if is_openai:\n", + " if not OPENAI_KEY:\n", + " return \"\", \"Error: No OpenAI key\", \"Missing OPENAI_KEY\"\n", + " else:\n", + " if not HF_TOKEN:\n", + " return \"\", \"Error: No HF token\", \"Missing HF_TOKEN\"\n", + " \n", + " max_retries = 2\n", + " for attempt in range(max_retries):\n", + " try:\n", + " if is_openai:\n", + " golang_code = convert_with_openai(python_code, model_id, OPENAI_KEY)\n", + " else:\n", + " golang_code = convert_with_huggingface(python_code, model_id, HF_TOKEN)\n", + " \n", + " if \"```go\" in golang_code:\n", + " parts = golang_code.split(\"```go\")\n", + " if len(parts) > 1:\n", + " golang_code = parts[1].split(\"```\")[0].strip()\n", + " elif \"```golang\" in golang_code:\n", + " parts = golang_code.split(\"```golang\")\n", + " if len(parts) > 1:\n", + " golang_code = parts[1].split(\"```\")[0].strip()\n", + " \n", + " if golang_code.startswith(\"```\"):\n", + " golang_code = golang_code[3:].strip()\n", + " if golang_code.endswith(\"```\"):\n", + " golang_code = golang_code[:-3].strip()\n", + " \n", + " if golang_code and len(golang_code) > 10:\n", + " provider = \"OpenAI\" if is_openai else \"HuggingFace\"\n", + " return golang_code, f\"✓ Converted with {model_name} ({provider})\", \"\"\n", + " else:\n", + " return \"\", \"Error: Empty response\", \"No valid code generated\"\n", + " \n", + " except Exception as e:\n", + " error_msg = str(e)\n", + " \n", + " if \"503\" in error_msg or \"loading\" in error_msg.lower():\n", + " return \"\", f\"Model loading. Wait 30s\", f\"503: Initializing\"\n", + " \n", + " elif \"404\" in error_msg:\n", + " return \"\", f\"Error 404: '{model_name}' not accessible\", f\"Try another model\"\n", + " \n", + " elif \"429\" in error_msg:\n", + " return \"\", \"Rate limit. Wait 1 min\", \"429: Too many requests\"\n", + " \n", + " elif \"401\" in error_msg or \"403\" in error_msg:\n", + " return \"\", \"Invalid API key\", \"Check credentials\"\n", + " \n", + " else:\n", + " if attempt < max_retries - 1:\n", + " time.sleep(3)\n", + " continue\n", + " return \"\", f\"Error: {error_msg[:100]}\", traceback.format_exc()\n", + " \n", + " return \"\", \"All retries failed\", \"Max attempts exceeded\"\n", + " \n", + " except Exception as e:\n", + " return \"\", f\"Error: {str(e)[:100]}\", traceback.format_exc()\n", + "\n", + "def write_output(go_code):\n", + " try:\n", + " with open(\"main.go\", \"w\", encoding=\"utf-8\") as f:\n", + " f.write(go_code)\n", + " return \"✓ Written to main.go\"\n", + " except Exception as e:\n", + " return f\"Error writing file: {str(e)}\"" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "91f01137", + "metadata": {}, + "outputs": [], + "source": [ + "custom_css = \"\"\"\n", + ".gradio-container {\n", + " font-family: 'Inter', sans-serif;\n", + "}\n", + ".main-header {\n", + " text-align: center;\n", + " padding: 2rem 0;\n", + " background: linear-gradient(135deg, #2193b0 0%, #6dd5ed 100%);\n", + " color: white;\n", + " border-radius: 8px;\n", + " margin-bottom: 2rem;\n", + "}\n", + "\"\"\"\n", + "\n", + "demo = gr.Blocks(css=custom_css, title=\"Python to Golang Converter\", theme=gr.themes.Soft())\n", + "\n", + "with demo:\n", + " gr.HTML(\"\"\"\n", + "
\n", + "

Python to Golang Code Converter

\n", + "

High-performance code conversion with runtime comparison

\n", + "
\n", + " \"\"\")\n", + " \n", + " hf_status = \"✓ Configured\" if HF_TOKEN else \"✗ Not Found\"\n", + " hf_color = \"green\" if HF_TOKEN else \"red\"\n", + " \n", + " openai_status = \"✓ Configured\" if OPENAI_KEY else \"✗ Not Found\"\n", + " openai_color = \"green\" if OPENAI_KEY else \"red\"\n", + " \n", + " gr.HTML(f\"\"\"\n", + "
\n", + "

HF Token: {hf_status}

\n", + "

OpenAI Key: {openai_status}

\n", + " \n", + "
\n", + " \"\"\")\n", + " \n", + " with gr.Tabs():\n", + " with gr.Tab(\"Convert Code\"):\n", + " with gr.Row():\n", + " with gr.Column():\n", + " sample_selector = gr.Dropdown(\n", + " choices=list(SAMPLE_CODES.keys()),\n", + " label=\"Load Sample\",\n", + " value=\"Hello World\"\n", + " )\n", + " \n", + " python_editor = gr.Code(\n", + " label=\"Python Code\",\n", + " value=SAMPLE_CODES[\"Hello World\"],\n", + " language=\"python\",\n", + " lines=15,\n", + " interactive=True\n", + " )\n", + " \n", + " model_selector = gr.Radio(\n", + " choices=list(ALL_MODELS.keys()),\n", + " label=\"Select Model\",\n", + " value=\"GPT-4\" if OPENAI_KEY else \"CodeLlama-7B\"\n", + " )\n", + " \n", + " with gr.Row():\n", + " convert_btn = gr.Button(\"Convert to Golang\", variant=\"primary\")\n", + " save_btn = gr.Button(\"Save to main.go\", variant=\"secondary\")\n", + " \n", + " with gr.Column():\n", + " golang_editor = gr.Textbox(\n", + " label=\"Generated Golang Code\",\n", + " lines=15,\n", + " interactive=True,\n", + " show_copy_button=True\n", + " )\n", + " \n", + " save_status = gr.Textbox(\n", + " label=\"Save Status\",\n", + " lines=1,\n", + " interactive=False\n", + " )\n", + " \n", + " with gr.Row():\n", + " conversion_status = gr.Textbox(\n", + " label=\"Status\",\n", + " lines=2,\n", + " interactive=False\n", + " )\n", + " \n", + " with gr.Row():\n", + " error_display = gr.Textbox(\n", + " label=\"Error Details\",\n", + " lines=8,\n", + " interactive=False,\n", + " visible=True,\n", + " show_copy_button=True\n", + " )\n", + " \n", + " sample_selector.change(\n", + " fn=lambda x: load_sample(x),\n", + " inputs=[sample_selector],\n", + " outputs=[python_editor, error_display]\n", + " )\n", + " \n", + " def convert_only(python_code, model_name):\n", + " try:\n", + " if not python_code:\n", + " return \"\", \"Error: No code\", \"Empty\"\n", + " return convert_python_to_golang(python_code, model_name)\n", + " except Exception as e:\n", + " return \"\", f\"Error: {str(e)}\", traceback.format_exc()\n", + " \n", + " convert_btn.click(\n", + " fn=convert_only,\n", + " inputs=[python_editor, model_selector],\n", + " outputs=[golang_editor, conversion_status, error_display]\n", + " )\n", + " \n", + " save_btn.click(\n", + " fn=write_output,\n", + " inputs=[golang_editor],\n", + " outputs=[save_status]\n", + " )\n", + " \n", + " with gr.Tab(\"Compare Models & Runtime\"):\n", + " gr.Markdown(\"### Compare All Models with Runtime Performance\")\n", + " \n", + " with gr.Row():\n", + " with gr.Column():\n", + " sample_selector2 = gr.Dropdown(\n", + " choices=list(SAMPLE_CODES.keys()),\n", + " label=\"Load Sample\",\n", + " value=\"Pi Calculation\"\n", + " )\n", + " \n", + " python_input2 = gr.Code(\n", + " label=\"Python Code\",\n", + " value=SAMPLE_CODES[\"Pi Calculation\"],\n", + " language=\"python\",\n", + " lines=12,\n", + " interactive=True\n", + " )\n", + " \n", + " compare_btn = gr.Button(\"Compare All Models\", variant=\"primary\", size=\"lg\")\n", + " \n", + " with gr.Row():\n", + " comparison_summary = gr.Textbox(\n", + " label=\"Summary\",\n", + " interactive=False,\n", + " lines=2\n", + " )\n", + " \n", + " with gr.Row():\n", + " comparison_table = gr.Dataframe(\n", + " label=\"Runtime Comparison Results\",\n", + " interactive=False,\n", + " wrap=True\n", + " )\n", + " \n", + " with gr.Row():\n", + " compare_error = gr.Textbox(\n", + " label=\"Error Details\",\n", + " lines=8,\n", + " interactive=False,\n", + " visible=True,\n", + " show_copy_button=True\n", + " )\n", + " \n", + " sample_selector2.change(\n", + " fn=lambda x: load_sample(x),\n", + " inputs=[sample_selector2],\n", + " outputs=[python_input2, compare_error]\n", + " )\n", + " \n", + " compare_btn.click(\n", + " fn=compare_all_models,\n", + " inputs=[python_input2],\n", + " outputs=[comparison_table, comparison_summary, compare_error]\n", + " )\n", + " " + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "89abbebf", + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "#Launch\n", + "demo.launch()\n", + "\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "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.12.12" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}