Bharath370 commited on
Commit
b89129c
·
verified ·
1 Parent(s): 286afa0

Upload 3 files

Browse files
Files changed (3) hide show
  1. .gitignore +64 -0
  2. app.py +682 -0
  3. notepad.txt +34 -0
.gitignore ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## 4. .gitignore
2
+
3
+ ```gitignore
4
+ # Virtual environment
5
+ venv/
6
+ env/
7
+ ENV/
8
+ .venv/
9
+
10
+ # Python cache
11
+ __pycache__/
12
+ *.py[cod]
13
+ *$py.class
14
+ *.so
15
+ .Python
16
+
17
+ # IDE
18
+ .vscode/
19
+ .idea/
20
+ *.swp
21
+ *.swo
22
+ *.sublime-project
23
+ *.sublime-workspace
24
+
25
+ # OS files
26
+ .DS_Store
27
+ .DS_Store?
28
+ ._*
29
+ .Spotlight-V100
30
+ .Trashes
31
+ ehthumbs.db
32
+ Thumbs.db
33
+
34
+ # Environment variables
35
+ .env
36
+ .env.local
37
+ .env.production
38
+ secrets.toml
39
+
40
+ # Logs
41
+ logs/
42
+ *.log
43
+ npm-debug.log*
44
+ yarn-debug.log*
45
+ yarn-error.log*
46
+
47
+ # Data files
48
+ data/
49
+ *.json
50
+ *.csv
51
+ *.xlsx
52
+
53
+ # Streamlit
54
+ .streamlit/secrets.toml
55
+
56
+ # Testing
57
+ .coverage
58
+ .pytest_cache/
59
+ htmlcov/
60
+
61
+ # Build
62
+ build/
63
+ dist/
64
+ *.egg-info/
app.py ADDED
@@ -0,0 +1,682 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ """TriviaVerse Enhanced - Advanced Quiz Application"""
3
+
4
+ import streamlit as st
5
+ import time
6
+ from datetime import datetime
7
+ import random
8
+ # Removed dotenv import and os import as .env file is not persisting
9
+ # from dotenv import load_dotenv
10
+ # import os
11
+
12
+ from config.settings import (
13
+ DIFFICULTY_LEVELS,
14
+ BADGES,
15
+ RANDOM_TOPICS,
16
+ )
17
+ from config.themes import THEMES
18
+ from config.languages import SUPPORTED_LANGUAGES
19
+ from modules.mcq_generator import generate_quiz_set
20
+ from modules.flashcard_generator import generate_smart_deck
21
+ from modules.fact_game import generate_random_fact
22
+ from modules.adaptive_engine import AdaptiveEngine
23
+ from utils.ui_components import (
24
+ apply_custom_theme,
25
+ display_user_stats,
26
+ display_badges,
27
+ create_progress_chart,
28
+ animated_success,
29
+ create_quiz_card,
30
+ render_flashcard,
31
+ )
32
+ from utils.score_tracker import ScoreTracker
33
+ from utils.mobile_responsive import responsive_columns, responsive_css
34
+ from utils.user_auth import init_authentication, authenticate_user
35
+ from utils.challenge_manager import ChallengeManager
36
+ from modules.info_page import display_page_info
37
+ from utils.translator import get_translated_texts
38
+
39
+ # Removed load_dotenv() call as .env file is not persisting
40
+ # load_dotenv()
41
+
42
+ # --- Page Config ---
43
+ st.set_page_config(
44
+ page_title="TriviaVerse",
45
+ page_icon="🎯",
46
+ layout="wide",
47
+ initial_sidebar_state="expanded",
48
+ )
49
+
50
+ # --- App State Initialization ---
51
+ if "user_id" not in st.session_state:
52
+ st.session_state.user_id = st.session_state.get("username", f"user_{int(time.time())}")
53
+ if "score_tracker" not in st.session_state:
54
+ st.session_state.score_tracker = ScoreTracker(st.session_state.user_id)
55
+ if "theme" not in st.session_state:
56
+ st.session_state.theme = "default"
57
+ if "language" not in st.session_state:
58
+ st.session_state.language = "en"
59
+ if "topic" not in st.session_state:
60
+ st.session_state.topic = "Python programming"
61
+
62
+ # --- Load UI Text based on Language ---
63
+ ui = get_translated_texts(st.session_state.language)
64
+
65
+ # --- Update Page Title with Translated Text ---
66
+ st.title(f"{ui.get('app_name', 'TriviaVerse')} - {ui.get('enhanced_edition', 'Enhanced Edition')}")
67
+
68
+ # Initialize other session state variables
69
+ if "current_streak" not in st.session_state:
70
+ st.session_state.current_streak = 0
71
+ if "adaptive_engine" not in st.session_state:
72
+ st.session_state.adaptive_engine = AdaptiveEngine(st.session_state.user_id)
73
+ if "answer" not in st.session_state:
74
+ st.session_state.answer = None
75
+ if "mcq_quiz_questions" not in st.session_state:
76
+ st.session_state.mcq_quiz_questions = []
77
+ if "current_question_index" not in st.session_state:
78
+ st.session_state.current_question_index = 0
79
+ if "quiz_started" not in st.session_state:
80
+ st.session_state.quiz_started = False
81
+ if "quiz_results" not in st.session_state:
82
+ st.session_state.quiz_results = []
83
+ if "flashcard_deck" not in st.session_state:
84
+ st.session_state.flashcard_deck = []
85
+ if "current_flashcard_index" not in st.session_state:
86
+ st.session_state.current_flashcard_index = 0
87
+ if "challenge_manager" not in st.session_state:
88
+ st.session_state.challenge_manager = ChallengeManager()
89
+ if "current_challenge_id" not in st.session_state:
90
+ st.session_state.current_challenge_id = None
91
+ if "challenge_quiz_questions" not in st.session_state:
92
+ st.session_state.challenge_quiz_questions = []
93
+ if "challenge_current_question_index" not in st.session_state:
94
+ st.session_state.challenge_current_question_index = 0
95
+ if "game_state" not in st.session_state:
96
+ st.session_state.game_state = "menu"
97
+ if "challenge_created_id" not in st.session_state:
98
+ st.session_state.challenge_created_id = None
99
+ if "current_page" not in st.session_state:
100
+ st.session_state.current_page = "home"
101
+
102
+ # --- Authentication ---
103
+ init_authentication()
104
+ if not authenticate_user():
105
+ st.stop()
106
+
107
+ # --- UI Rendering ---
108
+ apply_custom_theme(st.session_state.theme)
109
+ st.markdown(responsive_css(), unsafe_allow_html=True)
110
+
111
+ def render_homepage():
112
+ st.markdown(f"""
113
+ <div class="homepage-container" style="text-align: center;">
114
+ <h1 class="homepage-title">{ui.get('app_name', 'TriviaVerse')}</h1>
115
+ <p class="homepage-description">{ui.get('app_description', 'A Dynamic Quiz App')}</p>
116
+ <br><br>
117
+ """, unsafe_allow_html=True)
118
+
119
+ if st.button(ui.get('start_your_learning_journey', "Start Your Learning Journey"), key="start_journey"):
120
+ st.session_state.current_page = "game_modes"
121
+ st.rerun()
122
+
123
+ with st.sidebar:
124
+ st.title(f"🎯 {ui.get('app_name', 'TriviaVerse')}")
125
+ st.markdown(f"### 🎮 {ui.get('game_settings', 'Game Settings')}")
126
+
127
+ if st.button(f"🏠 {ui.get('home', 'Home')}", key="sidebar_home"):
128
+ st.session_state.current_page = "home"
129
+ st.rerun()
130
+
131
+ st.divider()
132
+
133
+ lang_choice_key = st.selectbox(
134
+ f"🌐 {ui.get('choose_language', 'Choose Language')}",
135
+ options=list(SUPPORTED_LANGUAGES.keys()),
136
+ index=list(SUPPORTED_LANGUAGES.values()).index(st.session_state.language)
137
+ )
138
+ if SUPPORTED_LANGUAGES[lang_choice_key] != st.session_state.language:
139
+ st.session_state.language = SUPPORTED_LANGUAGES[lang_choice_key]
140
+ st.rerun()
141
+
142
+ st.info(f"👤 {ui.get('welcome', 'Welcome')}, {st.session_state.get('username', 'Guest')}!")
143
+
144
+ theme_select = st.selectbox(
145
+ f"🎨 {ui.get('choose_theme', 'Choose Theme')}",
146
+ list(THEMES.keys()),
147
+ index=list(THEMES.keys()).index(st.session_state.theme),
148
+ )
149
+ if theme_select != st.session_state.theme:
150
+ st.session_state.theme = theme_select
151
+ st.rerun()
152
+
153
+ st.divider()
154
+
155
+ mode = st.radio(
156
+ f"🎲 {ui.get('select_game_mode', 'Select Game Mode')}",
157
+ [ui.get(k, k) for k in ["mcq_quiz", "flashcards", "fact_game", "challenge_mode", "page_info"]],
158
+ )
159
+
160
+ use_adaptive = st.checkbox(f"🤖 {ui.get('use_adaptive_difficulty', 'Use Adaptive Difficulty')}", value=True)
161
+ difficulty = st.session_state.adaptive_engine.get_recommended_difficulty() if use_adaptive else st.selectbox(
162
+ f"⚡ {ui.get('difficulty_level', 'Difficulty Level')}",
163
+ list(DIFFICULTY_LEVELS.keys()),
164
+ )
165
+ if use_adaptive:
166
+ st.info(f"{ui.get('recommended', 'Recommended')}: {difficulty}")
167
+
168
+ st.markdown(f"### 📖 {ui.get('choose_topic', 'Choose Topic')}")
169
+
170
+ def update_topic_text_input():
171
+ st.session_state.topic = st.session_state.topic_text_input
172
+
173
+ st.text_input(ui.get("enter_topic", "Enter topic"), value=st.session_state.topic, key="topic_text_input", on_change=update_topic_text_input)
174
+
175
+ def update_random_topic():
176
+ st.session_state.topic = random.choice(RANDOM_TOPICS)
177
+
178
+ if st.button(f"🎲 {ui.get('random_topic', 'Random')}", on_click=update_random_topic):
179
+ pass # The topic is updated by the on_click callback
180
+
181
+ st.markdown(f"### 🔥 {ui.get('trending_topics', 'Trending Topics')}")
182
+ def update_trending_topic():
183
+ if st.session_state.trending_topic_select:
184
+ st.session_state.topic = st.session_state.trending_topic_select
185
+
186
+ st.selectbox(ui.get("quick_select", "Quick select"), [""] + RANDOM_TOPICS, key="trending_topic_select", on_change=update_trending_topic)
187
+
188
+ if mode in [ui.get("mcq_quiz"), ui.get("challenge_mode")]:
189
+ st.markdown(f"### 🔢 {ui.get('number_of_questions', 'Number of Questions')}")
190
+ st.session_state.num_questions = st.selectbox(ui.get("select_number_of_questions", "Select number"), [5, 10, 15], index=1)
191
+
192
+ st.divider()
193
+ st.markdown(f"### 📊 {ui.get('your_stats', 'Your Stats')}")
194
+ stats = st.session_state.score_tracker.get_stats()
195
+ display_user_stats(stats, ui)
196
+
197
+ if st.button(f"🚪 {ui.get('logout', 'Logout')}", type="secondary", use_container_width=True):
198
+ st.session_state.clear()
199
+ st.rerun()
200
+
201
+ if st.session_state.current_page == "home":
202
+ render_homepage()
203
+ else:
204
+ # Header with user dashboard
205
+ col1, col2 = st.columns([2, 1])
206
+ with col1:
207
+ st.markdown(f"<h1 class='app-title'>🎮 {ui.get('app_name', 'TriviaVerse')} - {ui.get('enhanced_edition', 'Enhanced Edition')}</h1>", unsafe_allow_html=True)
208
+ st.markdown(f"*{ui.get('app_description', 'A gamified learning platform powered by Wikimedia')}*")
209
+ with col2:
210
+ # Display current time and greeting
211
+ current_hour = datetime.now().hour
212
+ greeting = (
213
+ ui.get("good_morning", "Good morning")
214
+ if current_hour < 12
215
+ else ui.get("good_afternoon", "Good afternoon")
216
+ if current_hour < 18
217
+ else ui.get("good_evening", "Good evening")
218
+ )
219
+ st.markdown(f"### {greeting}, {st.session_state.get('username', 'Learner')}! 👋")
220
+ st.caption(f"{datetime.now().strftime('%B %d, %Y - %I:%M %p')}")
221
+
222
+ # Display user statistics dashboard
223
+ stats = st.session_state.score_tracker.get_stats()
224
+ display_user_stats(stats, ui)
225
+
226
+ # Display badges
227
+ if stats["badges"]:
228
+ st.markdown(f"### 🏅 {ui.get('your_achievements', 'Your Achievements')}")
229
+ display_badges(stats["badges"], ui)
230
+
231
+ # Progress chart
232
+ with st.expander(f"📈 {ui.get('view_detailed_progress', 'View Detailed Progress')}", expanded=False):
233
+ if stats["quizzes_completed"] > 0:
234
+ fig = create_progress_chart(stats, ui)
235
+ st.plotly_chart(fig, use_container_width=True)
236
+ else:
237
+ st.info(ui.get("complete_quizzes_prompt", "Complete some quizzes to see your progress chart!"))
238
+
239
+ st.divider()
240
+
241
+ # Main game area
242
+ if mode == ui.get("mcq_quiz"):
243
+ st.header(ui.get("mcq_quiz"))
244
+
245
+ # Initialize or reset quiz
246
+ if not st.session_state.quiz_started:
247
+ if st.button(ui.get("start_new_quiz", "Start New Quiz"), type="primary", use_container_width=True):
248
+ with st.spinner(ui.get("generating_quiz_questions", "Generating quiz questions...")):
249
+ st.session_state.mcq_quiz_questions = generate_quiz_set(
250
+ st.session_state.topic,
251
+ difficulty,
252
+ st.session_state.num_questions
253
+ )
254
+ if st.session_state.mcq_quiz_questions:
255
+ st.session_state.current_question_index = 0
256
+ st.session_state.quiz_started = True
257
+ st.session_state.answered = False
258
+ st.session_state.question_start_time = time.time()
259
+ st.session_state.hints_used = 0
260
+ st.session_state.quiz_results = [] # Reset quiz results
261
+ st.rerun()
262
+ else:
263
+ st.error(ui.get("failed_quiz_generation", "Failed to generate quiz questions. Please try a different topic."))
264
+
265
+ if st.session_state.quiz_started and st.session_state.mcq_quiz_questions:
266
+ # Display current question
267
+ current_mcq = st.session_state.mcq_quiz_questions[st.session_state.current_question_index]
268
+ question_number = st.session_state.current_question_index + 1
269
+ total_questions = len(st.session_state.mcq_quiz_questions)
270
+
271
+ st.subheader(f"{ui.get('question', 'Question')} {question_number} {ui.get('of', 'of')} {total_questions}")
272
+
273
+ col1, col2, col3 = responsive_columns([1, 1, 1], [1, 1, 1])
274
+ with col2:
275
+ time_limit = DIFFICULTY_LEVELS[difficulty]["time_limit"]
276
+ st.info(f"⏱️ {ui.get('time_limit', 'Time Limit')}: {time_limit}s")
277
+ with col3:
278
+ hints_allowed = DIFFICULTY_LEVELS[difficulty]["hints_allowed"]
279
+ st.info(f"💡 {ui.get('hints', 'Hints')}: {hints_allowed}")
280
+
281
+ # Timer
282
+ elapsed_time = int(time.time() - st.session_state.question_start_time)
283
+ remaining_time = max(0, time_limit - elapsed_time)
284
+
285
+ if remaining_time > 0 and not st.session_state.answered:
286
+ st.progress(remaining_time / time_limit)
287
+ st.caption(f"⏱️ {ui.get('time_remaining', 'Time remaining')}: {remaining_time}s")
288
+
289
+ create_quiz_card(
290
+ current_mcq["question"],
291
+ current_mcq["options"],
292
+ key="answer"
293
+ )
294
+
295
+ if hints_allowed > st.session_state.hints_used:
296
+ if st.button(f"💡 {ui.get('get_hint', 'Get Hint')} ({hints_allowed - st.session_state.hints_used} {ui.get('left', 'left')})"):
297
+ st.session_state.hints_used += 1
298
+ st.info(f"💡 {ui.get('hint', 'Hint')}: {current_mcq['explanation'][:100]}...")
299
+
300
+ col1_btn, col2_btn, col3_btn = st.columns([1, 2, 1])
301
+ with col2_btn:
302
+ if st.button(ui.get("submit_answer", "Submit Answer"), type="primary", use_container_width=True):
303
+ is_correct = st.session_state.answer == current_mcq["correct_answer"]
304
+ st.session_state.answered = True
305
+ st.session_state.quiz_results.append({
306
+ "question": current_mcq["question"],
307
+ "user_answer": st.session_state.answer,
308
+ "correct_answer": current_mcq["correct_answer"],
309
+ "is_correct": is_correct,
310
+ "explanation": current_mcq["explanation"]
311
+ })
312
+ st.session_state.adaptive_engine.update_performance(is_correct, difficulty, topic=current_mcq.get("topic"))
313
+ if is_correct:
314
+ st.session_state.current_streak += 1
315
+ points = st.session_state.score_tracker.add_quiz_result("MCQ Quiz", 1, 1, difficulty)
316
+ animated_success(f"{ui.get('correct', 'Correct')}! +{points} {ui.get('points', 'points')}")
317
+ st.balloons()
318
+ else:
319
+ st.session_state.current_streak = 0
320
+ st.error(f"❌ {ui.get('incorrect', 'Incorrect')}. {ui.get('the_answer_was', 'The answer was')}: {current_mcq['correct_answer']}")
321
+ st.info(f"📚 {current_mcq['explanation']}")
322
+ st.rerun()
323
+ elif st.session_state.answered:
324
+ if st.session_state.current_question_index < total_questions - 1:
325
+ if st.button(ui.get("next_question", "Next Question"), type="secondary", use_container_width=True):
326
+ st.session_state.current_question_index += 1
327
+ st.session_state.answered = False
328
+ st.session_state.question_start_time = time.time()
329
+ st.session_state.hints_used = 0
330
+ st.rerun()
331
+ else:
332
+ st.success(ui.get("quiz_completed", "Quiz Completed!"))
333
+ st.session_state.quiz_started = False
334
+ st.session_state.mcq_quiz_questions = []
335
+ st.session_state.current_question_index = 0
336
+ st.markdown(f"### {ui.get('quiz_results_summary', 'Quiz Results Summary')}")
337
+ for i, result in enumerate(st.session_state.quiz_results):
338
+ st.markdown(f"**{ui.get('question', 'Question')} {i+1}:** {result['question']}")
339
+ if result['is_correct']:
340
+ st.success(f"✅ {ui.get('your_answer', 'Your Answer')}: {result['user_answer']} ({ui.get('correct', 'Correct')})")
341
+ else:
342
+ st.error(f"❌ {ui.get('your_answer', 'Your Answer')}: {result['user_answer']} ({ui.get('incorrect', 'Incorrect')})")
343
+ st.info(f"{ui.get('correct_answer', 'Correct Answer')}: {result['correct_answer']}")
344
+ st.caption(f"{ui.get('explanation', 'Explanation')}: {result['explanation']}")
345
+ st.divider()
346
+ if st.button(ui.get("start_new_quiz", "Start New Quiz"), type="primary", use_container_width=True):
347
+ st.rerun()
348
+ else:
349
+ st.error(f"⏱️ {ui.get('times_up', 'Time is up!')}")
350
+ st.session_state.answered = True
351
+ st.session_state.quiz_results.append({
352
+ "question": current_mcq["question"],
353
+ "user_answer": ui.get("no_answer_timed_out", "No answer (Time's up)"),
354
+ "correct_answer": current_mcq["correct_answer"],
355
+ "is_correct": False,
356
+ "explanation": current_mcq["explanation"]
357
+ })
358
+ st.session_state.score_tracker.add_quiz_result("MCQ Quiz", 0, 1, difficulty)
359
+ st.rerun()
360
+
361
+ elif mode == ui.get("flashcards"):
362
+ st.header(ui.get("interactive_flashcards", "Interactive Flashcards"))
363
+
364
+ if st.button(ui.get("generate_flashcard", "Generate Flashcard"), type="primary"):
365
+ with st.spinner(ui.get("creating_flashcard_deck", "Creating flashcard deck...")):
366
+ st.session_state.flashcard_deck = generate_smart_deck(
367
+ st.session_state.topic,
368
+ deck_size=10,
369
+ difficulty=difficulty,
370
+ adaptive_engine=st.session_state.adaptive_engine
371
+ )
372
+ if st.session_state.flashcard_deck:
373
+ st.session_state.current_flashcard_index = 0
374
+ st.session_state.card_flipped = False
375
+ st.rerun()
376
+ else:
377
+ st.error(ui.get("failed_flashcard_generation", "Failed to generate flashcards. Please try a different topic."))
378
+
379
+ if st.session_state.flashcard_deck:
380
+ current_flashcard = st.session_state.flashcard_deck[st.session_state.current_flashcard_index]
381
+ st.subheader(f"{ui.get('flashcard', 'Flashcard')} {st.session_state.current_flashcard_index + 1} {ui.get('of', 'of')} {len(st.session_state.flashcard_deck)}")
382
+
383
+ col1, col2, col3 = st.columns([1, 2, 1])
384
+ with col2:
385
+ render_flashcard(
386
+ current_flashcard["front"],
387
+ current_flashcard["back"],
388
+ is_flipped=st.session_state.get("card_flipped", False),
389
+ )
390
+
391
+ if not st.session_state.get("card_flipped", False):
392
+ if st.button(ui.get("flip_card", "Flip Card"), use_container_width=True):
393
+ st.session_state.card_flipped = True
394
+ st.rerun()
395
+ else:
396
+ st.write("")
397
+ btn_col1, btn_col2 = st.columns(2)
398
+ with btn_col1:
399
+ if st.button(ui.get("got_it", "Got it!"), use_container_width=True):
400
+ st.session_state.adaptive_engine.update_performance(
401
+ is_correct=True,
402
+ difficulty=current_flashcard.get("difficulty", "Medium"),
403
+ item_id=current_flashcard.get("item_id"),
404
+ topic=current_flashcard.get("topic")
405
+ )
406
+ points = st.session_state.score_tracker.add_quiz_result("Flashcards", 1, 1, current_flashcard.get("difficulty", "Medium"))
407
+ animated_success(f"{ui.get('great', 'Great')}! +{points} {ui.get('points', 'points')}")
408
+ st.session_state.card_flipped = False
409
+ if st.session_state.current_flashcard_index < len(st.session_state.flashcard_deck) - 1:
410
+ st.session_state.current_flashcard_index += 1
411
+ else:
412
+ st.success(ui.get("flashcard_deck_completed", "Flashcard Deck Completed!"))
413
+ st.session_session.flashcard_deck = []
414
+ st.session_state.current_flashcard_index = 0
415
+ st.rerun()
416
+ with btn_col2:
417
+ if st.button(ui.get("need_practice", "Need Practice"), use_container_width=True):
418
+ st.session_state.adaptive_engine.update_performance(
419
+ is_correct=False,
420
+ difficulty=current_flashcard.get("difficulty", "Medium"),
421
+ item_id=current_flashcard.get("item_id"),
422
+ topic=current_flashcard.get("topic")
423
+ )
424
+ st.session_state.score_tracker.add_quiz_result("Flashcards", 0, 1, current_flashcard.get("difficulty", "Medium"))
425
+ st.session_state.card_flipped = False
426
+ if st.session_state.current_flashcard_index < len(st.session_state.flashcard_deck) - 1:
427
+ st.session_state.current_flashcard_index += 1
428
+ else:
429
+ st.info(ui.get("flashcard_deck_completed_practice", "Flashcard Deck Completed. Keep practicing!"))
430
+ st.session_state.flashcard_deck = []
431
+ st.session_state.current_flashcard_index = 0
432
+ st.rerun()
433
+ else:
434
+ st.info(ui.get("no_flashcards_in_deck", "No flashcards in deck. Click 'Generate Flashcard' to create a new one."))
435
+
436
+ elif mode == ui.get("fact_game"):
437
+ st.header(ui.get("random_fact_game", "Random Fact Game"))
438
+
439
+ col1, col2 = st.columns([2, 1])
440
+
441
+ with col1:
442
+ if st.button(ui.get("get_random_fact", "Get Random Fact"), type="primary", use_container_width=True):
443
+ if "current_fact" in st.session_state:
444
+ del st.session_state["current_fact"]
445
+
446
+ with st.spinner(ui.get("finding_interesting_fact", "Finding an interesting fact...")):
447
+ fact = generate_random_fact()
448
+ if fact.get("status"):
449
+ st.session_state.current_fact = fact
450
+ st.session_state.fact_start_time = time.time()
451
+ else:
452
+ st.session_state.current_fact = {"status": False}
453
+
454
+ with col2:
455
+ st.info(f"⏱️ {ui.get('quick_read_challenge', 'Quick Read Challenge')}: 15s")
456
+
457
+ if "current_fact" in st.session_state:
458
+ fact = st.session_state.current_fact
459
+
460
+ if fact.get("status"):
461
+ elapsed = int(time.time() - st.session_state.get("fact_start_time", time.time()))
462
+ remaining = max(0, 15 - elapsed)
463
+
464
+ if remaining > 0:
465
+ st.progress(remaining / 15)
466
+ st.markdown(
467
+ f"""
468
+ <div class="quiz-container">
469
+ <h3>🌟 {ui.get('did_you_know', 'Did you know?')}</h3>
470
+ <p style="font-size: 18px; line-height: 1.8;">{fact["fact"]}</p>
471
+ <p style="margin-top: 20px; color: #666;">{ui.get('topic', 'Topic')}: <strong>{fact["topic"]}</strong></p>
472
+ </div>
473
+ """,
474
+ unsafe_allow_html=True,
475
+ )
476
+ if st.button(ui.get("interesting_next_fact", "Interesting! Next fact")):
477
+ points = st.session_state.score_tracker.add_quiz_result("Fact Game", 1, 1, difficulty)
478
+ animated_success(f"{ui.get('knowledge_gained', 'Knowledge gained')}! +{points} {ui.get('points', 'points')}")
479
+ del st.session_state["current_fact"]
480
+ else:
481
+ st.success(ui.get("times_up_next_fact", "Time's up! Ready for the next fact?"))
482
+ if st.button(ui.get("next_fact", "Next Fact")):
483
+ del st.session_state["current_fact"]
484
+ else:
485
+ st.error(ui.get("failed_fact_generation", "Failed to generate fact. Please try again."))
486
+
487
+ elif mode == ui.get("challenge_mode"):
488
+ st.header(ui.get("challenge_mode", "Challenge Mode"))
489
+
490
+ if not st.session_state.current_challenge_id:
491
+ tab1, tab2 = st.tabs([ui.get("create_challenge", "Create Challenge"), ui.get("join_challenge", "Join Challenge")])
492
+
493
+ with tab1:
494
+ st.subheader(ui.get("create_new_challenge", "Create a New Challenge"))
495
+ with st.form("create_challenge_form"):
496
+ challenge_topic = st.text_input(ui.get("challenge_topic", "Challenge Topic"), value=st.session_state.topic)
497
+ challenge_difficulty = st.selectbox(
498
+ ui.get("challenge_difficulty", "Challenge Difficulty"),
499
+ list(DIFFICULTY_LEVELS.keys()),
500
+ index=list(DIFFICULTY_LEVELS.keys()).index(difficulty),
501
+ )
502
+ challenge_num_questions = st.selectbox(
503
+ ui.get("number_of_questions", "Number of Questions"),
504
+ [5, 10, 15],
505
+ index=[5, 10, 15].index(st.session_state.get("num_questions", 5)),
506
+ )
507
+ create_challenge_submitted = st.form_submit_button(ui.get("create_challenge", "Create Challenge"), type="primary")
508
+
509
+ if create_challenge_submitted:
510
+ new_challenge_id = st.session_state.challenge_manager.create_challenge(
511
+ creator_id=st.session_state.user_id,
512
+ topic=challenge_topic,
513
+ difficulty=challenge_difficulty,
514
+ num_questions=challenge_num_questions
515
+ )
516
+ st.session_state.challenge_created_id = new_challenge_id
517
+ st.success(f"{ui.get('challenge_created', 'Challenge created! Share this ID')}: **{new_challenge_id}**")
518
+
519
+ if st.session_state.challenge_created_id:
520
+ st.info(f"{ui.get('challenge_id', 'Challenge ID')}: **{st.session_state.challenge_created_id}**")
521
+ if st.button(ui.get("start_challenge_play", "Start Challenge Play"), key="start_created_challenge"):
522
+ st.session_state.current_challenge_id = st.session_state.challenge_created_id
523
+ st.session_state.challenge_quiz_questions = generate_quiz_set(
524
+ st.session_state.challenge_manager.get_challenge(st.session_state.current_challenge_id)["topic"],
525
+ st.session_state.challenge_manager.get_challenge(st.session_state.current_challenge_id)["difficulty"],
526
+ st.session_state.challenge_manager.get_challenge(st.session_state.current_challenge_id)["num_questions"]
527
+ )
528
+ st.session_state.challenge_quiz_started = True
529
+ st.session_state.challenge_current_question_index = 0
530
+ st.session_state.answered = False
531
+ st.session_state.question_start_time = time.time()
532
+ st.session_state.hints_used = 0
533
+ st.session_state.quiz_results = []
534
+ st.session_state.challenge_created_id = None
535
+ st.rerun()
536
+
537
+ with tab2:
538
+ st.subheader(ui.get("join_existing_challenge", "Join an Existing Challenge"))
539
+ with st.form("join_challenge_form"):
540
+ join_challenge_id = st.text_input(ui.get("enter_challenge_id", "Enter Challenge ID"))
541
+ join_challenge_submitted = st.form_submit_button(ui.get("join_challenge", "Join Challenge"), type="primary")
542
+
543
+ if join_challenge_submitted:
544
+ challenge = st.session_state.challenge_manager.get_challenge(join_challenge_id)
545
+ if challenge:
546
+ st.success(f"{ui.get('joined_challenge', 'Joined challenge')}: {challenge['topic']} ({challenge['difficulty']})")
547
+ st.session_state.current_challenge_id = join_challenge_id
548
+ st.session_state.challenge_quiz_questions = generate_quiz_set(
549
+ challenge["topic"],
550
+ challenge["difficulty"],
551
+ challenge["num_questions"]
552
+ )
553
+ st.session_state.challenge_quiz_started = True
554
+ st.session_state.challenge_current_question_index = 0
555
+ st.session_state.answered = False
556
+ st.session_state.question_start_time = time.time()
557
+ st.session_state.hints_used = 0
558
+ st.session_state.quiz_results = []
559
+ st.rerun()
560
+ else:
561
+ st.error(ui.get("challenge_not_found", "Challenge not found. Please check the ID."))
562
+
563
+ if st.session_state.current_challenge_id:
564
+ current_challenge = st.session_state.challenge_manager.get_challenge(st.session_state.current_challenge_id)
565
+ if current_challenge:
566
+ st.markdown(f"---")
567
+ st.subheader(f"{ui.get('active_challenge', 'Active Challenge')}: {current_challenge['topic']} ({current_challenge['difficulty']})")
568
+ st.write(f"{ui.get('created_by', 'Created by')}: {current_challenge['creator_id']}")
569
+ st.write(f"{ui.get('questions', 'Questions')}: {current_challenge['num_questions']}")
570
+
571
+ st.markdown(f"#### {ui.get('participants', 'Participants')}:")
572
+ if current_challenge["participants"]:
573
+ for participant_id, p_data in current_challenge["participants"].items():
574
+ st.write(f"- {participant_id}: {ui.get('score', 'Score')} {p_data['score']} ({ui.get('completed', 'Completed')}: {p_data.get('completed_at', 'N/A')})")
575
+ else:
576
+ st.write(ui.get("no_participants_yet", "No participants yet."))
577
+
578
+ if st.session_state.challenge_quiz_started and st.session_state.challenge_quiz_questions:
579
+ current_mcq = st.session_state.challenge_quiz_questions[st.session_state.challenge_current_question_index]
580
+ question_number = st.session_state.challenge_current_question_index + 1
581
+ total_questions = len(st.session_state.challenge_quiz_questions)
582
+
583
+ st.subheader(f"{ui.get('challenge_question', 'Challenge Question')} {question_number} {ui.get('of', 'of')} {total_questions}")
584
+
585
+ col1, col2, col3 = responsive_columns([1, 1, 1], [1, 1, 1])
586
+ with col2:
587
+ time_limit = DIFFICULTY_LEVELS[current_challenge['difficulty']]["time_limit"]
588
+ st.info(f"⏱️ {ui.get('time_limit', 'Time Limit')}: {time_limit}s")
589
+ with col3:
590
+ hints_allowed = DIFFICULTY_LEVELS[current_challenge['difficulty']]["hints_allowed"]
591
+ st.info(f"💡 {ui.get('hints', 'Hints')}: {hints_allowed}")
592
+
593
+ elapsed_time = int(time.time() - st.session_state.question_start_time)
594
+ remaining_time = max(0, time_limit - elapsed_time)
595
+
596
+ if remaining_time > 0 and not st.session_state.answered:
597
+ st.progress(remaining_time / time_limit)
598
+ st.caption(f"⏱️ {ui.get('time_remaining', 'Time remaining')}: {remaining_time}s")
599
+
600
+ create_quiz_card(current_mcq["question"], current_mcq["options"], key="challenge_answer")
601
+
602
+ if hints_allowed > st.session_state.hints_used:
603
+ if st.button(f"💡 {ui.get('get_hint', 'Get Hint')} ({hints_allowed - st.session_state.hints_used} {ui.get('left', 'left')})"):
604
+ st.session_state.hints_used += 1
605
+ st.info(f"💡 {ui.get('hint', 'Hint')}: {current_mcq['explanation'][:100]}...")
606
+
607
+ col1_btn, col2_btn, col3_btn = st.columns([1, 2, 1])
608
+ with col2_btn:
609
+ if st.button(ui.get("submit_answer", "Submit Answer"), type="primary", use_container_width=True):
610
+ is_correct = st.session_state.challenge_answer == current_mcq["correct_answer"]
611
+ st.session_state.answered = True
612
+ st.session_state.quiz_results.append({
613
+ "question": current_mcq["question"],
614
+ "user_answer": st.session_state.challenge_answer,
615
+ "correct_answer": current_mcq["correct_answer"],
616
+ "is_correct": is_correct,
617
+ "explanation": current_mcq["explanation"]
618
+ })
619
+ st.session_state.adaptive_engine.update_performance(is_correct, current_challenge['difficulty'], topic=current_mcq.get("topic"))
620
+ if is_correct:
621
+ st.session_state.current_streak += 1
622
+ points = st.session_state.score_tracker.add_quiz_result("Challenge Mode", 1, 1, current_challenge['difficulty'])
623
+ animated_success(f"{ui.get('correct', 'Correct')}! +{points} {ui.get('points', 'points')}")
624
+ st.balloons()
625
+ else:
626
+ st.session_state.current_streak = 0
627
+ st.error(f"❌ {ui.get('incorrect', 'Incorrect')}. {ui.get('the_answer_was', 'The answer was')}: {current_mcq['correct_answer']}")
628
+ st.info(f"📚 {current_mcq['explanation']}")
629
+ st.rerun()
630
+ elif st.session_state.answered:
631
+ if st.session_state.challenge_current_question_index < total_questions - 1:
632
+ if st.button(ui.get("next_question", "Next Question"), type="secondary", use_container_width=True):
633
+ st.session_state.challenge_current_question_index += 1
634
+ st.session_state.answered = False
635
+ st.session_state.question_start_time = time.time()
636
+ st.session_state.hints_used = 0
637
+ st.rerun()
638
+ else:
639
+ st.success(ui.get("challenge_quiz_completed", "Challenge Quiz Completed!"))
640
+ final_score = sum(1 for r in st.session_state.quiz_results if r['is_correct'])
641
+ st.session_state.challenge_manager.update_challenge_score(
642
+ st.session_state.current_challenge_id,
643
+ st.session_state.user_id,
644
+ final_score,
645
+ st.session_state.quiz_results
646
+ )
647
+ st.session_state.challenge_quiz_started = False
648
+ st.session_state.challenge_quiz_questions = []
649
+ st.session_state.challenge_current_question_index = 0
650
+ st.session_state.current_challenge_id = None
651
+ st.rerun()
652
+ else:
653
+ st.error(f"⏱️ {ui.get('times_up', 'Time is up!')}")
654
+ st.session_state.answered = True
655
+ st.session_state.quiz_results.append({
656
+ "question": current_mcq["question"],
657
+ "user_answer": ui.get("no_answer_timed_out", "No answer (Time's up)"),
658
+ "correct_answer": current_mcq["correct_answer"],
659
+ "is_correct": False,
660
+ "explanation": current_mcq["explanation"]
661
+ })
662
+ st.session_state.score_tracker.add_quiz_result("Challenge Mode", 0, 1, difficulty)
663
+ st.rerun()
664
+
665
+ elif mode == ui.get("page_info"):
666
+ st.header(ui.get("page_information", "Page Information"))
667
+ st.write(ui.get("get_page_info_prompt", "Get detailed information and images for any topic."))
668
+
669
+ info_topic = st.text_input(ui.get("enter_topic_for_info", "Enter Topic for Information"), value=st.session_state.topic)
670
+ num_images = st.slider(ui.get("number_of_images", "Number of Images"), 0, 5, 1)
671
+
672
+ if st.button(ui.get("get_information", "Get Information"), type="primary"):
673
+ with st.spinner(f"{ui.get('fetching_information_for', 'Fetching information for')} {info_topic}..."):
674
+ display_page_info(info_topic, num_images)
675
+
676
+ st.divider()
677
+ st.markdown(f"""
678
+ <div style='text-align: center'>
679
+ <p>{ui.get('made_with', 'Made with')} ❤️ {ui.get('using_streamlit_and_wikimedia', 'using Streamlit and Wikimedia APIs')}</p>
680
+ <p style='opacity: 0.7; font-size: 0.9em;'>{ui.get('app_name', 'TriviaVerse')} v2.0 - {ui.get('enhanced_edition', 'Enhanced Edition')}</p>
681
+ </div>
682
+ """, unsafe_allow_html=True)
notepad.txt ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ TriviaVerse/
2
+
3
+ ├── app.py # Main Streamlit application
4
+ ├── requirements.txt # Dependencies
5
+ ├── README.md # Documentation
6
+ ├── .gitignore # Git ignore file
7
+
8
+ ├── modules/ # Core modules
9
+ │ ├── __init__.py
10
+ │ ├── api_utils.py # API utilities
11
+ │ ├── mcq_generator.py # MCQ generation
12
+ │ ├── flashcard_generator.py # Flashcard generation
13
+ │ ├── fact_game.py # Fact game logic
14
+ │ └── adaptive_engine.py # Adaptive difficulty
15
+
16
+ ├── utils/ # Utilities
17
+ │ ├── __init__.py
18
+ │ ├── score_tracker.py # Score tracking system
19
+ │ ├── user_auth.py # User authentication
20
+ │ ├── ui_components.py # UI components
21
+ │ └── mobile_responsive.py # Mobile responsive helpers
22
+
23
+ ├── assets/ # Static assets
24
+ │ ├── style.css # Custom CSS
25
+ │ ├── logo.png # App logo
26
+ │ └── images/ # Additional images
27
+
28
+ ├── config/ # Configuration
29
+ │ ├── __init__.py
30
+ │ ├── settings.py # App settings
31
+ │ └── themes.py # UI themes
32
+
33
+ └── data/ # Data storage
34
+ └── user_scores.json # Local score storage