Rathapoom commited on
Commit
7dd1646
Β·
verified Β·
1 Parent(s): a59b1bf

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +179 -138
app.py CHANGED
@@ -1,174 +1,215 @@
1
  import streamlit as st
2
- import openai
3
- import datetime
4
  import json
 
 
 
5
 
6
- # Set your OpenAI API key
7
- openai.api_key = 'YOUR_OPENAI_API_KEY'
8
 
9
- # Set up the Streamlit page configuration
10
  st.set_page_config(
11
  page_title="JoyStory - Interactive Story Adventure",
12
- page_icon=":book:",
13
  layout="wide",
14
  initial_sidebar_state="collapsed",
15
  )
16
 
17
  # Initialize session state variables
18
- if 'story' not in st.session_state:
19
- st.session_state.story = []
20
- if 'achievements' not in st.session_state:
21
- st.session_state.achievements = []
22
- if 'level' not in st.session_state:
23
- st.session_state.level = 'Beginner'
24
- if 'unique_words' not in st.session_state:
25
- st.session_state.unique_words = set()
26
- if 'total_words' not in st.session_state:
27
- st.session_state.total_words = 0
28
- if 'badges' not in st.session_state:
29
- st.session_state.badges = []
30
-
31
- # Function to generate AI response
32
- def generate_ai_response(user_input, level):
33
- prompt = f"Continue the story in a way that is engaging and suitable for a {level.lower()} English learner.\n\nStory so far:\n{''.join(st.session_state.story)}\nUser input: {user_input}\nAI continuation:"
34
- response = openai.Completion.create(
35
- engine='gpt-4o-mini',
36
- prompt=prompt,
37
- max_tokens=100,
38
- temperature=0.7,
39
- )
40
- ai_output = response.choices[0].text.strip()
41
- return ai_output
42
-
43
- # Function to get vocabulary suggestions
44
- def get_vocabulary_suggestions():
45
- suggestions = openai.Completion.create(
46
- engine='gpt-4o-mini',
47
- prompt=f"Provide 3 interesting words suitable for a {st.session_state.level.lower()} English learner to use in the next part of the story.",
48
- max_tokens=20,
49
- n=1,
50
- stop=None,
51
- temperature=0.5,
52
- )
53
- words = suggestions.choices[0].text.strip().split(', ')
54
- return words
55
-
56
- # Function to get creative prompts
57
- def get_creative_prompt():
58
- prompt = openai.Completion.create(
59
- engine='gpt-4o-mini',
60
- prompt="Ask an open-ended question to inspire the next part of the story.",
61
- max_tokens=30,
62
- n=1,
63
- stop=None,
64
- temperature=0.7,
65
- )
66
- question = prompt.choices[0].text.strip()
67
- return question
68
-
69
- # Function to provide feedback
70
- def get_feedback(user_input):
71
- feedback_prompt = f"Provide one positive, simple feedback on the following sentence for a {st.session_state.level.lower()} English learner:\n\n{user_input}"
72
- feedback = openai.Completion.create(
73
- engine='gpt-4o-mini',
74
- prompt=feedback_prompt,
75
- max_tokens=50,
76
- temperature=0.5,
77
- )
78
- return feedback.choices[0].text.strip()
79
 
80
- # Function to update achievements
81
- def update_achievements(user_input):
82
- words = set(user_input.lower().split())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  st.session_state.unique_words.update(words)
84
  st.session_state.total_words += len(words)
85
- # Example achievement: Use 50 unique words
86
- if len(st.session_state.unique_words) >= 50 and '50 Unique Words' not in st.session_state.badges:
87
- st.session_state.badges.append('50 Unique Words')
88
- st.success("Achievement Unlocked: 50 Unique Words!")
89
-
90
- # Layout the UI
 
 
 
 
 
 
 
 
91
  st.title("πŸ“– JoyStory - Interactive Story Adventure")
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  col1, col2 = st.columns([3, 1])
94
 
95
  with col1:
96
  # Story Display Box
97
- st.header("Story So Far")
98
- story_display = st.empty()
99
- if st.session_state.story:
100
- story_display.markdown('\n\n'.join(st.session_state.story))
101
- else:
102
- st.info("Your story will appear here as you write it.")
103
-
 
 
 
104
  # User Input Box
105
- st.header("Your Turn to Write")
106
  user_input = st.text_area("Continue the story:", height=100)
 
107
  if st.button("Submit"):
108
- if user_input.strip() == "":
109
- st.warning("Please enter some text to continue the story.")
110
- else:
111
- st.session_state.story.append(f"**You:** {user_input}")
 
112
  update_achievements(user_input)
113
- feedback = get_feedback(user_input)
114
- st.session_state.story.append(f"**Feedback:** {feedback}")
115
-
116
- ai_response = generate_ai_response(user_input, st.session_state.level)
117
- st.session_state.story.append(f"**AI:** {ai_response}")
118
- story_display.markdown('\n\n'.join(st.session_state.story))
 
 
 
 
 
 
119
 
120
  with col2:
121
  # Help and Suggestions Box
122
- st.header("Need Some Help?")
123
- if st.button("Get Vocabulary Suggestions"):
124
  vocab_suggestions = get_vocabulary_suggestions()
125
- st.write("Try using these words in your next sentence:")
126
  for word in vocab_suggestions:
127
- st.write(f"- {word}")
128
-
129
  if st.button("Get a Creative Prompt"):
130
  creative_prompt = get_creative_prompt()
131
  st.write(creative_prompt)
132
-
133
- # Rewards and Progress Box
134
- st.header("Achievements")
135
  if st.session_state.badges:
136
  for badge in st.session_state.badges:
137
  st.success(f"πŸ† {badge}")
138
  else:
139
- st.write("No achievements yet. Keep writing to earn badges!")
140
-
141
- # Story Saving
142
- if st.button("Save Story"):
143
- story_data = {
144
- 'level': st.session_state.level,
145
- 'date': datetime.datetime.now().isoformat(),
146
- 'story': st.session_state.story,
147
- 'achievements': st.session_state.badges,
148
- 'total_words': st.session_state.total_words,
149
- 'unique_words': list(st.session_state.unique_words),
150
- }
151
- story_json = json.dumps(story_data, indent=4)
152
- st.download_button(
153
- label="Download Story",
154
- data=story_json,
155
- file_name='joystory.json',
156
- mime='application/json',
157
- )
158
-
159
- # Sidebar for selecting language level
160
- with st.sidebar:
161
- st.header("Settings")
162
- level = st.radio(
163
- "Select your English level:",
164
- ('Beginner', 'Intermediate', 'Advanced'),
165
- index=['Beginner', 'Intermediate', 'Advanced'].index(st.session_state.level)
166
- )
167
- st.session_state.level = level
168
- if st.button("Start New Story"):
169
- st.session_state.story = []
170
- st.session_state.achievements = []
171
- st.session_state.unique_words = set()
172
- st.session_state.total_words = 0
173
- st.session_state.badges = []
174
- st.experimental_rerun()
 
1
  import streamlit as st
 
 
2
  import json
3
+ import datetime
4
+ from openai import OpenAI
5
+ from typing import Dict, List, Set
6
 
7
+ # Initialize OpenAI client
8
+ client = OpenAI() # Make sure OPENAI_API_KEY is set in your environment variables
9
 
10
+ # Set up Streamlit page configuration
11
  st.set_page_config(
12
  page_title="JoyStory - Interactive Story Adventure",
13
+ page_icon="πŸ“–",
14
  layout="wide",
15
  initial_sidebar_state="collapsed",
16
  )
17
 
18
  # Initialize session state variables
19
+ def init_session_state():
20
+ if 'story' not in st.session_state:
21
+ st.session_state.story = []
22
+ if 'achievements' not in st.session_state:
23
+ st.session_state.achievements = []
24
+ if 'level' not in st.session_state:
25
+ st.session_state.level = 'Beginner'
26
+ if 'unique_words' not in st.session_state:
27
+ st.session_state.unique_words = set()
28
+ if 'total_words' not in st.session_state:
29
+ st.session_state.total_words = 0
30
+ if 'badges' not in st.session_state:
31
+ st.session_state.badges = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
 
33
+ init_session_state()
34
+
35
+ def generate_story_continuation(user_input: str, level: str) -> str:
36
+ """Generate AI story continuation using ChatGPT."""
37
+ try:
38
+ story_context = '\n'.join([entry['content'] for entry in st.session_state.story])
39
+
40
+ response = client.chat.completions.create(
41
+ model="gpt-4o-mini",
42
+ messages=[
43
+ {"role": "system", "content": f"You are a creative storytelling assistant for {level} English learners. Keep the language simple and engaging, avoid complex vocabulary, and maintain story coherence."},
44
+ {"role": "user", "content": f"Story so far:\n{story_context}\nUser's addition:\n{user_input}\nContinue the story in an engaging way:"}
45
+ ],
46
+ max_tokens=150,
47
+ temperature=0.7
48
+ )
49
+ return response.choices[0].message.content
50
+ except Exception as e:
51
+ st.error(f"Error generating story continuation: {str(e)}")
52
+ return "I'm having trouble continuing the story. Please try again."
53
+
54
+ def get_vocabulary_suggestions() -> List[str]:
55
+ """Get vocabulary suggestions based on the story context."""
56
+ try:
57
+ response = client.chat.completions.create(
58
+ model="gpt-4o-mini",
59
+ messages=[
60
+ {"role": "system", "content": f"You are a language tutor. Suggest 3 appropriate vocabulary words for {st.session_state.level} English learners."},
61
+ {"role": "user", "content": "Suggest 3 interesting words that could be used in the story. Format: word1, word2, word3"}
62
+ ],
63
+ max_tokens=50,
64
+ temperature=0.6
65
+ )
66
+ return response.choices[0].message.content.split(', ')
67
+ except Exception as e:
68
+ st.error(f"Error getting vocabulary suggestions: {str(e)}")
69
+ return ["exciting", "beautiful", "happy"]
70
+
71
+ def get_creative_prompt() -> str:
72
+ """Generate a creative prompt to inspire the next part of the story."""
73
+ try:
74
+ response = client.chat.completions.create(
75
+ model="gpt-4o-mini",
76
+ messages=[
77
+ {"role": "system", "content": "Generate an inspiring question to help continue the story."},
78
+ {"role": "user", "content": "Create an open-ended question to inspire the next part of the story."}
79
+ ],
80
+ max_tokens=50,
81
+ temperature=0.7
82
+ )
83
+ return response.choices[0].message.content
84
+ except Exception as e:
85
+ st.error(f"Error generating creative prompt: {str(e)}")
86
+ return "What happens next in your story?"
87
+
88
+ def provide_feedback(text: str, level: str) -> str:
89
+ """Provide constructive feedback on the user's writing."""
90
+ try:
91
+ response = client.chat.completions.create(
92
+ model="gpt-4o-mini",
93
+ messages=[
94
+ {"role": "system", "content": f"You are an encouraging English teacher for {level} students. Provide one brief, positive piece of feedback."},
95
+ {"role": "user", "content": f"Provide encouraging feedback on: {text}"}
96
+ ],
97
+ max_tokens=50,
98
+ temperature=0.6
99
+ )
100
+ return response.choices[0].message.content
101
+ except Exception as e:
102
+ st.error(f"Error generating feedback: {str(e)}")
103
+ return "Great effort! Keep writing!"
104
+
105
+ def update_achievements(text: str):
106
+ """Update user achievements based on their writing."""
107
+ words = set(text.lower().split())
108
  st.session_state.unique_words.update(words)
109
  st.session_state.total_words += len(words)
110
+
111
+ # Check for achievements
112
+ achievements = {
113
+ '50 Words': len(st.session_state.unique_words) >= 50,
114
+ '100 Words': len(st.session_state.unique_words) >= 100,
115
+ 'Story Master': len(st.session_state.story) >= 10,
116
+ }
117
+
118
+ for badge, condition in achievements.items():
119
+ if condition and badge not in st.session_state.badges:
120
+ st.session_state.badges.append(badge)
121
+ st.success(f"πŸ† Achievement Unlocked: {badge}!")
122
+
123
+ # Main UI Layout
124
  st.title("πŸ“– JoyStory - Interactive Story Adventure")
125
 
126
+ # Sidebar for settings
127
+ with st.sidebar:
128
+ st.header("Settings")
129
+ level = st.radio(
130
+ "Select your English level:",
131
+ ('Beginner', 'Intermediate', 'Advanced')
132
+ )
133
+ st.session_state.level = level
134
+
135
+ if st.button("Start New Story"):
136
+ st.session_state.story = []
137
+ st.experimental_rerun()
138
+
139
+ # Main content area
140
  col1, col2 = st.columns([3, 1])
141
 
142
  with col1:
143
  # Story Display Box
144
+ st.header("Your Story")
145
+ story_display = st.container()
146
+
147
+ with story_display:
148
+ if not st.session_state.story:
149
+ st.info("Start your adventure by writing the first sentence!")
150
+ else:
151
+ for entry in st.session_state.story:
152
+ st.write(f"{entry['role']}: {entry['content']}")
153
+
154
  # User Input Box
155
+ st.header("Your Turn")
156
  user_input = st.text_area("Continue the story:", height=100)
157
+
158
  if st.button("Submit"):
159
+ if user_input.strip():
160
+ # Add user's input to story
161
+ st.session_state.story.append({"role": "You", "content": user_input})
162
+
163
+ # Update achievements
164
  update_achievements(user_input)
165
+
166
+ # Get feedback
167
+ feedback = provide_feedback(user_input, st.session_state.level)
168
+ st.session_state.story.append({"role": "Feedback", "content": feedback})
169
+
170
+ # Generate AI continuation
171
+ ai_response = generate_story_continuation(user_input, st.session_state.level)
172
+ st.session_state.story.append({"role": "AI", "content": ai_response})
173
+
174
+ st.experimental_rerun()
175
+ else:
176
+ st.warning("Please write something to continue the story.")
177
 
178
  with col2:
179
  # Help and Suggestions Box
180
+ st.header("Writing Help")
181
+ if st.button("Get Vocabulary Ideas"):
182
  vocab_suggestions = get_vocabulary_suggestions()
183
+ st.write("Try using these words:")
184
  for word in vocab_suggestions:
185
+ st.write(f"β€’ {word}")
186
+
187
  if st.button("Get a Creative Prompt"):
188
  creative_prompt = get_creative_prompt()
189
  st.write(creative_prompt)
190
+
191
+ # Achievements Box
192
+ st.header("Your Achievements")
193
  if st.session_state.badges:
194
  for badge in st.session_state.badges:
195
  st.success(f"πŸ† {badge}")
196
  else:
197
+ st.write("Keep writing to earn badges!")
198
+
199
+ # Save Story Button
200
+ if st.session_state.story:
201
+ if st.button("Save Story"):
202
+ story_data = {
203
+ 'level': st.session_state.level,
204
+ 'date': datetime.datetime.now().isoformat(),
205
+ 'story': st.session_state.story,
206
+ 'achievements': st.session_state.badges,
207
+ 'total_words': st.session_state.total_words,
208
+ 'unique_words': list(st.session_state.unique_words)
209
+ }
210
+ st.download_button(
211
+ label="Download Story",
212
+ data=json.dumps(story_data, indent=2),
213
+ file_name='joystory.json',
214
+ mime='application/json'
215
+ )