Download app.py from QuickLearnerAI/Smart-Math-Assistant: direct link, hf CLI and curl.
- Browser
- Download file 10.9 kB
-
https://huggingface.co/spaces/QuickLearnerAI/Smart-Math-Assistant/resolve/271e143e5221cee44328f3aaffd70742e9bc2fc9/app.py
- Command line
-
hf download hf://spaces/QuickLearnerAI/Smart-Math-Assistant@271e143e5221cee44328f3aaffd70742e9bc2fc9/app.py
-
curl -L -o app.py https://huggingface.co/spaces/QuickLearnerAI/Smart-Math-Assistant/resolve/271e143e5221cee44328f3aaffd70742e9bc2fc9/app.py
10.9 kB
| import gradio as gr | |
| import os | |
| import re | |
| import time | |
| import base64 | |
| from openai import OpenAI # access the open router api | |
| from together import Together | |
| from PIL import Image | |
| import io | |
| def math_solution_openrouter(api_key, prob_text, history=None): | |
| if not api_key.strip(): | |
| return "please enter your OpenRouter Key.",history | |
| if not prob_text.strip(): | |
| return "please enter a math problem so that I can solve it for you", | |
| try: | |
| client= OpenAI( | |
| base_url="https://openrouter.ai/api/v1", | |
| api_key=api_key, | |
| ) | |
| messages= [ | |
| { "role": "system", "content": | |
| """You are a very smart math tutor who can able to solve math and give proper explanations clearly and in a precise manner. | |
| You can analyze the math problem given to you and provide the details solution step by step. | |
| For every step: | |
| 1. Show all the mathematical explanations. | |
| 2. Explain each step and its necessity. | |
| 3. Connect it to the relevant mathematical concept. | |
| Format your response with clear section of headers using markdown and comment if necessary. | |
| Begin with a section of analysis named "Initail step" and followed number of step and conclude with "Final step" section. | |
| """}, | |
| ] | |
| if history: | |
| for exchange in history: | |
| messages.append({"role":"user","content":exchange[0]}) #@ task a math problem | |
| if exchange[1]: # check if there is a problem | |
| messages.append({"role": "assistant","content": exchange[1]}) # AI response with solution. | |
| messages.append({"role":"user","content":f"Solve the given math problem step-by-step: {prob_text}"}) # math problem | |
| completion = client.chat.completions.create( | |
| model= "openai/gpt-4o", | |
| message= messages, | |
| extra_headers={ | |
| "HTTP-Referer": "https://smartmathtutor.edu", # Optional. Site URL for rankings on openrouter.ai. | |
| "X-Title": "Smart Math Tutor", # Optional. Site title for rankings on openrouter.ai. | |
| } | |
| ) | |
| solution = completion.choices[0].message.content | |
| #update history | |
| if history is None: | |
| history=[] | |
| history.append((prob_text, solution )) | |
| return solution, history | |
| except Exception as e: | |
| error_message= f"Error:{str(e)}" | |
| return error_message, history | |
| #image processing | |
| def img_conv_base64(img_path): | |
| if img_path is None: | |
| return None | |
| try: | |
| with open(img_path,"rb") as img_file: | |
| return base64.b64encode(img_file.read()).decode("utf-8") | |
| except Exception as e: | |
| print(f"Error converting image to base64:{str(e)}") | |
| return None | |
| # function for a given math problem for image data[Togetherai] | |
| def gen_math_sol_together(api_key, prob_text, img_path=None, history=None): | |
| if not api_key.strip(): | |
| return "Please enter your Valid Together API key",history | |
| if not prob_text.strip() and img_path is None: | |
| return "please enter a valid math problem or upload an image of a math problem", history | |
| try: | |
| client= Together(api_key=api_key) | |
| messages=[{ "role": "system", "content": | |
| """You are a very smart math tutor who can able to solve math and give proper explanations clearly and in a precise manner. | |
| You can analyze the math problem from image given to you and provide the details solution step by step. | |
| For every step: | |
| 1. Show all the mathematical explanations. | |
| 2. Explain each step and its necessity. | |
| 3. Connect it to the relevant mathematical concept. | |
| Format your response with clear section of headers using markdown and comment if necessary. | |
| Begin with a section of analysis named "Initail step" and followed number of step and conclude with "Final step" section. | |
| """},] | |
| if history: | |
| for exchange in history: | |
| messages.append({"role":"user","content":exchange[0]}) #@ task a math problem | |
| if exchange[1]: # check if there is a problem | |
| messages.append({"role": "assistant","content": exchange[1]}) # AI response with solution. | |
| user_message_content= [] # if we want to add some instructions regaring how to solve the math from given image | |
| if prob_text.strip(): # for text | |
| user_message_content.append({ | |
| "type": "text", | |
| "text": f"Solve this math problem:{prob_text}" | |
| }) | |
| else: #image | |
| user_message_content.append({ | |
| "type": "text", | |
| "text": "Solve this math problem from the given image" | |
| }) | |
| if img_path: | |
| base64_image= img_conv_base64(img_path) | |
| if base64_image: | |
| user_message_content.append({ | |
| "type": "image_url", | |
| "image_url": { | |
| "url": f"data:image/jpeg;base64,{base64_image}" | |
| } | |
| }) | |
| messages.append({ | |
| "role": "user", #conversation saved with image data | |
| "content": user_message_content | |
| }) | |
| response = client.chat.completions.create( | |
| model= "meta-llama/Llama-Vision-Free", | |
| message= messages, | |
| stream= False | |
| ) | |
| solution= response.choices[0].message.content | |
| if history is None: | |
| history=[] | |
| history.append(prob_text if prob_text.strip() else "Image problem ..", solution) | |
| return solution, history | |
| except Exception as e: | |
| error_msg= f"Error: {str(e)}" | |
| return error_msg, history | |
| def create_demo(): | |
| with gr.Blocks(theme=gr.themes.Ocean(primary_hue="blue")) as demo: | |
| gr.Markdown("# Smart Math Tutor") | |
| gr.Markdown("""This applications provide step by step solution to a math paroblem using AI Tools. | |
| Choose between OpenPouter's Phi-4-reasoning-plus for text based analysis and Together AI's Llama-Vision for problem with images""")\ | |
| with gr.Tabs(): | |
| with gr.TabItem("Text problem solver (OpenRouter)"): | |
| with gr.Row(): | |
| with gr.Column(scale=1): #left side | |
| openrouter_api_key= gr.Textbox( | |
| label= "OpenRouter API key", | |
| placeholder= "enter your API key here", | |
| type= "password" | |
| ) | |
| text_prob_input= gr.Textbox( | |
| label="Math Problem", | |
| placeholder= "Enter ypur math problem here..", | |
| lines= 5 | |
| ) | |
| example_problems= gr.Examples( | |
| examples=[ | |
| ["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"], | |
| ["Find all values of x that satisfy the equation: log₁₀(x+1) + log₁₀(x²) = 5"] | |
| ], | |
| input=[text_prob_input], | |
| label="Example Problems" | |
| ) | |
| with gr.Row(): | |
| openrouter_submit_btn= gr.Button("solve problem", variant= "primary") | |
| openrouter_clear_btn= gr.Button("Clear") | |
| with gr.Column(scale=2): #right side | |
| openrouter_solution_output= gr.Markdown(label="Solution") | |
| openrouter_conversation_history= gr.State(value=None) | |
| openrouter_submit_btn.click( | |
| fn=math_solution_openrouter, | |
| inputs=[openrouter_api_key, text_prob_input, openrouter_conversation_history], | |
| outputs=[openrouter_solution_output, openrouter_conversation_history] | |
| ) | |
| openrouter_clear_btn.click( | |
| fn=lambda: ("",None), | |
| inputs=[], | |
| outputs=[openrouter_solution_output, openrouter_conversation_history] | |
| ) | |
| with gr.TabItem("Text problem solver (Together AI)"): | |
| with gr.Row(): | |
| with gr.Column(scale=1): #left side | |
| together_api_key= gr.Textbox( | |
| label= "Together API key", | |
| placeholder= "enter your API key here", | |
| type= "password" | |
| ) | |
| together_prob_input= gr.Textbox( | |
| label="Math Problem Description", | |
| placeholder= "Enter additional math problem here..", | |
| lines= 3 | |
| ) | |
| together_image_input= gr.Image( | |
| label="upload math problem image", | |
| type="filepath" | |
| ) | |
| with gr.Row(): | |
| together_submit_btn= gr.Button("Solve Problem", variant="primary") | |
| together_clear_btn = gr.Button("clear") | |
| with gr.Column(scale=2): | |
| together_solution_output= gr.Markdown(label="Solution") | |
| together_conversation_history= gr.State(value=None) | |
| # Button actions | |
| together_submit_btn.click( | |
| fn=generate_math_solution_together, | |
| inputs=[together_api_key, together_problem_input, together_image_input, together_conversation_history], | |
| outputs=[together_solution_output, together_conversation_history] | |
| ) | |
| together_clear_btn.click( | |
| fn=lambda: ("", None), | |
| inputs=[], | |
| outputs=[together_solution_output, together_conversation_history] | |
| ) | |
| # Footer | |
| gr.Markdown(""" | |
| --- | |
| ### About | |
| This application uses Microsoft's Phi-4-reasoning-plus model via OpenRouter for text-based problems | |
| and Llama-Vision-Free via Together AI for image-based problems. | |
| Your API keys are required but not stored permanently. | |
| """) | |
| return demo | |
| # Launch the app | |
| if __name__ == "__main__": | |
| demo = create_demo() | |
| demo.launch() | |