File size: 3,361 Bytes
5ac732d
65eb8e4
5ac732d
f39c7e1
65eb8e4
 
 
bfd0106
a9f0287
bfd0106
65eb8e4
 
 
 
 
8a8602f
 
 
 
5ac732d
8a8602f
65eb8e4
 
f39c7e1
bfd0106
8a8602f
 
5ac732d
8a8602f
65eb8e4
8a8602f
f39c7e1
8a8602f
f39c7e1
8a8602f
 
f39c7e1
8a8602f
 
 
 
65eb8e4
 
 
bfd0106
f39c7e1
65eb8e4
8a8602f
65eb8e4
8a8602f
65eb8e4
 
8a8602f
 
65eb8e4
 
 
 
d984995
f39c7e1
65eb8e4
 
 
 
f39c7e1
 
 
 
65eb8e4
 
 
8a8602f
f39c7e1
65eb8e4
 
 
8a8602f
5ac732d
f39c7e1
65eb8e4
2084430
65eb8e4
 
 
 
a9f0287
65eb8e4
8a8602f
a9f0287
65eb8e4
 
 
 
 
f39c7e1
 
 
8a8602f
f39c7e1
65eb8e4
8a8602f
bfd0106
f39c7e1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import os
import streamlit as st
from dotenv import load_dotenv
from openai import OpenAI
import ast
import subprocess
import tempfile

load_dotenv()

class StoryToCodeConverter:
    def __init__(self):
        api_key = os.getenv("NOVITA_API_KEY")
        if not api_key:
            raise ValueError("NOVITA_API_KEY not found in environment")
        self.client = OpenAI(
            api_key=api_key,
            base_url="https://api.novita.ai/v3/openai"
        )

    def generate_code(self, story: str) -> str:
        prompt = f"""
Convert this children's story into Python animation code using turtle graphics.
Include comments that explain loops, movement, colors—easy for kids.

Story:
\"\"\"{story}\"\"\"

Wrap the code in triple backticks like ```python ... ```
"""
        response = self.client.chat.completions.create(
            model="meta-llama/llama-3.1-8b-instruct",
            messages=[
                {"role": "system", "content": "You are a friendly teacher and coder for kids."},
                {"role": "user", "content": prompt}
            ],
            max_tokens=512,
        )
        return self._extract_code(response.choices[0].message.content)

    def _extract_code(self, content: str) -> str:
        if "```python" in content:
            return content.split("```python")[1].split("```")[0]
        return content


class CodeExecutor:
    def execute_safely(self, code: str) -> bool:
        try:
            ast.parse(code)
            with tempfile.NamedTemporaryFile(delete=False, suffix=".py") as tmp:
                tmp.write(code.encode("utf-8"))
                path = tmp.name
            subprocess.Popen(["python", path])
            return True
        except Exception as e:
            st.error(f"Robot Chef burned the cake: {e}")
            return False


st.set_page_config(page_title="CodeTales", page_icon="✨")
with st.sidebar:
    st.header("🍰 How It Works")
    st.markdown("""
1. 📝 Kids write a story  
2. 🔮 Novita AI turns it into Python‑turtle code  
3. 🎮 Animation plays  
4. 🤖 Robot Teacher explains concepts  
""")

st.title("✨ CodeTales: Storytime + Coding Magic")
story = st.text_area("Write your story here:", height=200,
                     placeholder="A turtle draws a rainbow circle...")

if st.button("✨ Bake My Story Cake!"):
    if not story.strip():
        st.warning("Please enter a story!")
    else:
        with st.spinner("Baking your story code... 🍰"):
            try:
                converter = StoryToCodeConverter()
                code = converter.generate_code(story)
            except Exception as e:
                st.error(f"AI oven broke down! {e}")
                st.stop()

            st.subheader("📜 Your Code Recipe")
            st.code(code, language="python")

            executor = CodeExecutor()
            if executor.execute_safely(code):
                st.balloons()
                with st.expander("🤖 Robot Teacher Says:"):
                    st.markdown("""
- `turtle.forward(100)` – Moves forward  
- `turtle.color("red")` – Changes color  
- `for` loops – Repeat patterns  
""")
                st.success("🎉 Animation ready!")
            else:
                st.error("Oops, something went wrong.")

st.caption("Made with ❤️ for young coders | Powered by Novita AI + Python Turtle")