sunbal7 commited on
Commit
34f7b23
·
verified ·
1 Parent(s): 2d70a3f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +149 -385
app.py CHANGED
@@ -1,3 +1,4 @@
 
1
  import streamlit as st
2
  import os
3
  import time
@@ -7,10 +8,11 @@ import tempfile
7
  import subprocess
8
  import numpy as np
9
  import pygame
10
- import matplotlib.pyplot as plt
 
11
  from PIL import Image
12
  import io
13
- from manim import *
14
 
15
  # Configure Streamlit page
16
  st.set_page_config(
@@ -184,256 +186,6 @@ CHARACTERS = {
184
  "pirate": {"color": (255, 255, 150), "speed": 5, "size": 40}
185
  }
186
 
187
- # Animation templates
188
- ANIMATION_TEMPLATES = {
189
- "loop": {
190
- "pygame": """
191
- import pygame
192
- import sys
193
- import math
194
-
195
- # Initialize pygame
196
- pygame.init()
197
-
198
- # Screen setup
199
- WIDTH, HEIGHT = 800, 600
200
- screen = pygame.display.set_mode((WIDTH, HEIGHT))
201
- pygame.display.set_caption("Your Story Animation")
202
-
203
- # Colors
204
- BACKGROUND = (25, 25, 50)
205
- GROUND = (40, 100, 40)
206
- SUN = (255, 255, 200)
207
-
208
- # Character setup
209
- character = "{character}"
210
- char_color = {char_color}
211
- char_size = {char_size}
212
- char_x = 100
213
- char_y = HEIGHT - 100
214
- char_speed = {char_speed}
215
-
216
- # Target setup
217
- target_x = 700
218
- target_y = HEIGHT - 100
219
- target_reached = False
220
- hops = 0
221
-
222
- # Animation clock
223
- clock = pygame.time.Clock()
224
- frames = []
225
-
226
- # Main animation loop
227
- for frame in range(120):
228
- for event in pygame.event.get():
229
- if event.type == pygame.QUIT:
230
- pygame.quit()
231
- sys.exit()
232
-
233
- # Clear screen
234
- screen.fill(BACKGROUND)
235
-
236
- # Draw ground
237
- pygame.draw.rect(screen, GROUND, (0, HEIGHT - 50, WIDTH, 50))
238
-
239
- # Draw sun
240
- pygame.draw.circle(screen, SUN, (700, 100), 50)
241
-
242
- # Draw target
243
- pygame.draw.circle(screen, (255, 200, 100), (target_x, target_y), 30)
244
- pygame.draw.circle(screen, (255, 150, 50), (target_x, target_y), 20)
245
- pygame.draw.circle(screen, (255, 100, 0), (target_x, target_y), 10)
246
-
247
- # Move character
248
- if not target_reached:
249
- char_x += char_speed
250
- # Hop animation
251
- hop_height = 50 * math.sin(frame * 0.2)
252
- char_y = HEIGHT - 100 - abs(hop_height)
253
-
254
- # Check if target reached
255
- if char_x >= target_x - 40:
256
- hops += 1
257
- char_x = 100
258
- if hops >= {count}:
259
- target_reached = True
260
-
261
- # Draw character
262
- pygame.draw.circle(screen, char_color, (int(char_x), int(char_y)), char_size)
263
-
264
- # Draw eyes
265
- pygame.draw.circle(screen, (255, 255, 255), (int(char_x + 10), int(char_y - 5)), 8)
266
- pygame.draw.circle(screen, (0, 0, 0), (int(char_x + 10), int(char_y - 5)), 4)
267
-
268
- # Draw hop counter
269
- font = pygame.font.SysFont(None, 36)
270
- text = font.render(f"Hops: {{hops}}/{{count}}", True, (255, 255, 255))
271
- screen.blit(text, (20, 20))
272
-
273
- # Capture frame
274
- frames.append(pygame.surfarray.array3d(screen).swapaxes(0, 1))
275
-
276
- pygame.display.flip()
277
- clock.tick(30)
278
-
279
- # Save animation as GIF
280
- import imageio
281
- imageio.mimsave('animation.gif', frames, fps=30)
282
- """
283
- },
284
- "conditional": {
285
- "pygame": """
286
- import pygame
287
- import sys
288
-
289
- # Initialize pygame
290
- pygame.init()
291
-
292
- # Screen setup
293
- WIDTH, HEIGHT = 800, 600
294
- screen = pygame.display.set_mode((WIDTH, HEIGHT))
295
- pygame.display.set_caption("Your Story Animation")
296
-
297
- # Colors
298
- BACKGROUND = (25, 25, 50)
299
- GROUND = (40, 100, 40)
300
- CHEST_COLOR = (139, 69, 19)
301
- LOCK_COLOR = (192, 192, 192)
302
- TREASURE_COLOR = (255, 215, 0)
303
-
304
- # Knight setup
305
- knight_x = 100
306
- knight_y = HEIGHT - 100
307
- knight_speed = 4
308
- knight_size = 40
309
- knight_color = (100, 150, 255)
310
-
311
- # Chest setup
312
- chest_x = 600
313
- chest_y = HEIGHT - 100
314
- chest_width = 80
315
- chest_height = 50
316
- is_unlocked = {condition}
317
-
318
- # Animation clock
319
- clock = pygame.time.Clock()
320
- frames = []
321
-
322
- # Main animation loop
323
- for frame in range(180):
324
- for event in pygame.event.get():
325
- if event.type == pygame.QUIT:
326
- pygame.quit()
327
- sys.exit()
328
-
329
- # Clear screen
330
- screen.fill(BACKGROUND)
331
-
332
- # Draw ground
333
- pygame.draw.rect(screen, GROUND, (0, HEIGHT - 50, WIDTH, 50))
334
-
335
- # Draw chest
336
- pygame.draw.rect(screen, CHEST_COLOR, (chest_x, chest_y, chest_width, chest_height))
337
- pygame.draw.rect(screen, (101, 67, 33), (chest_x, chest_y, chest_width, 20))
338
-
339
- # Draw lock or treasure
340
- if not is_unlocked:
341
- pygame.draw.rect(screen, LOCK_COLOR, (chest_x + chest_width//2 - 10, chest_y - 15, 20, 15))
342
- pygame.draw.circle(screen, LOCK_COLOR, (chest_x + chest_width//2, chest_y - 15), 8)
343
- else:
344
- pygame.draw.rect(screen, (255, 223, 0), (chest_x + 10, chest_y + 10, 20, 30))
345
- pygame.draw.rect(screen, (218, 165, 32), (chest_x + 50, chest_y + 15, 20, 20))
346
-
347
- # Move knight
348
- if knight_x < chest_x - 100:
349
- knight_x += knight_speed
350
-
351
- # Draw knight
352
- pygame.draw.circle(screen, knight_color, (knight_x, knight_y), knight_size)
353
- pygame.draw.rect(screen, (50, 50, 150), (knight_x - 15, knight_y - 50, 30, 50)) # Body
354
- pygame.draw.circle(screen, (200, 200, 200), (knight_x, knight_y - 60), 15) # Head
355
-
356
- # Draw text
357
- font = pygame.font.SysFont(None, 36)
358
- if is_unlocked:
359
- text = font.render("Chest is unlocked! Treasure acquired!", True, (255, 255, 100))
360
- else:
361
- text = font.render("Chest is locked! Find the key!", True, (255, 100, 100))
362
- screen.blit(text, (WIDTH//2 - text.get_width()//2, 50))
363
-
364
- # Capture frame
365
- frames.append(pygame.surfarray.array3d(screen).swapaxes(0, 1))
366
-
367
- pygame.display.flip()
368
- clock.tick(30)
369
-
370
- # Save animation as GIF
371
- import imageio
372
- imageio.mimsave('animation.gif', frames, fps=30)
373
- """
374
- },
375
- "function": {
376
- "manim": """
377
- from manim import *
378
-
379
- class FunctionMagic(Scene):
380
- def construct(self):
381
- # Create wizard and flower
382
- wizard = Circle(radius=0.5, color=BLUE, fill_opacity=1).shift(LEFT*3)
383
- wizard_label = Text("Wizard").next_to(wizard, DOWN)
384
-
385
- flower = VGroup(
386
- Circle(radius=0.3, color=GREEN).shift(UP*0.3),
387
- Circle(radius=0.2, color=YELLOW).shift(UP*0.3),
388
- Line(UP*0.3, DOWN*1, color=GREEN)
389
- ).shift(RIGHT*3)
390
- flower_label = Text("Flower").next_to(flower, DOWN)
391
-
392
- # Create spell function
393
- func_label = Text("cast_grow_spell()", color=YELLOW).shift(UP*2)
394
-
395
- # Animation
396
- self.play(Create(wizard), Write(wizard_label))
397
- self.play(Create(flower), Write(flower_label))
398
- self.play(Write(func_label))
399
- self.wait(1)
400
-
401
- # Cast spell multiple times
402
- for i in range({count}):
403
- # Create spell effect
404
- spell = VGroup(
405
- Star(color=PURPLE, fill_opacity=1).scale(0.3),
406
- MathTex("\\star", color=PURPLE).scale(1.5)
407
- )
408
-
409
- # Animate spell moving
410
- self.play(
411
- Create(spell.move_to(wizard.get_center())),
412
- run_time=0.5
413
- )
414
- self.play(
415
- spell.animate.move_to(flower.get_center()),
416
- run_time=1
417
- )
418
- self.play(FadeOut(spell))
419
-
420
- # Grow flower
421
- self.play(
422
- flower.animate.scale(1.2),
423
- run_time=0.5
424
- )
425
- self.wait(0.5)
426
-
427
- # Show function call
428
- call_text = Text(f"cast_grow_spell() #{i+1}", color=GREEN).shift(DOWN*2)
429
- self.play(Write(call_text))
430
- self.play(FadeOut(call_text))
431
-
432
- self.wait(2)
433
- """
434
- }
435
- }
436
-
437
  def analyze_story(story):
438
  """Analyze story and identify programming concepts"""
439
  story_lower = story.lower()
@@ -461,106 +213,106 @@ def analyze_story(story):
461
 
462
  return list(set(detected_concepts))
463
 
464
- def generate_animation_code(story, concepts):
465
- """Generate Python animation code based on story"""
466
  try:
467
  # Choose a random character
468
  character = random.choice(list(CHARACTERS.keys()))
469
  char_details = CHARACTERS[character]
470
 
471
- # Choose the most relevant concept
472
- concept = concepts[0] if concepts else "loop"
473
-
474
- # Get template for the concept
475
- template = ANIMATION_TEMPLATES.get(concept, ANIMATION_TEMPLATES["loop"])
476
-
477
- # Fill in template parameters
478
- if concept == "loop":
479
- # Extract count from story
480
- count = 3
481
- for word in story.split():
482
- if word.isdigit():
483
- count = min(int(word), 10)
484
- break
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
 
486
- code = template["pygame"].format(
487
- character=character,
488
- char_color=char_details["color"],
489
- char_size=char_details["size"],
490
- char_speed=char_details["speed"],
491
- count=count
492
- )
493
- elif concept == "conditional":
494
- condition = "True" if random.random() > 0.5 else "False"
495
- code = template["pygame"].format(condition=condition)
496
- elif concept == "function":
497
- count = 3
498
- for word in story.split():
499
- if word.isdigit():
500
- count = min(int(word), 5)
501
- break
502
- code = template["manim"].format(count=count)
503
- else:
504
- # Default to loop animation
505
- code = ANIMATION_TEMPLATES["loop"]["pygame"].format(
506
- character=character,
507
- char_color=char_details["color"],
508
- char_size=char_details["size"],
509
- char_speed=char_details["speed"],
510
- count=3
511
- )
512
-
513
- return code
514
- except Exception as e:
515
- return f"# Error generating code\nprint('Could not generate code: {str(e)}')"
516
-
517
- def run_pygame_animation(code):
518
- """Run PyGame animation code and generate GIF"""
519
- try:
520
- # Create a temporary Python file
521
- with tempfile.NamedTemporaryFile(suffix=".py", delete=False, mode='w') as tmpfile:
522
- tmpfile.write(code)
523
- tmpfile_path = tmpfile.name
524
-
525
- # Run the animation script
526
- subprocess.run(["python", tmpfile_path], check=True)
527
-
528
- # Check for generated GIF
529
- if os.path.exists("animation.gif"):
530
- return "animation.gif"
531
 
532
- return None
 
 
 
533
  except Exception as e:
534
  st.error(f"Animation error: {str(e)}")
535
  return None
536
 
537
- def run_manim_animation(code):
538
- """Run Manim animation code and generate video"""
539
- try:
540
- # Create a temporary Python file
541
- with tempfile.NamedTemporaryFile(suffix=".py", delete=False, mode='w') as tmpfile:
542
- tmpfile.write(code)
543
- tmpfile_path = tmpfile.name
544
-
545
- # Run Manim render
546
- result = subprocess.run(
547
- ["manim", "-ql", "-o", "animation", tmpfile_path],
548
- capture_output=True,
549
- text=True
550
- )
551
-
552
- # Find the output file
553
- output_dir = "media/videos"
554
- if os.path.exists(output_dir):
555
- for file in os.listdir(output_dir):
556
- if file.startswith("animation") and file.endswith(".mp4"):
557
- return os.path.join(output_dir, file)
558
-
559
- return None
560
- except Exception as e:
561
- st.error(f"Manim error: {str(e)}")
562
- return None
563
-
564
  def create_story_image(story):
565
  """Create a story image with Matplotlib"""
566
  try:
@@ -621,14 +373,10 @@ def main():
621
  st.session_state.story = ""
622
  if 'concepts' not in st.session_state:
623
  st.session_state.concepts = []
624
- if 'animation_code' not in st.session_state:
625
- st.session_state.animation_code = ""
626
- if 'active_tab' not in st.session_state:
627
- st.session_state.active_tab = "story"
628
  if 'animation_path' not in st.session_state:
629
  st.session_state.animation_path = None
630
- if 'animation_type' not in st.session_state:
631
- st.session_state.animation_type = None
632
 
633
  # Create tabs
634
  tabs = st.empty()
@@ -649,9 +397,7 @@ def main():
649
  if st.button("🔄 Reset"):
650
  st.session_state.story = ""
651
  st.session_state.concepts = []
652
- st.session_state.animation_code = ""
653
  st.session_state.animation_path = None
654
- st.session_state.animation_type = None
655
  st.session_state.active_tab = "story"
656
 
657
  # Story creation tab
@@ -676,25 +422,11 @@ def main():
676
  with st.spinner("🧠 Analyzing your story for coding concepts..."):
677
  st.session_state.concepts = analyze_story(story)
678
 
679
- with st.spinner(" Generating animation code..."):
680
- st.session_state.animation_code = generate_animation_code(
681
  story, st.session_state.concepts
682
  )
683
 
684
- # Determine animation type
685
- if "manim" in st.session_state.animation_code:
686
- st.session_state.animation_type = "manim"
687
- with st.spinner("🎬 Rendering Manim animation (this may take a minute)..."):
688
- st.session_state.animation_path = run_manim_animation(
689
- st.session_state.animation_code
690
- )
691
- else:
692
- st.session_state.animation_type = "pygame"
693
- with st.spinner("🎬 Creating PyGame animation..."):
694
- st.session_state.animation_path = run_pygame_animation(
695
- st.session_state.animation_code
696
- )
697
-
698
  st.session_state.active_tab = "animation"
699
  st.rerun()
700
 
@@ -709,7 +441,7 @@ def main():
709
  st.code('"If it rains, the cat stays inside, else it goes out"', language="text")
710
  with col3:
711
  st.caption("Function Example")
712
- st.code('"A wizard casts a spell to make flowers grow 3 times"', language="text")
713
 
714
  # Animation tab
715
  elif st.session_state.active_tab == "animation":
@@ -728,10 +460,7 @@ def main():
728
  """, unsafe_allow_html=True)
729
 
730
  try:
731
- if st.session_state.animation_type == "pygame":
732
- st.image(st.session_state.animation_path, use_container_width=True)
733
- elif st.session_state.animation_type == "manim":
734
- st.video(st.session_state.animation_path)
735
  except Exception as e:
736
  st.error(f"Couldn't display animation: {str(e)}")
737
  story_image = create_story_image(st.session_state.story)
@@ -776,21 +505,56 @@ def main():
776
  st.header("💻 The Magic Code Behind Your Animation")
777
  st.write("Here's the Python code that created your animation:")
778
 
779
- if st.session_state.animation_code:
780
- st.code(st.session_state.animation_code, language="python")
781
-
782
- # Download button
783
- st.download_button(
784
- label="Download Animation Code",
785
- data=st.session_state.animation_code,
786
- file_name="story_animation.py",
787
- mime="text/python",
788
- use_container_width=True
789
- )
790
-
791
- st.write("You can run this code on your computer to see the animation!")
792
- else:
793
- st.warning("No code generated yet!")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
794
 
795
  if st.button("Create Another Story!", use_container_width=True):
796
  st.session_state.active_tab = "story"
 
1
+ # app.py - Final Deployment-Ready Version
2
  import streamlit as st
3
  import os
4
  import time
 
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(
 
186
  "pirate": {"color": (255, 255, 150), "speed": 5, "size": 40}
187
  }
188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  def analyze_story(story):
190
  """Analyze story and identify programming concepts"""
191
  story_lower = story.lower()
 
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)}")
314
  return None
315
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  def create_story_image(story):
317
  """Create a story image with Matplotlib"""
318
  try:
 
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
 
381
  # Create tabs
382
  tabs = st.empty()
 
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
  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
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
  st.session_state.active_tab = "animation"
431
  st.rerun()
432
 
 
441
  st.code('"If it rains, the cat stays inside, else it goes out"', language="text")
442
  with col3:
443
  st.caption("Function Example")
444
+ st.code('"A wizard casts a spell to make flowers grow"', language="text")
445
 
446
  # Animation tab
447
  elif st.session_state.active_tab == "animation":
 
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)
 
505
  st.header("💻 The Magic Code Behind Your Animation")
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
+
548
+ # Download button
549
+ st.download_button(
550
+ label="Download Animation Code",
551
+ data=sample_code,
552
+ file_name="story_animation.py",
553
+ mime="text/python",
554
+ use_container_width=True
555
+ )
556
+
557
+ st.write("You can run this code on your computer to create similar animations!")
558
 
559
  if st.button("Create Another Story!", use_container_width=True):
560
  st.session_state.active_tab = "story"