|
import gradio as gr |
|
import os |
|
import re |
|
import markdown |
|
from openai import OpenAI |
|
import time |
|
|
|
|
|
def generate_math_solution(api_key, problem_text, history=None): |
|
if not api_key.strip(): |
|
return "Please enter your OpenRouter API key.", history |
|
|
|
if not problem_text.strip(): |
|
return "Please enter a math problem.", history |
|
|
|
try: |
|
client = OpenAI( |
|
base_url="https://openrouter.ai/api/v1", |
|
api_key=api_key, |
|
) |
|
|
|
messages = [ |
|
{"role": "system", "content": |
|
"""You are an expert math tutor who explains concepts clearly and thoroughly. |
|
Analyze the given math problem and provide a detailed step-by-step solution. |
|
For each step: |
|
1. Show the mathematical operation |
|
2. Explain why this step is necessary |
|
3. Connect it to relevant mathematical concepts |
|
|
|
Format your response with clear section headers using markdown. |
|
Begin with an "Initial Analysis" section, follow with numbered steps, |
|
and conclude with a "Final Answer" section."""}, |
|
] |
|
|
|
|
|
if history: |
|
for exchange in history: |
|
messages.append({"role": "user", "content": exchange[0]}) |
|
if exchange[1]: |
|
messages.append({"role": "assistant", "content": exchange[1]}) |
|
|
|
|
|
messages.append({"role": "user", "content": f"Solve this math problem step-by-step: {problem_text}"}) |
|
|
|
|
|
completion = client.chat.completions.create( |
|
model="microsoft/phi-4-reasoning-plus:free", |
|
messages=messages, |
|
extra_headers={ |
|
"HTTP-Referer": "https://advancedmathtutor.edu", |
|
"X-Title": "Advanced Math Tutor", |
|
} |
|
) |
|
|
|
solution = completion.choices[0].message.content |
|
|
|
|
|
if history is None: |
|
history = [] |
|
history.append((problem_text, solution)) |
|
|
|
return solution, history |
|
|
|
except Exception as e: |
|
error_message = f"Error: {str(e)}" |
|
return error_message, history |
|
|
|
|
|
def generate_practice_problem(api_key, topic, difficulty, history=None): |
|
if not api_key.strip(): |
|
return "Please enter your OpenRouter API key.", history |
|
|
|
if not topic.strip(): |
|
return "Please specify a math topic.", history |
|
|
|
try: |
|
client = OpenAI( |
|
base_url="https://openrouter.ai/api/v1", |
|
api_key=api_key, |
|
) |
|
|
|
prompt = f"""Generate a {difficulty} level math problem related to {topic}. |
|
The problem should be challenging but solvable, and relevant to a student studying {topic}. |
|
Only provide the problem statement, not the solution.""" |
|
|
|
completion = client.chat.completions.create( |
|
model="microsoft/phi-4-reasoning-plus:free", |
|
messages=[ |
|
{"role": "system", "content": "You are an expert math teacher who creates engaging practice problems."}, |
|
{"role": "user", "content": prompt} |
|
], |
|
extra_headers={ |
|
"HTTP-Referer": "https://advancedmathtutor.edu", |
|
"X-Title": "Advanced Math Tutor", |
|
} |
|
) |
|
|
|
practice_problem = completion.choices[0].message.content |
|
|
|
return practice_problem, history |
|
|
|
except Exception as e: |
|
error_message = f"Error: {str(e)}" |
|
return error_message, history |
|
|
|
|
|
def validate_api_key(api_key): |
|
|
|
if api_key.startswith("sk-or-") and len(api_key) > 20: |
|
return True |
|
return False |
|
|
|
|
|
def process_solution(solution): |
|
|
|
solution = re.sub(r'(?<!\$)\$(?!\$)(.+?)(?<!\$)\$(?!\$)', r'$$\1$$', solution) |
|
return solution |
|
|
|
|
|
def create_demo(): |
|
with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue")) as demo: |
|
gr.Markdown("# 📚 Advanced Math Tutor") |
|
gr.Markdown(""" |
|
This application uses Microsoft's Phi-4-reasoning-plus model to provide step-by-step solutions |
|
to math problems. Enter your math problem, and get a detailed explanation with clear reasoning steps. |
|
""") |
|
|
|
|
|
with gr.Tabs(): |
|
with gr.TabItem("Problem Solver"): |
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
api_key_input = gr.Textbox( |
|
label="OpenRouter API Key", |
|
placeholder="Enter your OpenRouter API key (starts with sk-or-)", |
|
type="password" |
|
) |
|
problem_input = gr.Textbox( |
|
label="Math Problem", |
|
placeholder="Enter your math problem here...", |
|
lines=5 |
|
) |
|
with gr.Row(): |
|
submit_btn = gr.Button("Solve Problem", variant="primary") |
|
clear_btn = gr.Button("Clear") |
|
|
|
with gr.Column(scale=2): |
|
solution_output = gr.Markdown(label="Solution") |
|
|
|
|
|
conversation_history = gr.State(value=None) |
|
|
|
|
|
submit_btn.click( |
|
fn=generate_math_solution, |
|
inputs=[api_key_input, problem_input, conversation_history], |
|
outputs=[solution_output, conversation_history] |
|
) |
|
|
|
clear_btn.click( |
|
fn=lambda: ("", None), |
|
inputs=[], |
|
outputs=[solution_output, conversation_history] |
|
) |
|
|
|
with gr.TabItem("Practice Problems"): |
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
practice_api_key = gr.Textbox( |
|
label="OpenRouter API Key", |
|
placeholder="Enter your OpenRouter API key (starts with sk-or-)", |
|
type="password" |
|
) |
|
topic_input = gr.Textbox( |
|
label="Math Topic", |
|
placeholder="e.g., Algebra, Calculus, Geometry...", |
|
) |
|
difficulty_input = gr.Dropdown( |
|
label="Difficulty Level", |
|
choices=["Easy", "Medium", "Hard", "Challenge"], |
|
value="Medium" |
|
) |
|
generate_btn = gr.Button("Generate Practice Problem", variant="primary") |
|
|
|
with gr.Column(scale=2): |
|
practice_problem_output = gr.Markdown(label="Practice Problem") |
|
solve_practice_btn = gr.Button("Solve This Practice Problem") |
|
|
|
|
|
practice_history = gr.State(value=None) |
|
|
|
|
|
generate_btn.click( |
|
fn=generate_practice_problem, |
|
inputs=[practice_api_key, topic_input, difficulty_input, practice_history], |
|
outputs=[practice_problem_output, practice_history] |
|
) |
|
|
|
|
|
solve_practice_btn.click( |
|
fn=lambda problem: problem, |
|
inputs=[practice_problem_output], |
|
outputs=[problem_input], |
|
_js="() => {document.querySelector('button[id^=\"tabitem\"]').click();}" |
|
) |
|
|
|
with gr.TabItem("Help"): |
|
gr.Markdown(""" |
|
## How to Use the Advanced Math Tutor |
|
|
|
### Getting Started |
|
1. You'll need an API key from OpenRouter to use this app |
|
2. Sign up at [OpenRouter](https://openrouter.ai/) to get your API key |
|
3. Enter your API key in the designated field |
|
|
|
### Solving Math Problems |
|
- Type or paste your math problem in the input field |
|
- Click "Solve Problem" to get a detailed step-by-step solution |
|
- The solution will include explanations for each step |
|
|
|
### Practice Problems |
|
- Go to the Practice Problems tab |
|
- Enter a math topic (e.g., "Integration", "Linear Equations") |
|
- Select a difficulty level |
|
- Click "Generate Practice Problem" to get a new problem |
|
- Use "Solve This Practice Problem" to transfer it to the solver |
|
|
|
### Tips for Best Results |
|
- Be specific in your problem description |
|
- Include all necessary information |
|
- For complex equations, use clear notation |
|
|
|
### Example Problems |
|
Try these example problems: |
|
- Solve the quadratic equation: 3x² + 5x - 2 = 0 |
|
- Find the derivative of f(x) = x³ln(x) |
|
- Calculate the area of a circle with radius 5 cm |
|
""") |
|
|
|
|
|
gr.Markdown(""" |
|
--- |
|
### About |
|
This application uses Microsoft's Phi-4-reasoning-plus model via OpenRouter to generate step-by-step solutions. |
|
Your API key is required but not stored permanently. |
|
""") |
|
|
|
return demo |
|
|
|
|
|
if __name__ == "__main__": |
|
demo = create_demo() |
|
demo.launch() |