sunbal7 commited on
Commit
c969520
·
verified ·
1 Parent(s): 88248b0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +167 -155
app.py CHANGED
@@ -1,18 +1,15 @@
1
- # app.py - Final Deployment-Ready Version
2
  import streamlit as st
3
  import os
4
  import time
5
- import base64
6
  import random
7
- import tempfile
8
- import subprocess
9
  import numpy as np
10
- import pygame
11
- import sys
12
- import imageio
 
13
  from PIL import Image
14
  import io
15
- import matplotlib.pyplot as plt
16
 
17
  # Configure Streamlit page
18
  st.set_page_config(
@@ -131,6 +128,13 @@ st.markdown("""
131
  overflow: hidden;
132
  margin: 0 auto;
133
  display: block;
 
 
 
 
 
 
 
134
  }
135
  </style>
136
  """, unsafe_allow_html=True)
@@ -175,16 +179,16 @@ CONCEPTS = {
175
  }
176
 
177
  # Character database
178
- CHARACTERS = {
179
- "rabbit": {"color": (255, 150, 150), "speed": 5, "size": 30},
180
- "dragon": {"color": (255, 100, 100), "speed": 3, "size": 60},
181
- "cat": {"color": (200, 150, 255), "speed": 6, "size": 25},
182
- "dog": {"color": (255, 200, 150), "speed": 7, "size": 35},
183
- "knight": {"color": (150, 200, 255), "speed": 4, "size": 40},
184
- "wizard": {"color": (200, 255, 150), "speed": 4, "size": 35},
185
- "scientist": {"color": (150, 255, 200), "speed": 5, "size": 30},
186
- "pirate": {"color": (255, 255, 150), "speed": 5, "size": 40}
187
- }
188
 
189
  def analyze_story(story):
190
  """Analyze story and identify programming concepts"""
@@ -213,101 +217,87 @@ def analyze_story(story):
213
 
214
  return list(set(detected_concepts))
215
 
216
- def generate_pygame_animation(story, concepts):
217
- """Generate PyGame animation based on story and concepts"""
 
 
 
 
 
 
 
218
  try:
219
  # Choose a random character
220
- character = random.choice(list(CHARACTERS.keys()))
221
- char_details = CHARACTERS[character]
222
-
223
- # Extract count from story
224
- count = 3
225
- for word in story.split():
226
- if word.isdigit():
227
- count = min(int(word), 10)
228
- break
229
-
230
- # Create a temporary file for the animation
231
- with tempfile.NamedTemporaryFile(suffix=".gif", delete=False) as tmpfile:
232
- gif_path = tmpfile.name
233
-
234
- # Set up PyGame in headless mode
235
- os.environ['SDL_VIDEODRIVER'] = 'dummy'
236
- pygame.init()
237
- pygame.display.set_mode((1, 1)) # Tiny invisible window
238
-
239
- # Animation settings
240
- WIDTH, HEIGHT = 800, 600
241
- screen = pygame.Surface((WIDTH, HEIGHT))
242
- clock = pygame.time.Clock()
243
- frames = []
244
-
245
- # Colors
246
- BACKGROUND = (25, 25, 50)
247
- GROUND = (40, 100, 40)
248
- SUN = (255, 255, 200)
249
-
250
- # Character setup
251
- char_x = 100
252
- char_y = HEIGHT - 100
253
- target_x = 700
254
- target_y = HEIGHT - 100
255
- hops = 0
256
- hop_height = 0
257
-
258
- # Animation loop
259
- for frame in range(120):
260
- # Clear screen
261
- screen.fill(BACKGROUND)
262
-
263
- # Draw ground
264
- pygame.draw.rect(screen, GROUND, (0, HEIGHT - 50, WIDTH, 50))
265
-
266
- # Draw sun
267
- pygame.draw.circle(screen, SUN, (700, 100), 50)
268
-
269
- # Draw target
270
- pygame.draw.circle(screen, (255, 200, 100), (target_x, target_y), 30)
271
- pygame.draw.circle(screen, (255, 150, 50), (target_x, target_y), 20)
272
- pygame.draw.circle(screen, (255, 100, 0), (target_x, target_y), 10)
273
 
274
- # Move character
275
- if hops < count:
276
- char_x += char_details["speed"]
 
277
  # Hop animation
278
- hop_height = 50 * np.sin(frame * 0.2)
279
- char_y = HEIGHT - 100 - abs(hop_height)
 
 
280
 
281
- # Check if target reached
282
- if char_x >= target_x - 40:
283
- hops += 1
284
- char_x = 100
285
-
286
- # Draw character
287
- pygame.draw.circle(screen, char_details["color"], (int(char_x), int(char_y)), char_details["size"])
288
 
289
- # Draw eyes
290
- pygame.draw.circle(screen, (255, 255, 255), (int(char_x + 10), int(char_y - 5)), 8)
291
- pygame.draw.circle(screen, (0, 0, 0), (int(char_x + 10), int(char_y - 5)), 4)
 
 
292
 
293
- # Draw hop counter
294
- font = pygame.font.SysFont(None, 36)
295
- text = font.render(f"Hops: {hops}/{count}", True, (255, 255, 255))
296
- screen.blit(text, (20, 20))
297
-
298
- # Draw story text
299
- story_text = font.render(story[:40] + ("..." if len(story) > 40 else ""), True, (200, 200, 255))
300
- screen.blit(story_text, (WIDTH//2 - story_text.get_width()//2, 50))
301
-
302
- # Capture frame
303
- frame_data = pygame.surfarray.array3d(screen).swapaxes(0, 1)
304
- frames.append(frame_data)
305
-
306
- clock.tick(30)
307
 
308
- # Save as GIF
309
- imageio.mimsave(gif_path, frames, fps=30)
310
- return gif_path
 
311
 
312
  except Exception as e:
313
  st.error(f"Animation error: {str(e)}")
@@ -343,7 +333,7 @@ def create_story_image(story):
343
  lines.append(' '.join(current_line))
344
 
345
  for i, line in enumerate(lines):
346
- ax.text(5, 6.5 - i*0.7, line, fontsize=14, ha='center')
347
 
348
  # Add decoration
349
  ax.text(2, 2, '🐰', fontsize=40, ha='center')
@@ -353,12 +343,11 @@ def create_story_image(story):
353
 
354
  # Save to buffer
355
  buf = io.BytesIO()
356
- plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0.5)
357
  buf.seek(0)
358
- image = Image.open(buf)
359
  plt.close()
360
-
361
- return image
362
  except Exception as e:
363
  st.error(f"Image generation error: {str(e)}")
364
  return None
@@ -373,8 +362,8 @@ def main():
373
  st.session_state.story = ""
374
  if 'concepts' not in st.session_state:
375
  st.session_state.concepts = []
376
- if 'animation_path' not in st.session_state:
377
- st.session_state.animation_path = None
378
  if 'active_tab' not in st.session_state:
379
  st.session_state.active_tab = "story"
380
 
@@ -397,7 +386,7 @@ def main():
397
  if st.button("🔄 Reset"):
398
  st.session_state.story = ""
399
  st.session_state.concepts = []
400
- st.session_state.animation_path = None
401
  st.session_state.active_tab = "story"
402
 
403
  # Story creation tab
@@ -422,8 +411,8 @@ def main():
422
  with st.spinner("🧠 Analyzing your story for coding concepts..."):
423
  st.session_state.concepts = analyze_story(story)
424
 
425
- with st.spinner("🎬 Creating your animation (this may take a moment)..."):
426
- st.session_state.animation_path = generate_pygame_animation(
427
  story, st.session_state.concepts
428
  )
429
 
@@ -447,7 +436,7 @@ def main():
447
  elif st.session_state.active_tab == "animation":
448
  st.header("🎬 Your Story Animation")
449
 
450
- if not st.session_state.animation_path:
451
  st.warning("Please create a story first!")
452
  st.session_state.active_tab = "story"
453
  st.rerun()
@@ -459,13 +448,13 @@ def main():
459
  </div>
460
  """, unsafe_allow_html=True)
461
 
462
- try:
463
- st.image(st.session_state.animation_path, use_container_width=True)
464
- except Exception as e:
465
- st.error(f"Couldn't display animation: {str(e)}")
466
- story_image = create_story_image(st.session_state.story)
467
- if story_image:
468
- st.image(story_image, use_container_width=True)
469
 
470
  st.success("✨ Animation created successfully!")
471
  st.caption("This animation was generated with Python code based on your story!")
@@ -506,42 +495,65 @@ def main():
506
  st.write("Here's the Python code that created your animation:")
507
 
508
  # Sample code (in a real app, you would generate this based on the story)
509
- sample_code = """
510
- # Story: {story}
 
 
 
511
 
512
- import pygame
 
513
  import numpy as np
514
- import imageio
515
 
516
- def create_animation(story):
517
- # Setup PyGame
518
- pygame.init()
519
- WIDTH, HEIGHT = 800, 600
520
- screen = pygame.Surface((WIDTH, HEIGHT))
521
-
522
- # Animation parameters based on story
523
- character = "{character}"
524
- count = {count}
525
-
526
- # Animation loop
527
- frames = []
528
- for frame in range(120):
529
- # Draw background, character, etc.
530
- # ... animation code ...
531
-
532
- # Capture frame
533
- frame_data = pygame.surfarray.array3d(screen)
534
- frames.append(frame_data)
535
-
536
- # Save animation
537
- imageio.mimsave('animation.gif', frames, fps=30)
538
 
539
- create_animation("{story}")
540
- """.format(
541
- story=st.session_state.story[:50] + ("..." if len(st.session_state.story) > 50 else ""),
542
- character=random.choice(list(CHARACTERS.keys())),
543
- count=min([int(word) for word in st.session_state.story.split() if word.isdigit()] or [3])
544
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
545
 
546
  st.code(sample_code, language="python")
547
 
 
1
+ # app.py - Final Working Version
2
  import streamlit as st
3
  import os
4
  import time
 
5
  import random
 
 
6
  import numpy as np
7
+ import matplotlib.pyplot as plt
8
+ from matplotlib.animation import FuncAnimation
9
+ from matplotlib import rc
10
+ import base64
11
  from PIL import Image
12
  import io
 
13
 
14
  # Configure Streamlit page
15
  st.set_page_config(
 
128
  overflow: hidden;
129
  margin: 0 auto;
130
  display: block;
131
+ max-width: 100%;
132
+ }
133
+
134
+ .character {
135
+ font-size: 48px;
136
+ text-align: center;
137
+ margin: 10px 0;
138
  }
139
  </style>
140
  """, unsafe_allow_html=True)
 
179
  }
180
 
181
  # Character database
182
+ CHARACTERS = [
183
+ {"name": "rabbit", "emoji": "🐰", "color": "#FFB6C1"},
184
+ {"name": "dragon", "emoji": "🐉", "color": "#FF6347"},
185
+ {"name": "cat", "emoji": "🐱", "color": "#DDA0DD"},
186
+ {"name": "dog", "emoji": "🐶", "color": "#FFD700"},
187
+ {"name": "knight", "emoji": "🤺", "color": "#87CEEB"},
188
+ {"name": "wizard", "emoji": "🧙", "color": "#98FB98"},
189
+ {"name": "scientist", "emoji": "🔬", "color": "#20B2AA"},
190
+ {"name": "pirate", "emoji": "🏴‍☠️", "color": "#FFA500"}
191
+ ]
192
 
193
  def analyze_story(story):
194
  """Analyze story and identify programming concepts"""
 
217
 
218
  return list(set(detected_concepts))
219
 
220
+ def extract_count_from_story(story):
221
+ """Extract a number from the story to use in animations"""
222
+ for word in story.split():
223
+ if word.isdigit():
224
+ return min(int(word), 10)
225
+ return 3 # Default value
226
+
227
+ def create_animation(story, concepts):
228
+ """Create a matplotlib animation based on the story and concepts"""
229
  try:
230
  # Choose a random character
231
+ character = random.choice(CHARACTERS)
232
+ count = extract_count_from_story(story)
233
+
234
+ # Create figure and axis
235
+ fig, ax = plt.subplots(figsize=(10, 6), facecolor='#f0f8ff')
236
+ ax.set_xlim(0, 10)
237
+ ax.set_ylim(0, 10)
238
+ ax.axis('off')
239
+
240
+ # Add title
241
+ fig.suptitle('Your Story Animation', fontsize=20, color='purple', fontweight='bold')
242
+
243
+ # Add story text
244
+ ax.text(5, 9, f'"{story[:50]}{"..." if len(story) > 50 else ""}"',
245
+ fontsize=14, ha='center', wrap=True, color='#333')
246
+
247
+ # Character position
248
+ x_pos = 5
249
+ y_pos = 6
250
+
251
+ # Create character element
252
+ char_text = ax.text(x_pos, y_pos, character["emoji"],
253
+ fontsize=48, ha='center', color=character["color"])
254
+
255
+ # Target position
256
+ target_x = 8
257
+ target_y = 6
258
+ ax.plot(target_x, target_y, 'ro', markersize=15, alpha=0.5)
259
+ ax.text(target_x, target_y - 0.8, 'Target', ha='center', fontsize=12)
260
+
261
+ # Add hop counter
262
+ counter_text = ax.text(2, 8, f'Hops: 0/{count}', fontsize=16, color='#333')
263
+
264
+ # Animation function
265
+ def animate(frame):
266
+ nonlocal x_pos, y_pos
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
267
 
268
+ # Move character toward target
269
+ if frame < count:
270
+ x_pos += 0.3
271
+
272
  # Hop animation
273
+ if frame % 2 == 0:
274
+ y_pos = 6.5
275
+ else:
276
+ y_pos = 6
277
 
278
+ char_text.set_position((x_pos, y_pos))
279
+ counter_text.set_text(f'Hops: {frame+1}/{count}')
 
 
 
 
 
280
 
281
+ # Return to start after reaching target
282
+ elif frame == count:
283
+ x_pos = 5
284
+ y_pos = 6
285
+ char_text.set_position((x_pos, y_pos))
286
 
287
+ return char_text, counter_text
288
+
289
+ # Create animation
290
+ ani = FuncAnimation(fig, animate, frames=count*2, interval=500, blit=True)
291
+
292
+ # Save animation as GIF in memory
293
+ buf = io.BytesIO()
294
+ ani.save(buf, format='gif', writer='pillow', fps=2)
295
+ buf.seek(0)
 
 
 
 
 
296
 
297
+ # Close the figure to free memory
298
+ plt.close(fig)
299
+
300
+ return buf
301
 
302
  except Exception as e:
303
  st.error(f"Animation error: {str(e)}")
 
333
  lines.append(' '.join(current_line))
334
 
335
  for i, line in enumerate(lines):
336
+ ax.text(5, 6.5 - i*0.7, line, fontsize=14, ha='center', color='#333')
337
 
338
  # Add decoration
339
  ax.text(2, 2, '🐰', fontsize=40, ha='center')
 
343
 
344
  # Save to buffer
345
  buf = io.BytesIO()
346
+ plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0.5, dpi=100)
347
  buf.seek(0)
 
348
  plt.close()
349
+ return buf
350
+
351
  except Exception as e:
352
  st.error(f"Image generation error: {str(e)}")
353
  return None
 
362
  st.session_state.story = ""
363
  if 'concepts' not in st.session_state:
364
  st.session_state.concepts = []
365
+ if 'animation' not in st.session_state:
366
+ st.session_state.animation = None
367
  if 'active_tab' not in st.session_state:
368
  st.session_state.active_tab = "story"
369
 
 
386
  if st.button("🔄 Reset"):
387
  st.session_state.story = ""
388
  st.session_state.concepts = []
389
+ st.session_state.animation = None
390
  st.session_state.active_tab = "story"
391
 
392
  # Story creation tab
 
411
  with st.spinner("🧠 Analyzing your story for coding concepts..."):
412
  st.session_state.concepts = analyze_story(story)
413
 
414
+ with st.spinner("🎬 Creating your animation..."):
415
+ st.session_state.animation = create_animation(
416
  story, st.session_state.concepts
417
  )
418
 
 
436
  elif st.session_state.active_tab == "animation":
437
  st.header("🎬 Your Story Animation")
438
 
439
+ if not st.session_state.story:
440
  st.warning("Please create a story first!")
441
  st.session_state.active_tab = "story"
442
  st.rerun()
 
448
  </div>
449
  """, unsafe_allow_html=True)
450
 
451
+ if st.session_state.animation:
452
+ st.image(st.session_state.animation, use_container_width=True)
453
+ else:
454
+ st.warning("Animation couldn't be generated. Showing story image instead.")
455
+ story_img = create_story_image(st.session_state.story)
456
+ if story_img:
457
+ st.image(story_img, use_container_width=True)
458
 
459
  st.success("✨ Animation created successfully!")
460
  st.caption("This animation was generated with Python code based on your story!")
 
495
  st.write("Here's the Python code that created your animation:")
496
 
497
  # Sample code (in a real app, you would generate this based on the story)
498
+ count = extract_count_from_story(st.session_state.story)
499
+ character = random.choice(CHARACTERS)
500
+
501
+ sample_code = f"""
502
+ # Story: {st.session_state.story[:50]}{'...' if len(st.session_state.story) > 50 else ''}
503
 
504
+ import matplotlib.pyplot as plt
505
+ from matplotlib.animation import FuncAnimation
506
  import numpy as np
 
507
 
508
+ # Setup the figure
509
+ fig, ax = plt.subplots(figsize=(10, 6))
510
+ ax.set_xlim(0, 10)
511
+ ax.set_ylim(0, 10)
512
+ ax.axis('off')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
513
 
514
+ # Add story text
515
+ ax.text(5, 9, "{st.session_state.story[:50]}{'...' if len(st.session_state.story) > 50 else ''}",
516
+ fontsize=14, ha='center', wrap=True)
517
+
518
+ # Add character
519
+ char = ax.text(5, 6, "{character['emoji']}", fontsize=48, ha='center', color='{character['color']}')
520
+
521
+ # Add target
522
+ ax.plot(8, 6, 'ro', markersize=15, alpha=0.5)
523
+ ax.text(8, 5.2, 'Target', ha='center', fontsize=12)
524
+
525
+ # Add counter
526
+ counter = ax.text(2, 8, 'Hops: 0/{count}', fontsize=16)
527
+
528
+ # Animation function
529
+ def animate(frame):
530
+ x = char.get_position()[0]
531
+
532
+ # Move character toward target
533
+ if frame < {count}:
534
+ new_x = x + 0.3
535
+
536
+ # Hop animation
537
+ if frame % 2 == 0:
538
+ new_y = 6.5
539
+ else:
540
+ new_y = 6
541
+
542
+ char.set_position((new_x, new_y))
543
+ counter.set_text(f'Hops: {{frame+1}}/{count}')
544
+
545
+ # Return to start after reaching target
546
+ elif frame == {count}:
547
+ char.set_position((5, 6))
548
+
549
+ return char, counter
550
+
551
+ # Create and save animation
552
+ ani = FuncAnimation(fig, animate, frames={count*2}, interval=500, blit=True)
553
+ ani.save('animation.gif', writer='pillow', fps=2)
554
+
555
+ plt.close()
556
+ """
557
 
558
  st.code(sample_code, language="python")
559