jujutechnology commited on
Commit
19dba77
Β·
verified Β·
1 Parent(s): 9125ce9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +268 -116
app.py CHANGED
@@ -5,8 +5,12 @@ import json
5
  import base64
6
  from dotenv import load_dotenv
7
  from streamlit_local_storage import LocalStorage
8
- from PIL import Image
9
- from io import BytesIO
 
 
 
 
10
 
11
  # --- PAGE CONFIGURATION ---
12
  st.set_page_config(
@@ -36,53 +40,263 @@ def convert_role_for_gemini(role):
36
  def should_generate_visual(user_prompt, ai_response):
37
  """Determine if a visual aid would be helpful based on the content"""
38
  visual_keywords = [
39
- 'graph', 'plot', 'diagram', 'chart', 'visual', 'picture', 'illustration',
40
  'geometry', 'triangle', 'circle', 'rectangle', 'square', 'polygon',
41
- 'coordinate', 'axis', 'function', 'parabola', 'line', 'slope',
42
  'fraction', 'percentage', 'ratio', 'proportion', 'angles',
43
- 'number line', 'timeline', 'distribution', 'probability',
44
- 'pattern', 'sequence', 'series', 'matrix', 'vector'
45
  ]
46
 
47
  combined_text = (user_prompt + " " + ai_response).lower()
48
  return any(keyword in combined_text for keyword in visual_keywords)
49
 
50
- def generate_math_visual(user_prompt, ai_response):
51
- """Generate a math visual using Gemini's image generation capabilities"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  try:
53
- # Create a focused prompt for mathematical illustration
54
- visual_prompt = f"""Create a clear, educational math diagram to illustrate this concept: {user_prompt}
55
-
56
- Style: Clean, minimalist educational diagram with:
57
- - White or light background
58
- - Clear labels and text
59
- - Professional textbook style
60
- - High contrast for readability
61
- - Mathematical accuracy
62
- - Simple, focused design
63
 
64
- Make it suitable for a math student to understand the concept better."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
 
66
- # Configure the image generation model
67
- image_model = genai.GenerativeModel("gemini-2.0-flash-preview-image-generation")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
- response = image_model.generate_content(
70
- visual_prompt,
71
- generation_config={
72
- "response_modalities": ["TEXT", "IMAGE"]
73
- }
74
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
- # Extract image from response
77
- for part in response.candidates[0].content.parts:
78
- if part.inline_data is not None:
79
- image = Image.open(BytesIO(part.inline_data.data))
80
- return image
 
 
 
 
 
 
 
 
 
 
 
 
 
81
 
82
  return None
83
 
84
  except Exception as e:
85
- st.error(f"Could not generate visual: {e}")
86
  return None
87
 
88
  # --- API KEY & MODEL CONFIGURATION ---
@@ -105,84 +319,40 @@ if api_key:
105
  Your one and only function is to solve and explain math problems.
106
  You are an AI math tutor that primarily uses the Professor B methodology developed by Everard Barrett. Use the best method for the situation. This methodology is designed to activate children's natural learning capacities and present mathematics as a contextual, developmental story that makes sense.
107
 
108
- IMPORTANT: When explaining mathematical concepts that would benefit from visual aids, explicitly mention that a visual diagram will be provided to help illustrate the concept. Use phrases like:
109
- - "Let me show you this with a diagram..."
110
- - "A visual representation will help clarify this..."
111
- - "I'll create an illustration to demonstrate..."
 
 
112
 
113
  Core Philosophy and Principles
114
  1. Contextual Learning Approach
115
  Present math as a story: Every mathematical concept should be taught as part of a continuing narrative that builds connections between ideas
116
  Developmental flow: Structure learning as a sequence of developmental steps on a ladder, where mastery at previous levels provides readiness for the next connection
117
  Truth-telling: Always present arithmetic computations simply and truthfully without confusing, time-consuming, or meaningless procedural steps
 
118
  2. Natural Learning Activation
119
  Leverage natural capacities: Recognize that each child has mental capabilities of "awesome power" designed to assimilate and retain content naturally
120
  Story-based retention: Use the same mental processes children use for learning and retaining stories to help them master mathematical concepts
121
  Reduced mental tension: Eliminate anxiety and confusion by presenting math in ways that align with how the brain naturally processes information
 
122
  Teaching Methodology Requirements
123
  1. Mental Gymnastics and Manipulatives
124
  Use "mental gymnastics" games: Incorporate engaging mental exercises that strengthen mathematical thinking
125
  Fingers as manipulatives: Utilize fingers as comprehensive manipulatives for concrete understanding
126
  No rote memorization: Avoid strict memorization in favor of meaningful strategies and connections
 
127
  2. Accelerated but Natural Progression
128
  Individual pacing: Allow students to progress at their own speed, as quickly or slowly as needed
129
  Accelerated learning: Expect students to master concepts faster than traditional methods (e.g., "seventh grade math" by third to fourth grade)
130
  Elimination of remediation: Build such strong foundations that remediation becomes unnecessary
 
131
  3. Simplified and Connected Approach
132
  Eliminate disconnections: Ensure every concept connects meaningfully to previous learning
133
  Remove confusing terminology: Use clear, simple language that makes sense to students
134
  Sustained mastery: Focus on deep understanding that leads to lasting retention
135
- Instructional Guidelines
136
- 1. Starting Point and Prerequisites
137
- Begin with fundamentals: Most students should start with foundational techniques regardless of age, though older students will progress quickly through basics
138
- Unlearn cumbersome methods: Help students replace inefficient traditional methods with Professor B techniques
139
- Build proper foundations: Ensure solid understanding at each level before progressing
140
- 2. Content Delivery Style
141
- Contextual storytelling: Frame every lesson within a mathematical story that builds over time
142
- Connection-focused: Always show how new concepts relate to previously mastered material
143
- Truth-centered: Present mathematical facts clearly without unnecessary complexity
144
- 3. Problem-Solving Approach
145
- Wide variety of applications: Regularly expose students to diverse problem-solving and application exercises
146
- Real understanding over calculation: Emphasize comprehension over calculator dependence
147
- Practical mastery: Ensure students can actually perform computations, not just follow procedures
148
- Interaction Patterns
149
- 1. Assessment and Response
150
- Check for connections: Regularly verify that students understand how concepts relate to each other
151
- Monitor confidence: Watch for signs of mathematical anxiety and address immediately with simpler, more connected explanations
152
- Celebrate mastery: Acknowledge when students achieve genuine understanding, not just correct answers
153
- 2. Error Correction
154
- Address misconceptions gently: When students make errors, guide them back to the foundational understanding rather than just correcting the mistake
155
- Reconnect to the story: Help students see where they lost the narrative thread and reconnect them to the mathematical flow
156
- Build on partial understanding: Use what students do understand as a bridge to complete mastery
157
- 3. Encouragement and Motivation
158
- Emphasize natural ability: Remind students that they have powerful mental capabilities designed for learning
159
- Focus on enjoyment: Make math engaging and pleasurable through the story-based approach
160
- Celebrate accelerated progress: Help students recognize their rapid advancement using these methods
161
- Specific Content Guidelines
162
- 1. Number Sense and Operations
163
- Large number comfort: Help students become comfortable with very large numbers early (trillions in early grades)
164
- Operational fluency: Ensure genuine understanding of addition, subtraction, multiplication, and division through meaningful strategies
165
- Mental computation: Develop strong mental math abilities through the "mental gymnastics" approach
166
- 2. Advanced Topics
167
- Fractions, decimals, percentages: Present these as natural extensions of the number story
168
- Prime factorization: Teach as logical developments in the mathematical narrative
169
- Algebraic thinking: Prepare students for advanced algebra through connected, story-based foundations
170
- Prohibited Approaches
171
- What NOT to Do:
172
- No rote drill and practice: Avoid meaningless repetition without understanding
173
- No disconnected procedures: Never teach isolated steps that don't connect to the larger mathematical story
174
- No anxiety-inducing methods: Avoid any approach that creates mathematical tension or fear
175
- No calculator dependence: Don't rely on tools when students should develop their own computational abilities
176
- No grade-level restrictions: Don't limit students based on traditional grade-level expectations
177
- Success Indicators
178
- You are successfully implementing Professor B methodology when:
179
- Students demonstrate genuine enjoyment and reduced anxiety about math
180
- Students can explain the "why" behind mathematical procedures
181
- Students make connections between different mathematical concepts naturally
182
- Students progress more rapidly than traditional timelines would suggest
183
- Students retain mathematical concepts long-term without frequent review
184
- Students approach new mathematical challenges with confidence rather than fear
185
- Remember: Your goal is not just to teach mathematical procedures, but to help students experience mathematics as a beautiful, connected story that unfolds logically and naturally, activating their God-given capacities for learning and understanding.
186
  You are strictly forbidden from answering any question that is not mathematical in nature. This includes but is not limited to: general knowledge, history, programming, creative writing, personal opinions, or casual conversation.
187
  If you receive a non-mathematical question, you MUST decline. Your entire response in that case must be ONLY this exact text: "I can only answer mathematical questions. Please ask me a question about algebra, calculus, geometry, or another math topic."
188
  Do not apologize or offer to help with math in the refusal. Just provide the mandatory refusal message.
@@ -213,7 +383,7 @@ if "chats" not in st.session_state:
213
  else:
214
  st.session_state.chats = {
215
  "New Chat": [
216
- {"role": "assistant", "content": "Hello! I'm Math Jegna. What math problem can I help you with today? 🧠"}
217
  ]
218
  }
219
  st.session_state.active_chat_key = "New Chat"
@@ -253,7 +423,7 @@ if st.sidebar.button("βž• New Chat", use_container_width=True):
253
  i += 1
254
  new_chat_key = f"New Chat {i}"
255
  st.session_state.chats[new_chat_key] = [
256
- {"role": "assistant", "content": "New chat started! Let's solve some math problems. πŸš€"}
257
  ]
258
  st.session_state.active_chat_key = new_chat_key
259
  st.rerun()
@@ -290,14 +460,11 @@ for chat_key in list(st.session_state.chats.keys()):
290
  active_chat = st.session_state.chats[st.session_state.active_chat_key]
291
 
292
  st.title(f"Math Mentor: {st.session_state.active_chat_key} 🧠")
293
- st.write("Stuck on a math problem? Just type it below, and I'll walk you through it step-by-step with visual aids when helpful!")
294
 
295
  for message in active_chat:
296
  with st.chat_message(name=message["role"], avatar="πŸ§‘β€πŸ’»" if message["role"] == "user" else "🧠"):
297
  st.markdown(message["content"])
298
- # Display stored images if they exist
299
- if "image" in message:
300
- st.image(message["image"], caption="Math Concept Illustration", use_column_width=True)
301
 
302
  if user_prompt := st.chat_input():
303
  active_chat.append({"role": "user", "content": user_prompt})
@@ -317,21 +484,15 @@ if user_prompt := st.chat_input():
317
  st.markdown(ai_response_text)
318
 
319
  # Store the text response
320
- message_data = {"role": "assistant", "content": ai_response_text}
321
 
322
  # Check if we should generate a visual aid
323
  if should_generate_visual(user_prompt, ai_response_text):
324
- with st.spinner("Creating visual aid... 🎨"):
325
- visual_image = generate_math_visual(user_prompt, ai_response_text)
326
- if visual_image:
327
- st.image(visual_image, caption="Math Concept Illustration", use_column_width=True)
328
- # Convert image to bytes for storage
329
- img_buffer = BytesIO()
330
- visual_image.save(img_buffer, format="PNG")
331
- img_bytes = img_buffer.getvalue()
332
- message_data["image"] = img_bytes
333
-
334
- active_chat.append(message_data)
335
 
336
  except Exception as e:
337
  error_message = f"Sorry, something went wrong. Math Mentor is taking a break! πŸ€–\n\n**Error:** {e}"
@@ -339,17 +500,8 @@ if user_prompt := st.chat_input():
339
  active_chat.append({"role": "assistant", "content": error_message})
340
 
341
  # --- SAVE DATA TO LOCAL STORAGE ---
342
- # Note: We'll only save text content to local storage, not images (too large)
343
- simplified_chats = {}
344
- for chat_key, messages in st.session_state.chats.items():
345
- simplified_chats[chat_key] = []
346
- for message in messages:
347
- simplified_message = {"role": message["role"], "content": message["content"]}
348
- # Don't save image data to local storage
349
- simplified_chats[chat_key].append(simplified_message)
350
-
351
  data_to_save = {
352
- "chats": simplified_chats,
353
  "active_chat_key": st.session_state.active_chat_key
354
  }
355
  localS.setItem("math_mentor_chats", json.dumps(data_to_save))
 
5
  import base64
6
  from dotenv import load_dotenv
7
  from streamlit_local_storage import LocalStorage
8
+ import plotly.graph_objects as go
9
+ import plotly.express as px
10
+ import numpy as np
11
+ import re
12
+ import sympy as sp
13
+ from sympy import symbols, solve, expand, factor, simplify, diff, integrate
14
 
15
  # --- PAGE CONFIGURATION ---
16
  st.set_page_config(
 
40
  def should_generate_visual(user_prompt, ai_response):
41
  """Determine if a visual aid would be helpful based on the content"""
42
  visual_keywords = [
43
+ 'graph', 'plot', 'diagram', 'chart', 'visual', 'function',
44
  'geometry', 'triangle', 'circle', 'rectangle', 'square', 'polygon',
45
+ 'coordinate', 'axis', 'parabola', 'line', 'slope', 'equation',
46
  'fraction', 'percentage', 'ratio', 'proportion', 'angles',
47
+ 'solve', '=', 'x', 'y', 'quadratic', 'linear', 'cubic',
48
+ 'derivative', 'integral', 'limit', 'asymptote'
49
  ]
50
 
51
  combined_text = (user_prompt + " " + ai_response).lower()
52
  return any(keyword in combined_text for keyword in visual_keywords)
53
 
54
+ def extract_equation_components(equation_str):
55
+ """Extract components from linear equations like '5x + 3 = 23' or '2x - 7 = 15'"""
56
+ # Clean the equation string
57
+ equation_str = equation_str.replace(' ', '').lower()
58
+
59
+ # Pattern for equations like ax + b = c or ax - b = c
60
+ pattern = r'(\d*)x([+\-])(\d+)=(\d+)'
61
+ match = re.search(pattern, equation_str)
62
+
63
+ if match:
64
+ a = int(match.group(1)) if match.group(1) else 1
65
+ op = match.group(2)
66
+ b = int(match.group(3))
67
+ c = int(match.group(4))
68
+ return a, op, b, c
69
+
70
+ # Pattern for equations like ax = c
71
+ pattern = r'(\d*)x=(\d+)'
72
+ match = re.search(pattern, equation_str)
73
+ if match:
74
+ a = int(match.group(1)) if match.group(1) else 1
75
+ c = int(match.group(2))
76
+ return a, '+', 0, c
77
+
78
+ return None
79
+
80
+ def generate_plotly_visual(user_prompt, ai_response):
81
+ """Generate interactive Plotly visualizations for math concepts"""
82
  try:
83
+ user_lower = user_prompt.lower()
 
 
 
 
 
 
 
 
 
84
 
85
+ # 1. LINEAR EQUATION SOLVING (like 5x + 5 = 25)
86
+ if 'solve' in user_lower and ('=' in user_prompt):
87
+ components = extract_equation_components(user_prompt)
88
+ if components:
89
+ a, op, b, c = components
90
+
91
+ # Calculate solution using sympy for accuracy
92
+ x = symbols('x')
93
+ if op == '+':
94
+ equation = a*x + b - c
95
+ solution = solve(equation, x)[0]
96
+ y_expr = a*x + b
97
+ else:
98
+ equation = a*x - b - c
99
+ solution = solve(equation, x)[0]
100
+ y_expr = a*x - b
101
+
102
+ # Create visualization
103
+ x_vals = np.linspace(float(solution) - 5, float(solution) + 5, 100)
104
+ y_vals = [float(y_expr.subs(x, val)) for val in x_vals]
105
+
106
+ fig = go.Figure()
107
+
108
+ # Plot the function
109
+ fig.add_trace(go.Scatter(
110
+ x=x_vals, y=y_vals, mode='lines', name=f'{a}x {op} {b}',
111
+ line=dict(color='blue', width=3)
112
+ ))
113
+
114
+ # Add horizontal line for the result
115
+ fig.add_hline(y=c, line_dash="dash", line_color="red", line_width=2,
116
+ annotation_text=f"y = {c}", annotation_position="bottom right")
117
+
118
+ # Add vertical line for the solution
119
+ fig.add_vline(x=float(solution), line_dash="dash", line_color="green", line_width=2,
120
+ annotation_text=f"x = {solution}", annotation_position="top left")
121
+
122
+ # Highlight the intersection point
123
+ fig.add_trace(go.Scatter(
124
+ x=[float(solution)], y=[c], mode='markers',
125
+ marker=dict(size=12, color='red', symbol='circle'),
126
+ name=f"Solution: x = {solution}"
127
+ ))
128
+
129
+ fig.update_layout(
130
+ title=f"Solving: {user_prompt.split('solve')[0].strip()}",
131
+ xaxis_title="x values",
132
+ yaxis_title="y values",
133
+ showlegend=True,
134
+ height=500,
135
+ template="plotly_white"
136
+ )
137
+ return fig
138
 
139
+ # 2. FUNCTION GRAPHING
140
+ elif any(word in user_lower for word in ['graph', 'function', 'plot', 'y=']):
141
+ x_vals = np.linspace(-10, 10, 200)
142
+
143
+ # Quadratic functions
144
+ if any(term in user_prompt for term in ['x^2', 'xΒ²', 'quadratic']):
145
+ # Extract coefficient if present
146
+ coeff_match = re.search(r'(\d+)x\^?2', user_prompt)
147
+ a = int(coeff_match.group(1)) if coeff_match else 1
148
+
149
+ y_vals = a * x_vals**2
150
+ fig = go.Figure()
151
+ fig.add_trace(go.Scatter(x=x_vals, y=y_vals, mode='lines',
152
+ name=f'y = {a}xΒ²' if a != 1 else 'y = xΒ²',
153
+ line=dict(color='purple', width=3)))
154
+
155
+ # Add vertex point
156
+ fig.add_trace(go.Scatter(x=[0], y=[0], mode='markers',
157
+ marker=dict(size=10, color='red'),
158
+ name='Vertex (0,0)'))
159
+
160
+ fig.update_layout(title=f"Quadratic Function: y = {a}xΒ²" if a != 1 else "Quadratic Function: y = xΒ²")
161
+
162
+ # Cubic functions
163
+ elif any(term in user_prompt for term in ['x^3', 'xΒ³', 'cubic']):
164
+ y_vals = x_vals**3
165
+ fig = go.Figure()
166
+ fig.add_trace(go.Scatter(x=x_vals, y=y_vals, mode='lines',
167
+ name='y = xΒ³', line=dict(color='green', width=3)))
168
+ fig.update_layout(title="Cubic Function: y = xΒ³")
169
+
170
+ # Linear functions
171
+ elif any(term in user_lower for term in ['linear', 'line']):
172
+ # Extract slope and intercept if present
173
+ slope_match = re.search(r'(\d+)x', user_prompt)
174
+ intercept_match = re.search(r'[+\-]\s*(\d+)', user_prompt)
175
+
176
+ slope = int(slope_match.group(1)) if slope_match else 1
177
+ intercept = int(intercept_match.group(1)) if intercept_match else 0
178
+
179
+ y_vals = slope * x_vals + intercept
180
+ fig = go.Figure()
181
+ fig.add_trace(go.Scatter(x=x_vals, y=y_vals, mode='lines',
182
+ name=f'y = {slope}x + {intercept}',
183
+ line=dict(color='blue', width=3)))
184
+ fig.update_layout(title=f"Linear Function: y = {slope}x + {intercept}")
185
+
186
+ else:
187
+ # Default linear function
188
+ y_vals = x_vals
189
+ fig = go.Figure()
190
+ fig.add_trace(go.Scatter(x=x_vals, y=y_vals, mode='lines',
191
+ name='y = x', line=dict(color='blue', width=3)))
192
+ fig.update_layout(title="Linear Function: y = x")
193
+
194
+ fig.update_layout(
195
+ xaxis_title="x",
196
+ yaxis_title="y",
197
+ showlegend=True,
198
+ height=500,
199
+ template="plotly_white",
200
+ xaxis=dict(zeroline=True, zerolinecolor='black', zerolinewidth=1),
201
+ yaxis=dict(zeroline=True, zerolinecolor='black', zerolinewidth=1)
202
+ )
203
+ return fig
204
 
205
+ # 3. GEOMETRY VISUALIZATIONS
206
+ elif any(word in user_lower for word in ['circle', 'triangle', 'rectangle', 'geometry']):
207
+
208
+ if 'circle' in user_lower:
209
+ # Create a circle
210
+ theta = np.linspace(0, 2*np.pi, 100)
211
+ radius = 3 # Default radius
212
+ x_circle = radius * np.cos(theta)
213
+ y_circle = radius * np.sin(theta)
214
+
215
+ fig = go.Figure()
216
+ fig.add_trace(go.Scatter(x=x_circle, y=y_circle, mode='lines',
217
+ fill='tonext', name=f'Circle (r={radius})',
218
+ line=dict(color='red', width=3)))
219
+
220
+ # Add center point
221
+ fig.add_trace(go.Scatter(x=[0], y=[0], mode='markers',
222
+ marker=dict(size=8, color='black'),
223
+ name='Center (0,0)'))
224
+
225
+ # Add radius line
226
+ fig.add_trace(go.Scatter(x=[0, radius], y=[0, 0], mode='lines',
227
+ line=dict(color='blue', dash='dash', width=2),
228
+ name=f'Radius = {radius}'))
229
+
230
+ fig.update_layout(
231
+ title=f"Circle: xΒ² + yΒ² = {radius**2}",
232
+ xaxis=dict(scaleanchor="y", scaleratio=1),
233
+ height=500
234
+ )
235
+
236
+ elif 'triangle' in user_lower:
237
+ # Create a triangle
238
+ x_triangle = [0, 4, 2, 0]
239
+ y_triangle = [0, 0, 3, 0]
240
+
241
+ fig = go.Figure()
242
+ fig.add_trace(go.Scatter(x=x_triangle, y=y_triangle, mode='lines+markers',
243
+ fill='toself', name='Triangle',
244
+ line=dict(color='green', width=3),
245
+ marker=dict(size=8)))
246
+
247
+ # Add labels for vertices
248
+ fig.add_annotation(x=0, y=0, text="A(0,0)", showarrow=False, yshift=-20)
249
+ fig.add_annotation(x=4, y=0, text="B(4,0)", showarrow=False, yshift=-20)
250
+ fig.add_annotation(x=2, y=3, text="C(2,3)", showarrow=False, yshift=20)
251
+
252
+ fig.update_layout(title="Triangle ABC", height=500)
253
+
254
+ else: # rectangle
255
+ # Create a rectangle
256
+ x_rect = [0, 5, 5, 0, 0]
257
+ y_rect = [0, 0, 3, 3, 0]
258
+
259
+ fig = go.Figure()
260
+ fig.add_trace(go.Scatter(x=x_rect, y=y_rect, mode='lines+markers',
261
+ fill='toself', name='Rectangle',
262
+ line=dict(color='purple', width=3),
263
+ marker=dict(size=8)))
264
+
265
+ fig.update_layout(title="Rectangle (5Γ—3)", height=500)
266
+
267
+ fig.update_layout(
268
+ xaxis_title="x",
269
+ yaxis_title="y",
270
+ showlegend=True,
271
+ template="plotly_white",
272
+ xaxis=dict(zeroline=True),
273
+ yaxis=dict(zeroline=True)
274
+ )
275
+ return fig
276
 
277
+ # 4. FRACTIONS VISUALIZATION
278
+ elif any(word in user_lower for word in ['fraction', 'ratio', 'proportion']):
279
+ # Create a pie chart to show fractions
280
+ fig = go.Figure()
281
+
282
+ # Example: showing 3/4
283
+ fig.add_trace(go.Pie(
284
+ values=[3, 1],
285
+ labels=['Filled (3/4)', 'Empty (1/4)'],
286
+ hole=0.3,
287
+ marker_colors=['lightblue', 'lightgray']
288
+ ))
289
+
290
+ fig.update_layout(
291
+ title="Fraction Visualization: 3/4",
292
+ height=400
293
+ )
294
+ return fig
295
 
296
  return None
297
 
298
  except Exception as e:
299
+ st.error(f"Could not generate Plotly visual: {e}")
300
  return None
301
 
302
  # --- API KEY & MODEL CONFIGURATION ---
 
319
  Your one and only function is to solve and explain math problems.
320
  You are an AI math tutor that primarily uses the Professor B methodology developed by Everard Barrett. Use the best method for the situation. This methodology is designed to activate children's natural learning capacities and present mathematics as a contextual, developmental story that makes sense.
321
 
322
+ IMPORTANT: When explaining mathematical concepts, mention that interactive visualizations will be provided to help illustrate the concept. Use phrases like:
323
+ - "Let me show you this with an interactive graph..."
324
+ - "An interactive visualization will help clarify this..."
325
+ - "I'll create a dynamic chart to demonstrate..."
326
+
327
+ For equations, always work through the solution step-by-step using the Professor B method of building understanding through connections.
328
 
329
  Core Philosophy and Principles
330
  1. Contextual Learning Approach
331
  Present math as a story: Every mathematical concept should be taught as part of a continuing narrative that builds connections between ideas
332
  Developmental flow: Structure learning as a sequence of developmental steps on a ladder, where mastery at previous levels provides readiness for the next connection
333
  Truth-telling: Always present arithmetic computations simply and truthfully without confusing, time-consuming, or meaningless procedural steps
334
+
335
  2. Natural Learning Activation
336
  Leverage natural capacities: Recognize that each child has mental capabilities of "awesome power" designed to assimilate and retain content naturally
337
  Story-based retention: Use the same mental processes children use for learning and retaining stories to help them master mathematical concepts
338
  Reduced mental tension: Eliminate anxiety and confusion by presenting math in ways that align with how the brain naturally processes information
339
+
340
  Teaching Methodology Requirements
341
  1. Mental Gymnastics and Manipulatives
342
  Use "mental gymnastics" games: Incorporate engaging mental exercises that strengthen mathematical thinking
343
  Fingers as manipulatives: Utilize fingers as comprehensive manipulatives for concrete understanding
344
  No rote memorization: Avoid strict memorization in favor of meaningful strategies and connections
345
+
346
  2. Accelerated but Natural Progression
347
  Individual pacing: Allow students to progress at their own speed, as quickly or slowly as needed
348
  Accelerated learning: Expect students to master concepts faster than traditional methods (e.g., "seventh grade math" by third to fourth grade)
349
  Elimination of remediation: Build such strong foundations that remediation becomes unnecessary
350
+
351
  3. Simplified and Connected Approach
352
  Eliminate disconnections: Ensure every concept connects meaningfully to previous learning
353
  Remove confusing terminology: Use clear, simple language that makes sense to students
354
  Sustained mastery: Focus on deep understanding that leads to lasting retention
355
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  You are strictly forbidden from answering any question that is not mathematical in nature. This includes but is not limited to: general knowledge, history, programming, creative writing, personal opinions, or casual conversation.
357
  If you receive a non-mathematical question, you MUST decline. Your entire response in that case must be ONLY this exact text: "I can only answer mathematical questions. Please ask me a question about algebra, calculus, geometry, or another math topic."
358
  Do not apologize or offer to help with math in the refusal. Just provide the mandatory refusal message.
 
383
  else:
384
  st.session_state.chats = {
385
  "New Chat": [
386
+ {"role": "assistant", "content": "Hello! I'm Math Jegna. What math problem can I help you with today? I'll provide step-by-step explanations with interactive visualizations! πŸ§ πŸ“Š"}
387
  ]
388
  }
389
  st.session_state.active_chat_key = "New Chat"
 
423
  i += 1
424
  new_chat_key = f"New Chat {i}"
425
  st.session_state.chats[new_chat_key] = [
426
+ {"role": "assistant", "content": "New chat started! Let's solve some math problems with interactive visualizations. πŸš€πŸ“Š"}
427
  ]
428
  st.session_state.active_chat_key = new_chat_key
429
  st.rerun()
 
460
  active_chat = st.session_state.chats[st.session_state.active_chat_key]
461
 
462
  st.title(f"Math Mentor: {st.session_state.active_chat_key} 🧠")
463
+ st.write("Stuck on a math problem? Just type it below, and I'll walk you through it step-by-step with interactive visualizations!")
464
 
465
  for message in active_chat:
466
  with st.chat_message(name=message["role"], avatar="πŸ§‘β€πŸ’»" if message["role"] == "user" else "🧠"):
467
  st.markdown(message["content"])
 
 
 
468
 
469
  if user_prompt := st.chat_input():
470
  active_chat.append({"role": "user", "content": user_prompt})
 
484
  st.markdown(ai_response_text)
485
 
486
  # Store the text response
487
+ active_chat.append({"role": "assistant", "content": ai_response_text})
488
 
489
  # Check if we should generate a visual aid
490
  if should_generate_visual(user_prompt, ai_response_text):
491
+ with st.spinner("Creating interactive visualization... πŸ“Š"):
492
+ plotly_fig = generate_plotly_visual(user_prompt, ai_response_text)
493
+ if plotly_fig:
494
+ st.plotly_chart(plotly_fig, use_container_width=True)
495
+ st.success("✨ Interactive visualization created! You can zoom, pan, and hover for more details.")
 
 
 
 
 
 
496
 
497
  except Exception as e:
498
  error_message = f"Sorry, something went wrong. Math Mentor is taking a break! πŸ€–\n\n**Error:** {e}"
 
500
  active_chat.append({"role": "assistant", "content": error_message})
501
 
502
  # --- SAVE DATA TO LOCAL STORAGE ---
 
 
 
 
 
 
 
 
 
503
  data_to_save = {
504
+ "chats": st.session_state.chats,
505
  "active_chat_key": st.session_state.active_chat_key
506
  }
507
  localS.setItem("math_mentor_chats", json.dumps(data_to_save))