jujutechnology commited on
Commit
87188de
Β·
verified Β·
1 Parent(s): eec5e4f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +87 -22
app.py CHANGED
@@ -178,6 +178,9 @@ def create_number_line(start, end, points, title="Number Line"):
178
  """(NEW & Dynamic) Creates a simple number line SVG."""
179
  width = 600
180
  padding = 30
 
 
 
181
  scale = (width - 2 * padding) / (end - start)
182
  def to_x(n): return padding + (n - start) * scale
183
  ticks_html = "".join([f'<g transform="translate({to_x(i)}, 50)"><line y2="10" stroke="#aaa"/><text y="30" text-anchor="middle" fill="#555">{i}</text></g>' for i in range(start, end + 1)])
@@ -186,12 +189,68 @@ def create_number_line(start, end, points, title="Number Line"):
186
  return html
187
 
188
  def create_place_value_blocks(number):
189
- """(Dynamic) Create place value blocks for understanding numbers."""
190
  hundreds, tens, ones = number // 100, (number % 100) // 10, number % 10
191
- h_html = f'<div style="text-align: center;"><h4>Hundreds: {hundreds}</h4><div style="display: flex; gap: 5px;">{"".join([f\'<div style="width: 100px; height: 100px; background: #FF6B6B; border: 2px solid #D63031; display: grid; grid-template-columns: repeat(10, 1fr); gap: 2px; padding: 2px;">{"".join(["<div style=\'background:#F5A6A6\'></div>"]*100)}</div>\' for _ in range(hundreds)])}</div></div>' if hundreds > 0 else ''
192
- t_html = f'<div style="text-align: center;"><h4>Tens: {tens}</h4><div style="display: flex; gap: 5px;">{"".join([f\'<div style="width: 10px; height: 100px; background: #4ECDC4; border: 2px solid #00B894; display: grid; grid-template-rows: repeat(10, 1fr); gap: 2px; padding: 2px;">{"".join(["<div style=\'background:#A2E8E4\'></div>"]*10)}</div>\' for _ in range(tens)])}</div></div>' if tens > 0 else ''
193
- o_html = f'<div style="text-align: center;"><h4>Ones: {ones}</h4><div style="display: flex; gap: 5px;">{"".join([f\'<div style="width: 10px; height: 10px; background: #FFE066; border: 2px solid #FDCB6E;"></div>\' for _ in range(ones)])}</div></div>' if ones > 0 else ''
194
- html = f"""<div style="padding: 20px; background: linear-gradient(135deg, #dfe6e9 0%, #b2bec3 100%); border-radius: 15px; margin: 10px 0;"><h3 style="color: #333; text-align: center;">Place Value Blocks for {number}</h3><div style="display: flex; justify-content: center; align-items: flex-end; gap: 20px; flex-wrap: wrap; padding: 20px 0;">{h_html}{t_html}{o_html}</div><div style="text-align: center; margin-top: 15px; padding: 10px; background: rgba(0,0,0,0.1); border-radius: 10px;"><h4 style="color: #333; margin:0;">{hundreds if hundreds else 0} Hundreds + {tens if tens else 0} Tens + {ones} Ones = {number}</h4></div></div>"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
195
  return html
196
 
197
  def create_shape_explorer():
@@ -206,10 +265,6 @@ def create_money_counter():
206
 
207
  # --- [The rest of your application code remains the same] ---
208
  # --- API KEY & MODEL CONFIGURATION, SESSION STATE, DIALOGS, etc. ---
209
- # ... (Paste the rest of your original app.py code from the "API KEY" section onwards here) ...
210
-
211
- # NOTE: For brevity, I am not repeating the entire second half of your app.
212
- # The code below is identical to your original file.
213
 
214
  # --- API KEY & MODEL CONFIGURATION ---
215
  load_dotenv()
@@ -225,7 +280,7 @@ if api_key:
225
 
226
  # Main text model
227
  model = genai.GenerativeModel(
228
- model_name="gemini-2.5-flash-lite",
229
  system_instruction="""
230
  You are "Math Jegna", an AI specializing exclusively in K-12 mathematics.
231
  Your one and only function is to solve and explain math problems for children.
@@ -239,7 +294,6 @@ if api_key:
239
  Focus on concepts appropriate for K-12 students:
240
  - Basic counting and number recognition
241
  - Simple addition and subtraction (using manipulatives)
242
- - Fractions as parts of wholes (pizza slices, etc.)
243
  - Multiplication as arrays or groups
244
  - Basic shapes and geometry
245
  - Place value with hundreds, tens, ones
@@ -392,9 +446,11 @@ with st.sidebar:
392
  if st.button("πŸ”— Share Chat", use_container_width=True):
393
  chat_json = json.dumps(st.session_state.chats[st.session_state.active_chat_key])
394
  chat_b64 = base64.urlsafe_b64encode(chat_json.encode()).decode()
395
- share_url = f"{st.get_option('server.baseUrlPath')}?shared_chat={chat_b64}"
 
396
  st.code(share_url)
397
- st.info("Copy the URL above to share this specific chat!")
 
398
 
399
  st.header(f"Chatting with Math Jegna: _{st.session_state.active_chat_key}_")
400
 
@@ -402,6 +458,9 @@ st.header(f"Chatting with Math Jegna: _{st.session_state.active_chat_key}_")
402
  for message in st.session_state.chats[st.session_state.active_chat_key]:
403
  with st.chat_message(message["role"]):
404
  st.markdown(message["content"])
 
 
 
405
 
406
  # User input
407
  if prompt := st.chat_input("Ask a K-8 math question..."):
@@ -430,18 +489,24 @@ if prompt := st.chat_input("Ask a K-8 math question..."):
430
  response_container.markdown(full_response + " β–Œ")
431
  response_container.markdown(full_response)
432
 
433
- # After generating text, decide if a visual is needed
 
434
  if should_generate_visual(prompt, full_response):
435
- visual_html = create_visual_manipulative(prompt, full_response)
436
- if visual_html:
437
- # Display the generated HTML/SVG visual
438
- components.html(visual_html, height=400, scrolling=True)
 
 
 
 
 
 
439
 
440
- # Add AI response to session state
441
- st.session_state.chats[st.session_state.active_chat_key].append({"role": "assistant", "content": full_response})
442
 
443
  except genai.types.generation_types.BlockedPromptException as e:
444
- st.error("I can only answer math questions for students. Please ask me about numbers, shapes, or other math topics!")
445
- st.session_state.chats[st.session_state.active_chat_key].append({"role": "assistant", "content": "I can only answer math questions for students. Please ask me about numbers, shapes, or other math topics!"})
 
446
  except Exception as e:
447
  st.error(f"An error occurred: {e}")
 
178
  """(NEW & Dynamic) Creates a simple number line SVG."""
179
  width = 600
180
  padding = 30
181
+ # Handle the edge case where start equals end
182
+ if start >= end:
183
+ end = start + 1
184
  scale = (width - 2 * padding) / (end - start)
185
  def to_x(n): return padding + (n - start) * scale
186
  ticks_html = "".join([f'<g transform="translate({to_x(i)}, 50)"><line y2="10" stroke="#aaa"/><text y="30" text-anchor="middle" fill="#555">{i}</text></g>' for i in range(start, end + 1)])
 
189
  return html
190
 
191
  def create_place_value_blocks(number):
192
+ """(FIXED & Dynamic) Create place value blocks for understanding numbers."""
193
  hundreds, tens, ones = number // 100, (number % 100) // 10, number % 10
194
+
195
+ # --- Hundreds Block HTML ---
196
+ h_block_html = ""
197
+ if hundreds > 0:
198
+ hundreds_grid = "".join(["<div style='background:#F5A6A6'></div>"] * 100)
199
+ hundreds_squares = "".join([f"""
200
+ <div style="width: 100px; height: 100px; background: #FF6B6B; border: 2px solid #D63031; display: grid; grid-template-columns: repeat(10, 1fr); gap: 2px; padding: 2px;">
201
+ {hundreds_grid}
202
+ </div>
203
+ """ for _ in range(hundreds)])
204
+ h_block_html = f"""
205
+ <div style="text-align: center;">
206
+ <h4>Hundreds: {hundreds}</h4>
207
+ <div style="display: flex; gap: 5px;">{hundreds_squares}</div>
208
+ </div>
209
+ """
210
+
211
+ # --- Tens Block HTML ---
212
+ t_block_html = ""
213
+ if tens > 0:
214
+ tens_grid = "".join(["<div style='background:#A2E8E4'></div>"] * 10)
215
+ tens_sticks = "".join([f"""
216
+ <div style="width: 10px; height: 100px; background: #4ECDC4; border: 2px solid #00B894; display: grid; grid-template-rows: repeat(10, 1fr); gap: 2px; padding: 2px;">
217
+ {tens_grid}
218
+ </div>
219
+ """ for _ in range(tens)])
220
+ t_block_html = f"""
221
+ <div style="text-align: center;">
222
+ <h4>Tens: {tens}</h4>
223
+ <div style="display: flex; gap: 5px; align-items: flex-end;">{tens_sticks}</div>
224
+ </div>
225
+ """
226
+
227
+ # --- Ones Block HTML ---
228
+ o_block_html = ""
229
+ if ones > 0:
230
+ ones_cubes = "".join(['<div style="width: 10px; height: 10px; background: #FFE066; border: 2px solid #FDCB6E;"></div>' for _ in range(ones)])
231
+ o_block_html = f"""
232
+ <div style="text-align: center;">
233
+ <h4>Ones: {ones}</h4>
234
+ <div style="display: flex; gap: 5px; align-items: flex-end; flex-wrap: wrap; width: 50px; justify-content: center;">{ones_cubes}</div>
235
+ </div>
236
+ """
237
+
238
+ # --- Final Assembly ---
239
+ html = f"""
240
+ <div style="padding: 20px; background: linear-gradient(135deg, #dfe6e9 0%, #b2bec3 100%); border-radius: 15px; margin: 10px 0;">
241
+ <h3 style="color: #333; text-align: center;">Place Value Blocks for {number}</h3>
242
+ <div style="display: flex; justify-content: center; align-items: flex-end; gap: 20px; flex-wrap: wrap; padding: 20px 0; min-height: 150px;">
243
+ {h_block_html}
244
+ {t_block_html}
245
+ {o_block_html}
246
+ </div>
247
+ <div style="text-align: center; margin-top: 15px; padding: 10px; background: rgba(0,0,0,0.1); border-radius: 10px;">
248
+ <h4 style="color: #333; margin:0;">
249
+ {hundreds} Hundreds + {tens} Tens + {ones} Ones = {number}
250
+ </h4>
251
+ </div>
252
+ </div>
253
+ """
254
  return html
255
 
256
  def create_shape_explorer():
 
265
 
266
  # --- [The rest of your application code remains the same] ---
267
  # --- API KEY & MODEL CONFIGURATION, SESSION STATE, DIALOGS, etc. ---
 
 
 
 
268
 
269
  # --- API KEY & MODEL CONFIGURATION ---
270
  load_dotenv()
 
280
 
281
  # Main text model
282
  model = genai.GenerativeModel(
283
+ model_name="gemini-1.5-flash",
284
  system_instruction="""
285
  You are "Math Jegna", an AI specializing exclusively in K-12 mathematics.
286
  Your one and only function is to solve and explain math problems for children.
 
294
  Focus on concepts appropriate for K-12 students:
295
  - Basic counting and number recognition
296
  - Simple addition and subtraction (using manipulatives)
 
297
  - Multiplication as arrays or groups
298
  - Basic shapes and geometry
299
  - Place value with hundreds, tens, ones
 
446
  if st.button("πŸ”— Share Chat", use_container_width=True):
447
  chat_json = json.dumps(st.session_state.chats[st.session_state.active_chat_key])
448
  chat_b64 = base64.urlsafe_b64encode(chat_json.encode()).decode()
449
+ # This part might need adjustment depending on how Streamlit Community Cloud handles base URLs
450
+ share_url = f"https://huggingface.co/spaces/YOUR_SPACE_HERE?shared_chat={chat_b64}" # Placeholder
451
  st.code(share_url)
452
+ st.info("Copy the URL above to share this specific chat! (You might need to update the base URL)")
453
+
454
 
455
  st.header(f"Chatting with Math Jegna: _{st.session_state.active_chat_key}_")
456
 
 
458
  for message in st.session_state.chats[st.session_state.active_chat_key]:
459
  with st.chat_message(message["role"]):
460
  st.markdown(message["content"])
461
+ # If a visual was generated and saved with the message, display it
462
+ if "visual_html" in message and message["visual_html"]:
463
+ components.html(message["visual_html"], height=400, scrolling=True)
464
 
465
  # User input
466
  if prompt := st.chat_input("Ask a K-8 math question..."):
 
489
  response_container.markdown(full_response + " β–Œ")
490
  response_container.markdown(full_response)
491
 
492
+ # After generating text, decide if a visual is needed and generate it
493
+ visual_html_content = None
494
  if should_generate_visual(prompt, full_response):
495
+ visual_html_content = create_visual_manipulative(prompt, full_response)
496
+ if visual_html_content:
497
+ components.html(visual_html_content, height=400, scrolling=True)
498
+
499
+ # Add AI response and visual to session state
500
+ st.session_state.chats[st.session_state.active_chat_key].append({
501
+ "role": "assistant",
502
+ "content": full_response,
503
+ "visual_html": visual_html_content # Store the visual with the message
504
+ })
505
 
 
 
506
 
507
  except genai.types.generation_types.BlockedPromptException as e:
508
+ error_message = "I can only answer math questions for students. Please ask me about numbers, shapes, or other math topics!"
509
+ st.error(error_message)
510
+ st.session_state.chats[st.session_state.active_chat_key].append({"role": "assistant", "content": error_message, "visual_html": None})
511
  except Exception as e:
512
  st.error(f"An error occurred: {e}")