shukdevdattaEX commited on
Commit
0db7db0
·
verified ·
1 Parent(s): cbbd49e

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +287 -0
app.py ADDED
@@ -0,0 +1,287 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import os
3
+ import re
4
+ import time
5
+ import base64 # image has to be converted to base64
6
+ from openai import OpenAI #openrouter access
7
+ from together import Together
8
+ from PIL import Image #pillow for image processing
9
+ import io
10
+
11
+ ### function to create math solution from math problem text
12
+
13
+ def generate_math_solution_openrouter(api_key, problem_text, history=None):
14
+ if not api_key.strip():
15
+ return "Please enter your OpenRouter API key.", history
16
+
17
+ if not problem_text.strip():
18
+ return "Please enter a math problem so that I can solve it for you!",
19
+
20
+ try:
21
+ client=OpenAI(
22
+ base_url="https://openrouter.ai/api/v1",
23
+ api_key=api_key,
24
+ )
25
+
26
+ messages= [
27
+ {"role": "system", "content":
28
+ """You are an expert math tutor who explains concepts clearly and thoroughly.
29
+ Analyze the given math problem and provide a detailed step-by-step solution.
30
+ For each step:
31
+ 1. Show the mathematical operation
32
+ 2. Explain why this step is necessary
33
+ 3. Connect it to relevant mathematical concepts
34
+
35
+ Format your response with clear section headers using markdown.
36
+ Begin with an "Initial Analysis" section, follow with numbered steps,
37
+ and conclude with a "Final Answer" section."""},
38
+ ]
39
+
40
+ if history:
41
+ for exchange in history:
42
+ messages.append({"role": "user", "content": exchange[0]}) #asks a math prob
43
+ if exchange[1]: # Check if there's a response
44
+ messages.append({"role": "assistant", "content": exchange[1]}) #AI responses with a solution
45
+
46
+ # Add the current problem
47
+ messages.append({"role": "user", "content": f"Solve this math problem step-by-step: {problem_text}"})
48
+
49
+ # Create the completion
50
+ completion = client.chat.completions.create(
51
+ model="microsoft/phi-4-reasoning-plus:free",
52
+ messages=messages,
53
+ extra_headers={
54
+ "HTTP-Referer": "https://advancedmathtutor.edu",
55
+ "X-Title": "Advanced Math Tutor",
56
+ }
57
+ )
58
+
59
+ solution=completion.choices[0].message.content
60
+
61
+ # Update history
62
+ if history is None: #no convo
63
+ history = [] #my all convo saved here
64
+ history.append((problem_text, solution)) #now i update my convo history
65
+
66
+ return solution, history
67
+
68
+ except Exception as e:
69
+ error_message = f"Error: {str(e)}"
70
+ return error_message, history
71
+
72
+
73
+ #image processing
74
+
75
+ def image_to_base64(image_path):
76
+ if image_path is None:
77
+ return None
78
+
79
+ try:
80
+ with open(image_path, "rb") as img_file:
81
+ return base64.b64encode(img_file.read()).decode("utf-8")
82
+ except Exception as e:
83
+ print(f"Error converting image to base64: {str(e)}")
84
+ return None
85
+
86
+ #### function for a math problem that uses image data (Together)
87
+
88
+ def generate_math_solution_together(api_key, problem_text, image_path=None, history=None):
89
+ if not api_key.strip():
90
+ return "Please enter your Together AI API key.", history
91
+
92
+ if not problem_text.strip() and image_path is None:
93
+ return "Please enter a math problem or upload an image of a math problem.", history
94
+
95
+ try:
96
+ client = Together(api_key=api_key)
97
+
98
+ messages= [
99
+ {"role": "system", "content":
100
+ """You are an expert math tutor who explains concepts clearly and thoroughly.
101
+ Analyze the given math problem and provide a detailed step-by-step solution.
102
+ For each step:
103
+ 1. Show the mathematical operation
104
+ 2. Explain why this step is necessary
105
+ 3. Connect it to relevant mathematical concepts
106
+
107
+ Format your response with clear section headers using markdown.
108
+ Begin with an "Initial Analysis" section, follow with numbered steps,
109
+ and conclude with a "Final Answer" section."""},
110
+ ]
111
+
112
+ # Add conversation history if it exists
113
+ if history:
114
+ for exchange in history:
115
+ messages.append({"role": "user", "content": exchange[0]})
116
+ if exchange[1]: # Check if there's a response
117
+ messages.append({"role": "assistant", "content": exchange[1]})
118
+
119
+ # Prepare the user message content
120
+ user_message_content = [] # WE are going to add some instructions regarding how to solve the math problem in the image
121
+
122
+ # calculate the area of a circle with radius 6 cm (Image of a problem)
123
+
124
+ #problem text / user message = Before calculating area convert radius of 6 cm to meter first
125
+
126
+ # Add text content if provided
127
+ if problem_text.strip(): #image+instruction
128
+ user_message_content.append({
129
+ "type": "text",
130
+ "text": f"Solve this math problem: {problem_text}" #Before calculating area convert radius of 6 cm to meter first
131
+ })
132
+ else: #image
133
+ user_message_content.append({
134
+ "type": "text",
135
+ "text": "Solve this math problem from the image:"
136
+ })
137
+
138
+ # Add image if provided
139
+ if image_path:
140
+ # Convert image to base64
141
+ base64_image = image_to_base64(image_path)
142
+ if base64_image:
143
+ user_message_content.append({
144
+ "type": "image_url",
145
+ "image_url": {
146
+ "url": f"data:image/jpeg;base64,{base64_image}"
147
+ }
148
+ })
149
+
150
+ # Add the user message with content
151
+ messages.append({
152
+ "role": "user", #conversation saved with image data+usermessage/instruction
153
+ "content": user_message_content
154
+ })
155
+
156
+
157
+ response=client.chat.completions.create( #TOgether
158
+ model="meta-llama/Llama-Vision-Free",
159
+ messages=messages,
160
+ stream=False
161
+ )
162
+
163
+ solution=response.choices[0].message.content #problem----> ans syntax
164
+
165
+ # Update history - for simplicity, just store the text problem
166
+ if history is None:
167
+ history = []
168
+ history.append((problem_text if problem_text.strip() else "Image problem", solution))
169
+
170
+ return solution, history
171
+
172
+ except Exception as e:
173
+ error_message = f"Error: {str(e)}"
174
+ return error_message, history
175
+
176
+ def create_demo(): #interface design complete
177
+ with gr.Blocks(theme=gr.themes.Ocean(primary_hue="blue")) as demo:
178
+ gr.Markdown("# 📚 Advanced Math Tutor")
179
+ gr.Markdown("""
180
+ This application provides step-by-step solutions to math problems using advanced AI models.
181
+ Choose between OpenRouter's Phi-4-reasoning-plus for text-based problems or Together AI's
182
+ Llama-Vision for problems with images.
183
+ """)
184
+
185
+ with gr.Tabs():
186
+ with gr.TabItem("Text Problem Solver (OpenRouter)"):
187
+ with gr.Row():
188
+ with gr.Column(scale=1): #left side column design complete
189
+ openrouter_api_key = gr.Textbox(
190
+ label="OpenRouter API Key",
191
+ placeholder="Enter your OpenRouter API key (starts with sk-or-)",
192
+ type="password"
193
+ )
194
+ text_problem_input = gr.Textbox(
195
+ label="Math Problem",
196
+ placeholder="Enter your math problem here...", #Solve the quadratic equation: 3x² + 5x - 2 = 0"
197
+ lines=5
198
+ )
199
+ example_problems = gr.Examples(
200
+ examples=[
201
+ ["Solve the quadratic equation: 3x² + 5x - 2 = 0"],
202
+ ["Find the derivative of f(x) = x³ln(x)"],
203
+ ["Calculate the area of a circle with radius 5 cm"],
204
+ ["Find all values of x that satisfy the equation: log₂(x-1) + log₂(x+3) = 5"]
205
+ ],
206
+ inputs=[text_problem_input],
207
+ label="Example Problems"
208
+ )
209
+ with gr.Row():
210
+ openrouter_submit_btn = gr.Button("Solve Problem", variant="primary")
211
+ openrouter_clear_btn = gr.Button("Clear")
212
+
213
+ with gr.Column(scale=2):
214
+ openrouter_solution_output = gr.Markdown(label="Solution")
215
+
216
+ # Store conversation history (invisible to user)
217
+ openrouter_conversation_history = gr.State(value=None)
218
+
219
+ # Button actions
220
+ openrouter_submit_btn.click(
221
+ fn=generate_math_solution_openrouter, #text problem solve
222
+ inputs=[openrouter_api_key, text_problem_input, openrouter_conversation_history],
223
+ outputs=[openrouter_solution_output, openrouter_conversation_history]
224
+ )
225
+
226
+ openrouter_clear_btn.click(
227
+ fn=lambda: ("", None),
228
+ inputs=[],
229
+ outputs=[openrouter_solution_output, openrouter_conversation_history]
230
+ )
231
+
232
+ with gr.TabItem("Image Problem Solver (Together AI)"):
233
+ with gr.Row():
234
+ with gr.Column(scale=1):
235
+ together_api_key = gr.Textbox(
236
+ label="Together AI API Key",
237
+ placeholder="Enter your Together AI API key",
238
+ type="password"
239
+ )
240
+ together_problem_input = gr.Textbox(
241
+ label="Problem Description/Instruction (Optional)",
242
+ placeholder="Enter additional context for the image problem...",
243
+ lines=3
244
+ )
245
+ together_image_input = gr.Image(
246
+ label="Upload Math Problem Image",
247
+ type="filepath"
248
+ )
249
+ with gr.Row():
250
+ together_submit_btn = gr.Button("Solve Problem", variant="primary")
251
+ together_clear_btn = gr.Button("Clear")
252
+
253
+ with gr.Column(scale=2):
254
+ together_solution_output = gr.Markdown(label="Solution")
255
+
256
+ # Store conversation history (invisible to user)
257
+ together_conversation_history = gr.State(value=None)
258
+
259
+ # Button actions
260
+ together_submit_btn.click(
261
+ fn=generate_math_solution_together,
262
+ inputs=[together_api_key, together_problem_input, together_image_input, together_conversation_history],
263
+ outputs=[together_solution_output, together_conversation_history]
264
+ )
265
+
266
+ together_clear_btn.click(
267
+ fn=lambda: ("", None),
268
+ inputs=[],
269
+ outputs=[together_solution_output, together_conversation_history]
270
+ )
271
+
272
+
273
+ # Footer
274
+ gr.Markdown("""
275
+ ---
276
+ ### About
277
+ This application uses Microsoft's Phi-4-reasoning-plus model via OpenRouter for text-based problems
278
+ and Llama-Vision-Free via Together AI for image-based problems.
279
+ Your API keys are required but not stored permanently.
280
+ """)
281
+
282
+ return demo
283
+
284
+ # Launch the app
285
+ if __name__ == "__main__":
286
+ demo = create_demo()
287
+ demo.launch()