code-explainer / app.py
shamamanaeem03's picture
Update app.py
90a5e27 verified
import gradio as gr
import os
from groq import Groq
SYSTEM_PROMPT = """You are a professional coding teacher explaining code to a complete beginner.
When given code, respond ONLY in this exact HTML structure (no markdown, no backticks):
<div class="section" id="simple">
<h2>🧠 Simple Explanation</h2>
<ul>
[3-5 bullet points explaining what the code does in simple words]
</ul>
</div>
<div class="section" id="steps">
<h2>πŸ‘£ Step-by-Step Working</h2>
<ol>
[numbered steps of how the code runs]
</ol>
</div>
<div class="section" id="variables">
<h2>πŸ“¦ Variables & Functions</h2>
<ul>
[explain each variable and function simply]
</ul>
</div>
<div class="section" id="logic">
<h2>πŸ”„ Logic (Loops & Conditions)</h2>
<p>[explain any loops, if/else, conditions in very simple words]</p>
</div>
<div class="section" id="analogy">
<h2>🌍 Real-Life Analogy</h2>
<p>[a simple real-world comparison that a child could understand]</p>
</div>
<div class="section" id="output">
<h2>πŸ–₯️ Output</h2>
<div class="output-box">[what the code prints/returns]</div>
</div>
<div class="section" id="errors">
<h2>πŸ› Errors Found & Fixed</h2>
<p>[mention any bugs or if code is correct]</p>
</div>
<div class="section" id="improvements">
<h2>✨ Suggested Improvements</h2>
<ul>
[2-3 improvement tips]
</ul>
</div>
<div class="section" id="complexity">
<h2>⏱️ Time Complexity</h2>
<p>[explain time complexity in very simple words like "this runs once" or "this loops N times"]</p>
</div>
<div class="section" id="summary">
<h2>πŸ“ Short Summary</h2>
<p>[1-2 sentence summary of what the code does]</p>
</div>
Use very easy English. No technical jargon. Keep it short but clear."""
CSS = """
@import url('https://fonts.googleapis.com/css2?family=Syne:wght@400;600;700;800&family=DM+Mono:wght@400;500&family=DM+Sans:wght@300;400;500&display=swap');
:root {
--bg: #0a0a0f;
--surface: #12121a;
--surface2: #1e1e2e;
--border: #3a3a5c;
--accent: #a89fff;
--accent2: #ff8ec4;
--accent3: #6affb8;
--text: #e8e8f0;
--text-muted: #aaaacc;
--glow: 0 0 30px rgba(168, 159, 255, 0.2);
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body, .gradio-container {
background: var(--bg) !important;
font-family: 'DM Sans', sans-serif !important;
color: var(--text) !important;
min-height: 100vh;
}
.gradio-container {
max-width: 1100px !important;
margin: 0 auto !important;
padding: 2rem !important;
}
/* Header */
.header-block {
text-align: center;
padding: 3rem 0 2rem;
position: relative;
}
.header-block::before {
content: '';
position: absolute;
top: 0; left: 50%;
transform: translateX(-50%);
width: 300px; height: 300px;
background: radial-gradient(circle, rgba(124,106,255,0.12) 0%, transparent 70%);
pointer-events: none;
}
.app-title {
font-family: 'Syne', sans-serif !important;
font-size: 3rem !important;
font-weight: 800 !important;
background: linear-gradient(135deg, #7c6aff, #ff6a9e, #6affb8) !important;
-webkit-background-clip: text !important;
-webkit-text-fill-color: transparent !important;
background-clip: text !important;
line-height: 1.1 !important;
letter-spacing: -1px !important;
}
.app-subtitle {
color: var(--text-muted) !important;
font-size: 1.05rem !important;
margin-top: 0.6rem !important;
font-weight: 300 !important;
}
/* Input area */
.code-input textarea {
background: var(--surface) !important;
border: 1.5px solid var(--border) !important;
border-radius: 16px !important;
color: var(--text) !important;
font-family: 'DM Mono', monospace !important;
font-size: 0.9rem !important;
padding: 1.2rem !important;
transition: border-color 0.2s, box-shadow 0.2s !important;
resize: vertical !important;
}
.code-input textarea:focus {
border-color: var(--accent) !important;
box-shadow: var(--glow) !important;
outline: none !important;
}
.code-input label {
font-family: 'Syne', sans-serif !important;
font-weight: 600 !important;
color: var(--text) !important;
font-size: 0.95rem !important;
letter-spacing: 0.5px !important;
}
/* Button */
button.primary {
background: linear-gradient(135deg, var(--accent), var(--accent2)) !important;
border: none !important;
border-radius: 12px !important;
color: white !important;
font-family: 'Syne', sans-serif !important;
font-size: 1rem !important;
font-weight: 700 !important;
padding: 0.85rem 2.5rem !important;
cursor: pointer !important;
transition: transform 0.15s, box-shadow 0.15s !important;
letter-spacing: 0.5px !important;
}
button.primary:hover {
transform: translateY(-2px) !important;
box-shadow: 0 8px 25px rgba(124,106,255,0.35) !important;
}
/* Output HTML */
.output-html {
background: var(--surface) !important;
border: 1.5px solid var(--border) !important;
border-radius: 16px !important;
padding: 1.5rem !important;
}
/* Section cards rendered inside HTML output */
.section {
background: var(--surface2);
border: 1px solid var(--border);
border-radius: 14px;
padding: 1.4rem 1.6rem;
margin-bottom: 1rem;
transition: border-color 0.2s;
}
.section:hover { border-color: var(--accent); }
.section h2 {
font-family: 'Syne', sans-serif;
font-size: 1rem;
font-weight: 700;
color: var(--accent);
margin-bottom: 0.8rem;
letter-spacing: 0.3px;
}
.section ul, .section ol {
padding-left: 1.4rem;
color: #e8e8f0;
line-height: 1.8;
font-size: 0.93rem;
}
.section li {
color: #e8e8f0 !important;
margin-bottom: 0.3rem;
}
.section p {
color: #e8e8f0;
line-height: 1.7;
font-size: 0.93rem;
}
.output-box {
background: #0d0d15;
border: 1px solid var(--border);
border-left: 3px solid var(--accent3);
border-radius: 8px;
padding: 0.8rem 1rem;
font-family: 'DM Mono', monospace;
font-size: 0.88rem;
color: var(--accent3);
white-space: pre-wrap;
}
#analogy h2 { color: var(--accent3) !important; }
#output h2 { color: var(--accent3) !important; }
#summary h2 { color: var(--accent2) !important; }
#errors h2 { color: #ff9966 !important; }
/* Loading */
.generating {
text-align: center;
color: var(--text-muted);
padding: 2rem;
font-family: 'Syne', sans-serif;
}
/* Footer */
footer { display: none !important; }
"""
PLACEHOLDER = '''# Paste your code here! Example:
def greet(name):
for i in range(3):
print("Hello, " + name + "!")
greet("Alice")'''
def explain_code(code):
if not code.strip():
return "<p style='color:#8888aa; padding:1rem;'>⚠️ Please paste some code first!</p>"
try:
api_key = os.environ.get("GROQ_API_KEY")
if not api_key:
return "<p style='color:#ff6a6a;padding:1rem;'>❌ Error: GROQ_API_KEY secret is missing! Go to Space Settings β†’ Variables and Secrets β†’ Add GROQ_API_KEY</p>"
client = Groq(api_key=api_key)
response = client.chat.completions.create(
model="llama-3.3-70b-versatile",
max_tokens=2000,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": f"Explain this code:\n\n{code}"}
]
)
result = response.choices[0].message.content
# Wrap in styled container
return f"""
<style>
:root {{
--bg:#0a0a0f;--surface:#12121a;--surface2:#1e1e2e;
--border:#3a3a5c;--accent:#a89fff;--accent2:#ff8ec4;
--accent3:#6affb8;--text:#e8e8f0;--text-muted:#aaaacc;
}}
@import url('https://fonts.googleapis.com/css2?family=Syne:wght@700&family=DM+Mono&family=DM+Sans:wght@300;400&display=swap');
.section{{background:var(--surface2);border:1px solid var(--border);border-radius:14px;padding:1.4rem 1.6rem;margin-bottom:1rem;}}
.section:hover{{border-color:var(--accent);}}
.section h2{{font-family:'Syne',sans-serif;font-size:1rem;font-weight:700;color:#a89fff;margin-bottom:0.8rem;}}
.section ul,.section ol{{padding-left:1.4rem;color:#e8e8f0;line-height:1.8;font-size:0.93rem;}}
.section li{{color:#e8e8f0 !important;margin-bottom:0.3rem;}}
.section p{{color:#e8e8f0;line-height:1.7;font-size:0.93rem;}}
.output-box{{background:#0d0d15;border:1px solid var(--border);border-left:3px solid var(--accent3);border-radius:8px;padding:0.8rem 1rem;font-family:'DM Mono',monospace;font-size:0.88rem;color:var(--accent3);white-space:pre-wrap;}}
#analogy h2,#output h2{{color:var(--accent3)!important;}}
#summary h2{{color:var(--accent2)!important;}}
#errors h2{{color:#ff9966!important;}}
</style>
{result}
"""
except Exception as e:
return f"<p style='color:#ff6a6a;padding:1rem;'>❌ Error: {str(e)}</p>"
with gr.Blocks(css=CSS, title="CodeLens β€” AI Code Explainer") as demo:
gr.HTML("""
<div class="header-block">
<h1 class="app-title">CodeLens</h1>
<p class="app-subtitle">Paste any code β†’ Get a beginner-friendly explanation instantly ✨</p>
</div>
""")
with gr.Row():
with gr.Column(scale=1):
code_input = gr.Code(
label="πŸ“‹ Paste Your Code Here",
language="python",
lines=14,
elem_classes=["code-input"],
value=PLACEHOLDER
)
explain_btn = gr.Button(
"πŸ” Explain This Code",
variant="primary",
size="lg"
)
output = gr.HTML(
label="",
elem_classes=["output-html"]
)
explain_btn.click(
fn=explain_code,
inputs=[code_input],
outputs=[output]
)
gr.HTML("""
<div style="text-align:center; padding:1.5rem 0 0.5rem; color:#8888aa; font-size:0.82rem; font-family:'DM Sans',sans-serif;">
Built with ❀️ using Groq AI · CodeLens for Beginners
</div>
""")
if __name__ == "__main__":
demo.launch()