mikaelJ46 commited on
Commit
7b94087
Β·
verified Β·
1 Parent(s): 21df735

Update app. py

Browse files
Files changed (1) hide show
  1. app. py +258 -0
app. py CHANGED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import requests
3
+ import base64
4
+ from io import BytesIO
5
+ from PIL import Image
6
+ import json
7
+
8
+ # Hugging Face API configuration
9
+ API_URL = "https://api.anthropic.com/v1/messages"
10
+
11
+ def encode_image(image):
12
+ """Convert PIL Image to base64 string"""
13
+ buffered = BytesIO()
14
+ image.save(buffered, format="PNG")
15
+ img_str = base64.b64encode(buffered.getvalue()).decode()
16
+ return img_str
17
+
18
+ def analyze_math_work(image, grade_level, topic):
19
+ """
20
+ Analyze student's math work using Claude API
21
+ """
22
+ try:
23
+ # Encode the image
24
+ img_base64 = encode_image(image)
25
+
26
+ # Construct the prompt based on grade level and topic
27
+ system_prompt = f"""You are a patient and encouraging mathematics teacher for {grade_level} students.
28
+ Your role is to:
29
+ 1. Carefully examine the student's written work in the image
30
+ 2. Identify what mathematical problem they are solving
31
+ 3. Check their working step-by-step
32
+ 4. Point out any errors with clear, kind explanations
33
+ 5. Provide the correct solution with detailed steps
34
+ 6. Encourage the student and give tips for improvement
35
+
36
+ Focus on {topic} topics appropriate for {grade_level} level.
37
+ Be specific about where mistakes occur and explain why they are mistakes.
38
+ Always be encouraging and supportive."""
39
+
40
+ user_prompt = """Please analyze the mathematical work shown in this image.
41
+
42
+ Provide your feedback in the following format:
43
+
44
+ **Problem Identified:**
45
+ [State what problem the student is trying to solve]
46
+
47
+ **Student's Approach:**
48
+ [Describe what the student did]
49
+
50
+ **Evaluation:**
51
+ [Is it correct? If not, where did they go wrong?]
52
+
53
+ **Detailed Feedback:**
54
+ [Step-by-step explanation of mistakes and corrections]
55
+
56
+ **Correct Solution:**
57
+ [Show the complete correct solution with all steps]
58
+
59
+ **Encouragement & Tips:**
60
+ [Positive feedback and helpful tips]"""
61
+
62
+ # Make API request
63
+ response = requests.post(
64
+ API_URL,
65
+ headers={
66
+ "Content-Type": "application/json",
67
+ },
68
+ json={
69
+ "model": "claude-sonnet-4-20250514",
70
+ "max_tokens": 2000,
71
+ "system": system_prompt,
72
+ "messages": [
73
+ {
74
+ "role": "user",
75
+ "content": [
76
+ {
77
+ "type": "image",
78
+ "source": {
79
+ "type": "base64",
80
+ "media_type": "image/png",
81
+ "data": img_base64
82
+ }
83
+ },
84
+ {
85
+ "type": "text",
86
+ "text": user_prompt
87
+ }
88
+ ]
89
+ }
90
+ ]
91
+ },
92
+ timeout=60
93
+ )
94
+
95
+ if response.status_code == 200:
96
+ result = response.json()
97
+ feedback = result['content'][0]['text']
98
+ return feedback
99
+ else:
100
+ return f"Error: API returned status code {response.status_code}\n{response.text}"
101
+
102
+ except Exception as e:
103
+ return f"Error analyzing work: {str(e)}\n\nPlease make sure:\n1. Your image is clear and readable\n2. The mathematical work is visible\n3. Try again or contact support if the issue persists"
104
+
105
+ def create_practice_problem(grade_level, topic):
106
+ """Generate a practice problem for the student"""
107
+ try:
108
+ prompt = f"""Generate a {grade_level} level mathematics practice problem about {topic}.
109
+
110
+ Provide:
111
+ 1. A clear problem statement
112
+ 2. Any necessary context or setup
113
+ 3. Space for the student to work (indicate this)
114
+
115
+ Make it appropriate for {grade_level} students and engaging."""
116
+
117
+ response = requests.post(
118
+ API_URL,
119
+ headers={
120
+ "Content-Type": "application/json",
121
+ },
122
+ json={
123
+ "model": "claude-sonnet-4-20250514",
124
+ "max_tokens": 1000,
125
+ "messages": [
126
+ {
127
+ "role": "user",
128
+ "content": prompt
129
+ }
130
+ ]
131
+ },
132
+ timeout=30
133
+ )
134
+
135
+ if response.status_code == 200:
136
+ result = response.json()
137
+ return result['content'][0]['text']
138
+ else:
139
+ return "Error generating practice problem. Please try again."
140
+
141
+ except Exception as e:
142
+ return f"Error: {str(e)}"
143
+
144
+ # Create the Gradio interface
145
+ with gr.Blocks(title="Math Learning Assistant", theme=gr.themes.Soft()) as app:
146
+ gr.Markdown("""
147
+ # πŸ“š Math Learning Assistant
148
+ ### Learn mathematics by practicing and getting instant feedback!
149
+
150
+ **How to use:**
151
+ 1. Choose your grade level and math topic
152
+ 2. Either draw your solution using the canvas OR upload a photo of your written work
153
+ 3. Click "Check My Work" to get detailed feedback from your AI teacher
154
+ 4. Learn from the feedback and try again!
155
+ """)
156
+
157
+ with gr.Row():
158
+ with gr.Column(scale=1):
159
+ grade_level = gr.Dropdown(
160
+ choices=[
161
+ "Primary 1-2 (Ages 6-8)",
162
+ "Primary 3-4 (Ages 8-10)",
163
+ "Primary 5-6 (Ages 10-12)",
164
+ "Secondary 1-2 (Ages 12-14)",
165
+ "Secondary 3-4 (Ages 14-16)"
166
+ ],
167
+ label="Select Your Grade Level",
168
+ value="Primary 3-4 (Ages 8-10)"
169
+ )
170
+
171
+ topic = gr.Dropdown(
172
+ choices=[
173
+ "Addition & Subtraction",
174
+ "Multiplication & Division",
175
+ "Fractions",
176
+ "Decimals",
177
+ "Percentages",
178
+ "Algebra (Basic)",
179
+ "Algebra (Advanced)",
180
+ "Geometry",
181
+ "Word Problems",
182
+ "Equations",
183
+ "Ratios & Proportions",
184
+ "Measurements"
185
+ ],
186
+ label="Select Math Topic",
187
+ value="Addition & Subtraction"
188
+ )
189
+
190
+ get_problem_btn = gr.Button("πŸ“ Get Practice Problem", variant="secondary")
191
+ practice_problem = gr.Textbox(
192
+ label="Practice Problem",
193
+ placeholder="Click 'Get Practice Problem' to receive a new problem to solve",
194
+ lines=6
195
+ )
196
+
197
+ with gr.Row():
198
+ with gr.Column(scale=1):
199
+ gr.Markdown("### ✍️ Write or Upload Your Solution")
200
+
201
+ with gr.Tabs():
202
+ with gr.Tab("Draw Your Work"):
203
+ sketchpad = gr.Sketchpad(
204
+ label="Write your solution here (use your finger or mouse)",
205
+ type="pil",
206
+ brush=gr.Brush(colors=["#000000", "#0000FF", "#FF0000"], default_size=3)
207
+ )
208
+
209
+ with gr.Tab("Upload Photo"):
210
+ image_upload = gr.Image(
211
+ label="Upload a photo of your written work",
212
+ type="pil"
213
+ )
214
+
215
+ check_btn = gr.Button("πŸ” Check My Work", variant="primary", size="lg")
216
+
217
+ with gr.Column(scale=1):
218
+ gr.Markdown("### πŸ“Š Teacher's Feedback")
219
+ feedback_output = gr.Textbox(
220
+ label="Detailed Feedback",
221
+ lines=20,
222
+ placeholder="Your feedback will appear here after clicking 'Check My Work'"
223
+ )
224
+
225
+ gr.Markdown("""
226
+ ---
227
+ ### πŸ’‘ Tips for Best Results:
228
+ - Write clearly and show all your steps
229
+ - If uploading a photo, make sure it's well-lit and in focus
230
+ - Include the problem you're solving at the top
231
+ - Don't worry about mistakes - they help you learn!
232
+ """)
233
+
234
+ # Event handlers
235
+ def check_work(sketch, upload, grade, topic_val):
236
+ # Use whichever image is available (sketchpad takes priority)
237
+ image_to_analyze = sketch if sketch is not None else upload
238
+
239
+ if image_to_analyze is None:
240
+ return "⚠️ Please draw your solution or upload an image of your work first!"
241
+
242
+ return analyze_math_work(image_to_analyze, grade, topic_val)
243
+
244
+ check_btn.click(
245
+ fn=check_work,
246
+ inputs=[sketchpad, image_upload, grade_level, topic],
247
+ outputs=feedback_output
248
+ )
249
+
250
+ get_problem_btn.click(
251
+ fn=create_practice_problem,
252
+ inputs=[grade_level, topic],
253
+ outputs=practice_problem
254
+ )
255
+
256
+ # Launch the app
257
+ if __name__ == "__main__":
258
+ app.launch(share=True)