sunbal7 commited on
Commit
e95772d
Β·
verified Β·
1 Parent(s): c969520

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +256 -133
app.py CHANGED
@@ -1,15 +1,15 @@
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(
@@ -190,6 +190,90 @@ CHARACTERS = [
190
  {"name": "pirate", "emoji": "πŸ΄β€β˜ οΈ", "color": "#FFA500"}
191
  ]
192
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
  def analyze_story(story):
194
  """Analyze story and identify programming concepts"""
195
  story_lower = story.lower()
@@ -225,84 +309,146 @@ def extract_count_from_story(story):
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)}")
304
  return None
305
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
306
  def create_story_image(story):
307
  """Create a story image with Matplotlib"""
308
  try:
@@ -343,7 +489,7 @@ def create_story_image(story):
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
@@ -364,6 +510,12 @@ def main():
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
 
@@ -387,6 +539,9 @@ def main():
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
@@ -415,6 +570,14 @@ def main():
415
  st.session_state.animation = create_animation(
416
  story, st.session_state.concepts
417
  )
 
 
 
 
 
 
 
 
418
 
419
  st.session_state.active_tab = "animation"
420
  st.rerun()
@@ -448,14 +611,23 @@ def main():
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!")
461
 
@@ -492,81 +664,32 @@ def main():
492
  # Code tab
493
  elif st.session_state.active_tab == "code":
494
  st.header("πŸ’» The Magic Code Behind Your Animation")
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
-
560
- # Download button
561
- st.download_button(
562
- label="Download Animation Code",
563
- data=sample_code,
564
- file_name="story_animation.py",
565
- mime="text/python",
566
- use_container_width=True
567
- )
568
-
569
- st.write("You can run this code on your computer to create similar animations!")
570
 
571
  if st.button("Create Another Story!", use_container_width=True):
572
  st.session_state.active_tab = "story"
 
1
+ # app.py - Final Working Version with Animation
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
  import base64
9
  from PIL import Image
10
  import io
11
+ import pandas as pd
12
+ import plotly.express as px
13
 
14
  # Configure Streamlit page
15
  st.set_page_config(
 
190
  {"name": "pirate", "emoji": "πŸ΄β€β˜ οΈ", "color": "#FFA500"}
191
  ]
192
 
193
+ # Animation templates
194
+ ANIMATION_TEMPLATES = {
195
+ "loop": {
196
+ "description": "Character moving to a target multiple times",
197
+ "code": """
198
+ # Loop Animation
199
+ import matplotlib.pyplot as plt
200
+ import numpy as np
201
+
202
+ fig, ax = plt.subplots(figsize=(10, 6))
203
+ ax.set_xlim(0, 10)
204
+ ax.set_ylim(0, 10)
205
+ ax.axis('off')
206
+
207
+ character = ax.text(1, 5, "{emoji}", fontsize=48, color='{color}')
208
+ target = ax.text(9, 5, "🎯", fontsize=48)
209
+ ax.text(5, 9, "{story}", ha='center', fontsize=14)
210
+
211
+ for i in range({count}):
212
+ for pos in np.linspace(1, 9, 20):
213
+ character.set_position((pos, 5))
214
+ plt.pause(0.05)
215
+ plt.show()
216
+ """
217
+ },
218
+ "conditional": {
219
+ "description": "Character making a decision based on a condition",
220
+ "code": """
221
+ # Conditional Animation
222
+ import matplotlib.pyplot as plt
223
+ import numpy as np
224
+
225
+ fig, ax = plt.subplots(figsize=(10, 6))
226
+ ax.set_xlim(0, 10)
227
+ ax.set_ylim(0, 10)
228
+ ax.axis('off')
229
+
230
+ character = ax.text(5, 5, "{emoji}", fontsize=48, color='{color}')
231
+ ax.text(5, 9, "{story}", ha='center', fontsize=14)
232
+
233
+ # Condition: {condition}
234
+ if {condition}:
235
+ decision = ax.text(7, 7, "βœ… Yes", fontsize=24, color='green')
236
+ path = np.linspace(5, 8, 20)
237
+ else:
238
+ decision = ax.text(7, 7, "❌ No", fontsize=24, color='red')
239
+ path = np.linspace(5, 2, 20)
240
+
241
+ for pos in path:
242
+ character.set_position((pos, 5))
243
+ plt.pause(0.05)
244
+ plt.show()
245
+ """
246
+ },
247
+ "function": {
248
+ "description": "Character performing an action multiple times",
249
+ "code": """
250
+ # Function Animation
251
+ import matplotlib.pyplot as plt
252
+ import numpy as np
253
+
254
+ fig, ax = plt.subplots(figsize=(10, 6))
255
+ ax.set_xlim(0, 10)
256
+ ax.set_ylim(0, 10)
257
+ ax.axis('off')
258
+
259
+ character = ax.text(5, 5, "{emoji}", fontsize=48, color='{color}')
260
+ ax.text(5, 9, "{story}", ha='center', fontsize=14)
261
+
262
+ def perform_action():
263
+ for _ in range(5):
264
+ character.set_fontsize(60)
265
+ plt.pause(0.1)
266
+ character.set_fontsize(48)
267
+ plt.pause(0.1)
268
+
269
+ for i in range({count}):
270
+ perform_action()
271
+ character.set_position((5 + i, 5))
272
+ plt.show()
273
+ """
274
+ }
275
+ }
276
+
277
  def analyze_story(story):
278
  """Analyze story and identify programming concepts"""
279
  story_lower = story.lower()
 
309
  return 3 # Default value
310
 
311
  def create_animation(story, concepts):
312
+ """Create an animation visualization based on the story and concepts"""
313
  try:
314
  # Choose a random character
315
  character = random.choice(CHARACTERS)
316
  count = extract_count_from_story(story)
317
 
318
+ # Create figure
319
+ fig, ax = plt.subplots(figsize=(10, 6))
320
+ ax.set_facecolor('#f0f8ff')
321
  ax.set_xlim(0, 10)
322
  ax.set_ylim(0, 10)
323
  ax.axis('off')
324
 
325
  # Add title
326
+ ax.text(5, 9, '✨ Your Story Animation ✨',
327
+ fontsize=20, ha='center', color='purple', fontweight='bold')
328
 
329
  # Add story text
330
+ story_text = story[:80] + ('...' if len(story) > 80 else '')
331
+ ax.text(5, 8, f'"{story_text}"',
332
+ fontsize=14, ha='center', color='#333')
333
+
334
+ # Add character
335
+ ax.text(5, 5, character["emoji"],
336
+ fontsize=100, ha='center', color=character["color"])
337
+
338
+ # Add concept visualization
339
+ if "loop" in concepts:
340
+ ax.text(5, 3, f"πŸ”„ Repeating {count} times",
341
+ fontsize=18, ha='center', color=CONCEPTS["loop"]["color"])
342
+ elif "conditional" in concepts:
343
+ condition = random.choice(["sunny", "raining", "dark"])
344
+ ax.text(5, 3, f"❓ Checking if it's {condition}",
345
+ fontsize=18, ha='center', color=CONCEPTS["conditional"]["color"])
346
+ elif "function" in concepts:
347
+ ax.text(5, 3, f"✨ Performing action {count} times",
348
+ fontsize=18, ha='center', color=CONCEPTS["function"]["color"])
349
+ else:
350
+ ax.text(5, 3, "πŸ“ Creating your story visualization",
351
+ fontsize=18, ha='center', color=CONCEPTS["variable"]["color"])
352
 
353
+ # Add footer
354
+ ax.text(5, 1, "Created with StoryCoder",
355
+ fontsize=12, ha='center', style='italic', color='gray')
 
 
356
 
357
+ # Save to buffer
358
+ buf = io.BytesIO()
359
+ plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0.5, dpi=150)
360
+ buf.seek(0)
361
+ plt.close()
362
+ return buf
363
+
364
+ except Exception as e:
365
+ st.error(f"Animation error: {str(e)}")
366
+ return None
367
+
368
+ def create_interactive_animation(story, concepts):
369
+ """Create an interactive animation using Plotly"""
370
+ try:
371
+ # Choose a random character
372
+ character = random.choice(CHARACTERS)
373
+ count = extract_count_from_story(story)
374
 
375
+ # Create animation data
376
+ frames = []
377
+ for i in range(count):
378
+ frames.append({
379
+ "frame": i,
380
+ "x": np.random.uniform(1, 9),
381
+ "y": np.random.uniform(1, 9),
382
+ "size": np.random.uniform(10, 30),
383
+ "character": character["emoji"]
384
+ })
385
+
386
+ df = pd.DataFrame(frames)
387
+
388
+ # Create animated scatter plot
389
+ fig = px.scatter(
390
+ df,
391
+ x="x",
392
+ y="y",
393
+ animation_frame="frame",
394
+ text="character",
395
+ size="size",
396
+ size_max=45,
397
+ color_discrete_sequence=[character["color"]],
398
+ range_x=[0, 10],
399
+ range_y=[0, 10]
400
+ )
401
 
402
+ # Customize layout
403
+ fig.update_layout(
404
+ title=f'Animation for: "{story[:50]}{"..." if len(story) > 50 else ""}"',
405
+ showlegend=False,
406
+ plot_bgcolor='rgba(240,248,255,1)',
407
+ paper_bgcolor='rgba(240,248,255,1)',
408
+ width=800,
409
+ height=600
410
+ )
411
 
412
+ fig.update_traces(
413
+ textfont_size=30,
414
+ textposition='middle center'
415
+ )
416
 
417
+ fig.layout.updatemenus[0].buttons[0].args[1]["frame"]["duration"] = 1000
418
+ fig.layout.updatemenus[0].buttons[0].args[1]["transition"]["duration"] = 500
419
 
420
+ return fig
421
 
422
  except Exception as e:
423
+ st.error(f"Interactive animation error: {str(e)}")
424
  return None
425
 
426
+ def generate_animation_code(story, concepts):
427
+ """Generate Python animation code based on story"""
428
+ try:
429
+ # Choose a random character
430
+ character = random.choice(CHARACTERS)
431
+ count = extract_count_from_story(story)
432
+ concept = concepts[0] if concepts else "loop"
433
+
434
+ # Get the appropriate template
435
+ template = ANIMATION_TEMPLATES.get(concept, ANIMATION_TEMPLATES["loop"])
436
+
437
+ # Fill in the template
438
+ condition = random.choice(["True", "False"])
439
+ code = template["code"].format(
440
+ emoji=character["emoji"],
441
+ color=character["color"],
442
+ story=story[:80] + ('...' if len(story) > 80 else ''),
443
+ count=count,
444
+ condition=condition
445
+ )
446
+
447
+ return code, template["description"]
448
+
449
+ except Exception as e:
450
+ return f"# Error generating code\nprint('Could not generate code: {str(e)}')", ""
451
+
452
  def create_story_image(story):
453
  """Create a story image with Matplotlib"""
454
  try:
 
489
 
490
  # Save to buffer
491
  buf = io.BytesIO()
492
+ plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0.5, dpi=150)
493
  buf.seek(0)
494
  plt.close()
495
  return buf
 
510
  st.session_state.concepts = []
511
  if 'animation' not in st.session_state:
512
  st.session_state.animation = None
513
+ if 'interactive_animation' not in st.session_state:
514
+ st.session_state.interactive_animation = None
515
+ if 'animation_code' not in st.session_state:
516
+ st.session_state.animation_code = ""
517
+ if 'code_description' not in st.session_state:
518
+ st.session_state.code_description = ""
519
  if 'active_tab' not in st.session_state:
520
  st.session_state.active_tab = "story"
521
 
 
539
  st.session_state.story = ""
540
  st.session_state.concepts = []
541
  st.session_state.animation = None
542
+ st.session_state.interactive_animation = None
543
+ st.session_state.animation_code = ""
544
+ st.session_state.code_description = ""
545
  st.session_state.active_tab = "story"
546
 
547
  # Story creation tab
 
570
  st.session_state.animation = create_animation(
571
  story, st.session_state.concepts
572
  )
573
+
574
+ st.session_state.interactive_animation = create_interactive_animation(
575
+ story, st.session_state.concepts
576
+ )
577
+
578
+ st.session_state.animation_code, st.session_state.code_description = generate_animation_code(
579
+ story, st.session_state.concepts
580
+ )
581
 
582
  st.session_state.active_tab = "animation"
583
  st.rerun()
 
611
  </div>
612
  """, unsafe_allow_html=True)
613
 
614
+ # Display static animation
615
  if st.session_state.animation:
616
  st.image(st.session_state.animation, use_container_width=True)
617
  else:
618
+ st.warning("Static animation couldn't be generated. Showing story image instead.")
619
  story_img = create_story_image(st.session_state.story)
620
  if story_img:
621
  st.image(story_img, use_container_width=True)
622
 
623
+ # Display interactive animation
624
+ st.subheader("πŸ“Š Interactive Animation")
625
+ if st.session_state.interactive_animation:
626
+ st.plotly_chart(st.session_state.interactive_animation, use_container_width=True)
627
+ else:
628
+ st.info("Interactive animation preview. The real animation would run on your computer!")
629
+ st.image("https://i.imgur.com/5X8jYAy.gif", use_container_width=True)
630
+
631
  st.success("✨ Animation created successfully!")
632
  st.caption("This animation was generated with Python code based on your story!")
633
 
 
664
  # Code tab
665
  elif st.session_state.active_tab == "code":
666
  st.header("πŸ’» The Magic Code Behind Your Animation")
667
+ st.write("Here's the Python code that would create your animation:")
 
 
 
 
668
 
669
+ if st.session_state.animation_code:
670
+ st.markdown(f"**{st.session_state.code_description}**")
671
+ st.code(st.session_state.animation_code, language="python")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
672
 
673
+ # Download button
674
+ st.download_button(
675
+ label="Download Animation Code",
676
+ data=st.session_state.animation_code,
677
+ file_name="story_animation.py",
678
+ mime="text/python",
679
+ use_container_width=True
680
+ )
681
+
682
+ st.info("πŸ’‘ To run this animation on your computer:")
683
+ st.markdown("""
684
+ 1. Install Python from [python.org](https://python.org)
685
+ 2. Install required libraries: `pip install matplotlib numpy`
686
+ 3. Copy the code above into a file named `animation.py`
687
+ 4. Run it with: `python animation.py`
688
+ """)
689
+
690
+ st.success("πŸŽ‰ When you run this code, you'll see your story come to life!")
691
+ else:
692
+ st.warning("No code generated yet!")
 
 
 
 
 
 
 
 
693
 
694
  if st.button("Create Another Story!", use_container_width=True):
695
  st.session_state.active_tab = "story"