File size: 5,722 Bytes
1b8f38d 45ad2d3 1b8f38d da14dd5 45ad2d3 c0bf4e7 45ad2d3 156abc5 da14dd5 dbac21f da14dd5 156abc5 da14dd5 1b8f38d 156abc5 1b8f38d 479b25d 156abc5 1b8f38d da14dd5 1b8f38d e930e3c 1b8f38d e930e3c e5725e4 e930e3c 1b8f38d da14dd5 90865a6 180d94b e79845d 4056b9a db2c51d 4056b9a e79845d bd8e79a db2c51d bd8e79a 0b4b5fb e79845d bd8e79a db2c51d bd8e79a db2c51d e79845d bd8e79a e79845d 0b4b5fb 4056b9a 0b4b5fb bd8e79a e79845d ce648f5 22d7670 ce648f5 0b4b5fb 0b5541e 180d94b 22d7670 ce648f5 2ada91d ce648f5 0b5541e 180d94b 0b5541e 180d94b 0b5541e db2c51d 180d94b e79845d 0b5541e db2c51d 0b5541e db2c51d 0b5541e db2c51d 180d94b e930e3c 298cb2c 90865a6 156abc5 0b5541e 156abc5 90865a6 156abc5 0b5541e 156abc5 829ae92 156abc5 e930e3c 0b5541e e5725e4 156abc5 e930e3c 90865a6 da14dd5 dbac21f 94d1c9f 156abc5 dbac21f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | import os
import gradio as gr
from openai import OpenAI
import subprocess
import tempfile
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
# --- Core logic ---
def analyze_code(language, code):
error_output = ""
if language.lower() == "python":
with tempfile.NamedTemporaryFile(delete=False, suffix=".py") as tmp:
tmp.write(code.encode("utf-8"))
tmp.flush()
try:
subprocess.run(
["python3", tmp.name],
check=True,
capture_output=True,
text=True,
timeout=5,
)
except subprocess.CalledProcessError as e:
error_output = e.stderr
except Exception as e:
error_output = str(e)
else:
error_output = "Automatic execution only supported for Python. Please paste your error manually."
if not error_output.strip():
error_output = "β
No runtime error detected. Let's review for logic or syntax improvements."
return help_with_code(language, code, error_output)
def help_with_code(language, code, error):
prompt = f"""
You are a skilled coding instructor identifying skill gaps in students learning {language}.
--- CODE START ---
{code}
--- CODE END ---
--- ERROR ---
{error}
--- END ERROR ---
Your task:
1. Identify my coding skill gaps (syntax, logic, structure, or language fundamentals).
2. Explain clearly what went wrong and why.
3. Suggest one or two short, focused practice exercises to improve that specific skill.
4. Do NOT rewrite or fix the code.
"""
try:
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0.4,
)
return response.choices[0].message.content.strip()
except Exception as e:
err_msg = str(e)
# β
Handle inactive billing error cleanly
if "billing_not_active" in err_msg or "Error code: 429" in err_msg:
return (
"β οΈ Please contact an RC staff member β the billing is currently not active."
)
# Generic fallback
return "β οΈ An unexpected error occurred. Please try again later or verify your API key."
# --- Gradio UI ---
with gr.Blocks(
theme="soft",
css="""
/* === Apply theme colors immediately === */
body, .gradio-container, .dark, [data-theme="dark"] {
background-color: var(--body-background-fill) !important;
color: var(--body-text-color) !important;
transition: none !important;
}
/* === Base Theme Variables (Light Mode) === */
:root {
--body-background-fill: #ffffff;
--body-text-color: #1a1a1a;
--codebox-background: #f8f8f8;
--codebox-border: #EDEBEB;
--scrollbar-thumb: #c1c1c1;
--scrollbar-track: #f8f8f8;
}
/* π Dark Mode Theme */
:root .dark, [data-theme="dark"] {
--body-background-fill: #1e1e1f !important;
--body-text-color: #e5e5e5 !important;
--codebox-background: #2a2a2b !important;
--codebox-border: #3a3a3b !important;
--scrollbar-thumb: #555 !important;
--scrollbar-track: #2a2a2b !important;
}
/* π§± Code boxes, dropdowns, textareas unified */
#code-box,
select,
textarea,
pre,
code {
background-color: var(--codebox-background) !important;
border: 1px solid var(--codebox-border) !important;
border-radius: 6px !important;
color: var(--body-text-color) !important;
transition: none !important;
}
/* β¨ Consistent scrollbar theme */
#code-box::-webkit-scrollbar,
textarea::-webkit-scrollbar,
pre::-webkit-scrollbar {
width: 8px;
height: 8px;
}
#code-box::-webkit-scrollbar-thumb,
textarea::-webkit-scrollbar-thumb,
pre::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
border-radius: 10px;
}
#code-box::-webkit-scrollbar-track,
textarea::-webkit-scrollbar-track,
pre::-webkit-scrollbar-track {
background-color: var(--scrollbar-track);
}
/* π― Submit button */
#submit-btn {
background-color: #e40014 !important;
color: white !important;
border: none !important;
border-radius: 6px !important;
transition: background-color 0.2s ease-in-out;
margin-top: 6px !important;
width: 100%;
}
#submit-btn:hover {
background-color: #c00010 !important;
}
/* π§© Compact layout */
.gr-block, .gr-form, .gr-column, .gr-row {
gap: 4px !important;
padding: 0 !important;
margin: 0 !important;
}
.gr-markdown {
margin: 0 !important;
padding: 2px !important;
line-height: 1.4 !important;
}
/* β
Feedback area spacing */
.gr-markdown p {
margin-top: 0 !important;
margin-bottom: 4px !important;
}
/* Prevent reflow on feedback render */
.gr-column > *:not(:last-child) {
margin-bottom: 4px !important;
}
"""
) as demo:
with gr.Row(equal_height=True):
with gr.Column(scale=2):
# Removed markdown labels to reduce vertical spacing
language = gr.Dropdown(
["JavaScript", "HTML", "CSS", "Python"],
value="Python",
show_label=True,
label="Language",
)
code_input = gr.Code(
language="python",
lines=22,
show_label=True,
label="Your Code",
elem_id="code-box",
)
analyze_button = gr.Button("Submit", variant="secondary", elem_id="submit-btn")
with gr.Column(scale=1):
output = gr.Markdown("*Feedback will show here!*")
analyze_button.click(analyze_code, inputs=[language, code_input], outputs=output)
demo.launch()
|