tanjinadnanabir's picture
Create app.py
1c2e2cf verified
import gradio as gr
import requests
import json
import os
import re
# API Configuration
GROQ_API_KEY = os.environ.get("GROQ_API_KEY", "")
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "")
# Problem themes and topics
THEMES = {
"๐ŸŽฎ Gaming": ["video games", "esports", "streaming", "game development"],
"โšฝ Sports": ["soccer", "basketball", "olympics", "skateboarding"],
"๐Ÿš€ Space": ["astronauts", "planets", "rockets", "aliens"],
"๐Ÿ• Food": ["pizza party", "baking", "restaurant", "food truck"],
"๐ŸŽต Music": ["concert", "band", "playlist", "music festival"],
"๐Ÿพ Animals": ["zoo", "pets", "wildlife", "ocean creatures"],
"๐Ÿ’ป Tech": ["coding", "robots", "apps", "social media"],
"๐ŸŽจ Art": ["painting", "museum", "crafts", "design"],
}
GRADE_LEVELS = {
"Elementary (1-5)": "simple addition, subtraction, multiplication, division",
"Middle School (6-8)": "fractions, decimals, percentages, basic algebra",
"High School (9-12)": "algebra, geometry, trigonometry, basic calculus",
"College+": "advanced calculus, linear algebra, differential equations"
}
def call_groq_api(prompt: str):
"""Call Groq API"""
if not GROQ_API_KEY:
return None
url = "https://api.groq.com/openai/v1/chat/completions"
headers = {
"Authorization": f"Bearer {GROQ_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "llama-3.3-70b-versatile",
"messages": [{"role": "user", "content": prompt}],
"temperature": 0.7,
"max_tokens": 1500
}
try:
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status()
return response.json()["choices"][0]["message"]["content"]
except Exception as e:
print(f"Groq error: {e}")
return None
def call_gemini_api(prompt: str):
"""Fallback to Gemini"""
if not GEMINI_API_KEY:
return None
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash-exp:generateContent?key={GEMINI_API_KEY}"
payload = {
"contents": [{"parts": [{"text": prompt}]}],
"generationConfig": {"temperature": 0.7, "maxOutputTokens": 1500}
}
try:
response = requests.post(url, json=payload, timeout=30)
response.raise_for_status()
return response.json()["candidates"][0]["content"]["parts"][0]["text"]
except Exception as e:
print(f"Gemini error: {e}")
return None
def generate_problem(theme: str, grade: str, custom_topic: str = ""):
"""Generate a story problem"""
topic = custom_topic if custom_topic else THEMES.get(theme, ["general math"])[0]
math_level = GRADE_LEVELS.get(grade, "basic arithmetic")
prompt = f"""Create an engaging math story problem for {grade} students.
Theme: {topic}
Math concepts: {math_level}
Requirements:
1. Write a fun, relatable story (2-3 sentences)
2. Include specific numbers that make sense
3. Ask 2-3 questions of increasing difficulty
4. Make it realistic and age-appropriate
5. Use emojis to make it engaging
Format your response as:
TITLE: [Catchy title with emoji]
STORY: [The scenario]
QUESTIONS:
1. [Question 1 - easiest]
2. [Question 2 - medium]
3. [Question 3 - hardest]
Example for reference:
TITLE: ๐ŸŽฎ The Streaming Marathon
STORY: Alex is streaming a gaming marathon to raise money for charity. They stream for 6 hours on Saturday and 4 hours on Sunday. Their average viewership is 250 people per hour, and each viewer donates $0.50 per hour watched.
QUESTIONS:
1. How many total hours did Alex stream?
2. How many total viewer-hours did they get?
3. How much money did they raise for charity?"""
response = call_groq_api(prompt) or call_gemini_api(prompt)
if not response:
return "โŒ **Error**: Please add GROQ_API_KEY or GEMINI_API_KEY in Space settings.", ""
return format_problem_html(response), response
def solve_problem(problem_text: str):
"""Solve a given problem with step-by-step explanation"""
prompt = f"""Solve this math problem with detailed step-by-step explanations.
Problem:
{problem_text}
Provide:
1. A clear breakdown of what's being asked
2. Step-by-step solution for each question
3. Visual aids (use ASCII art, diagrams if helpful)
4. Final answers clearly marked
5. A "Check your work" tip
Format with markdown for readability. Use emojis to make it engaging."""
response = call_groq_api(prompt) or call_gemini_api(prompt)
if not response:
return "โŒ **Error**: Please add API key in Space settings."
return format_solution_html(response)
def format_problem_html(text: str):
"""Format problem in nice HTML"""
html = f"""
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
padding: 30px; border-radius: 15px; color: white; font-family: 'Segoe UI', sans-serif;">
<div style="background: rgba(255,255,255,0.15); backdrop-filter: blur(10px);
padding: 25px; border-radius: 12px; margin-bottom: 20px;">
<pre style="color: white; font-size: 16px; line-height: 1.8; white-space: pre-wrap; font-family: inherit;">
{text}
</pre>
</div>
<div style="text-align: center; margin-top: 15px; color: rgba(255,255,255,0.8); font-size: 14px;">
โœจ Scroll down to see the solution! โœจ
</div>
</div>
"""
return html
def format_solution_html(text: str):
"""Format solution in nice HTML"""
html = f"""
<div style="background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%);
padding: 30px; border-radius: 15px; color: white; font-family: 'Segoe UI', sans-serif;">
<div style="background: rgba(255,255,255,0.15); backdrop-filter: blur(10px);
padding: 25px; border-radius: 12px;">
<h2 style="margin-top: 0; color: white;">๐Ÿ“ Step-by-Step Solution</h2>
<div style="color: white; font-size: 15px; line-height: 1.8;">
{text.replace(chr(10), '<br>')}
</div>
</div>
</div>
"""
return html
# Gradio Interface
with gr.Blocks(
theme=gr.themes.Soft(),
css="""
.gradio-container {max-width: 900px !important;}
.generate-btn {background: linear-gradient(90deg, #667eea, #764ba2) !important;
color: white !important; font-weight: 600 !important; border: none !important;}
.solve-btn {background: linear-gradient(90deg, #11998e, #38ef7d) !important;
color: white !important; font-weight: 600 !important; border: none !important;}
""",
title="๐Ÿงฎ Math Story Problem Generator"
) as demo:
gr.Markdown("""
# ๐Ÿงฎ Math Story Problem Generator & Solver
### Transform boring math into exciting stories! ๐ŸŽ‰
**Generate** personalized word problems based on your interests, or **paste** any problem to get a detailed solution.
""")
with gr.Tabs():
# GENERATE TAB
with gr.Tab("โœจ Generate Problem"):
with gr.Row():
with gr.Column():
theme_choice = gr.Dropdown(
choices=list(THEMES.keys()),
value="๐ŸŽฎ Gaming",
label="๐Ÿ“š Choose Theme",
info="Pick what interests you!"
)
grade_choice = gr.Dropdown(
choices=list(GRADE_LEVELS.keys()),
value="Middle School (6-8)",
label="๐ŸŽ“ Grade Level"
)
custom_topic = gr.Textbox(
label="๐ŸŽฏ Custom Topic (Optional)",
placeholder="e.g., 'TikTok followers', 'Minecraft building', 'sneaker collection'",
lines=1
)
generate_btn = gr.Button(
"๐Ÿš€ Generate Story Problem",
variant="primary",
size="lg",
elem_classes="generate-btn"
)
problem_output = gr.HTML(label="Generated Problem")
problem_text_state = gr.State()
with gr.Row():
show_solution_btn = gr.Button(
"๐Ÿ“ Show Solution",
variant="secondary",
size="lg",
elem_classes="solve-btn"
)
solution_output = gr.HTML(label="Solution", visible=False)
# SOLVE TAB
with gr.Tab("๐Ÿ” Solve Problem"):
gr.Markdown("""
### Paste any math problem and get a detailed solution!
Works with story problems, equations, geometry, algebra, and more.
""")
paste_problem = gr.Textbox(
label="๐Ÿ“‹ Paste Your Math Problem",
placeholder="Example: A train leaves Chicago at 60 mph. Another train leaves NYC (800 miles away) at 40 mph. When do they meet?",
lines=5
)
solve_btn = gr.Button(
"๐Ÿง  Solve It!",
variant="primary",
size="lg",
elem_classes="solve-btn"
)
solve_output = gr.HTML(label="Solution")
gr.Markdown("""
---
## ๐ŸŽฏ Features
- โœ… **Personalized**: Choose themes you love
- โœ… **Adaptive**: Problems match your grade level
- โœ… **Step-by-Step**: Detailed solutions with explanations
- โœ… **Visual**: ASCII art and diagrams when helpful
- โœ… **Free**: Powered by free AI APIs!
## ๐Ÿ”‘ Setup
Add **GROQ_API_KEY** (from console.groq.com) as a HuggingFace Secret to enable generation.
Gemini API also supported as fallback!
## ๐Ÿ’ก Tips
- Try custom topics that match your interests
- Generate multiple problems to practice
- Challenge yourself with harder grade levels
- Use the solver to check your own work
---
*Built with โค๏ธ for math learners everywhere*
""")
# Event handlers
def generate_and_show(theme, grade, custom):
html, text = generate_problem(theme, grade, custom)
return html, text, gr.update(visible=False)
def show_solution_for_problem(problem_text):
if not problem_text:
return gr.update(visible=False)
solution = solve_problem(problem_text)
return gr.update(value=solution, visible=True)
generate_btn.click(
fn=generate_and_show,
inputs=[theme_choice, grade_choice, custom_topic],
outputs=[problem_output, problem_text_state, solution_output]
)
show_solution_btn.click(
fn=show_solution_for_problem,
inputs=[problem_text_state],
outputs=[solution_output]
)
solve_btn.click(
fn=solve_problem,
inputs=[paste_problem],
outputs=[solve_output]
)
if __name__ == "__main__":
demo.launch()