import streamlit as st
import sqlite3
import json
import random
from datetime import datetime
import os
# Import our custom modules
from components.mcq_generator import MCQGenerator
from utils.wiki_api import WikiAPI
from utils.translator import Translator
# Page configuration
st.set_page_config(
page_title="TriviaVerse - Multilingual Quiz Generator",
page_icon="๐ง ",
layout="wide",
initial_sidebar_state="expanded"
)
# Initialize session state
if 'current_quiz' not in st.session_state:
st.session_state.current_quiz = None
if 'score' not in st.session_state:
st.session_state.score = 0
if 'current_question' not in st.session_state:
st.session_state.current_question = 0
if 'user_answers' not in st.session_state:
st.session_state.user_answers = []
# Initialize components
@st.cache_resource
def initialize_components():
wiki_api = WikiAPI()
translator = Translator()
mcq_generator = MCQGenerator()
return wiki_api, translator, mcq_generator
def initialize_database():
"""Initialize SQLite database for offline storage"""
conn = sqlite3.connect('triviaverse.db')
cursor = conn.cursor()
cursor.execute('''
CREATE TABLE IF NOT EXISTS cached_content (
id INTEGER PRIMARY KEY AUTOINCREMENT,
topic TEXT NOT NULL,
language TEXT NOT NULL,
content TEXT NOT NULL,
summary TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
cursor.execute('''
CREATE TABLE IF NOT EXISTS quiz_history (
id INTEGER PRIMARY KEY AUTOINCREMENT,
topic TEXT NOT NULL,
language TEXT NOT NULL,
difficulty TEXT NOT NULL,
mode TEXT NOT NULL,
score INTEGER,
total_questions INTEGER,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
''')
conn.commit()
conn.close()
def main():
# Initialize database
initialize_database()
# Initialize components
wiki_api, translator, mcq_generator = initialize_components()
# Custom CSS
st.markdown("""
""", unsafe_allow_html=True)
# Main header
st.markdown('
๐ง TriviaVerse
', unsafe_allow_html=True)
st.markdown('Multilingual AI-Powered Quiz Generator
', unsafe_allow_html=True)
# Sidebar configuration
with st.sidebar:
st.markdown('', unsafe_allow_html=True)
# Generate quiz button
if st.button("๐ Generate Quiz", type="primary", use_container_width=True):
if topic:
generate_quiz(wiki_api, translator, mcq_generator, topic, selected_language,
difficulty, mode, is_online, num_questions)
else:
st.error("Please enter a topic!")
# Quiz history
st.markdown('', unsafe_allow_html=True)
# Main content area
if st.session_state.current_quiz:
display_quiz()
else:
display_welcome_screen()
def generate_quiz(wiki_api, translator, mcq_generator, topic, language, difficulty, mode, is_online, num_questions):
"""Generate a new quiz based on user parameters"""
with st.spinner(f"๐ Fetching content about '{topic}'..."):
# Fetch content from Wikipedia
if is_online:
content = wiki_api.fetch_content(topic, language)
if not content:
st.error("โ Could not fetch content. Try offline mode or a different topic.")
return
else:
content = load_cached_content(topic, language)
if not content:
st.error("โ No cached content found. Please try online mode first.")
return
with st.spinner("๐ง Generating quiz questions..."):
# Generate questions
questions = mcq_generator.generate_questions(
content, difficulty, num_questions, language, translator
)
if not questions:
st.error("โ Could not generate questions. Please try a different topic.")
return
# Store quiz in session state
st.session_state.current_quiz = {
'topic': topic,
'language': language,
'difficulty': difficulty,
'mode': mode,
'questions': questions,
'created_at': datetime.now()
}
# Reset quiz state
st.session_state.current_question = 0
st.session_state.score = 0
st.session_state.user_answers = []
# Cache content for offline use
if is_online:
cache_content(topic, language, content)
st.success(f"โ
Generated {len(questions)} questions successfully!")
st.rerun()
def display_quiz():
"""Display the current quiz"""
quiz = st.session_state.current_quiz
questions = quiz['questions']
current_q = st.session_state.current_question
# Progress bar
progress = (current_q + 1) / len(questions)
st.progress(progress, text=f"Question {current_q + 1} of {len(questions)}")
# Score display
if current_q > 0:
st.markdown(f'Score: {st.session_state.score}/{current_q}
',
unsafe_allow_html=True)
if current_q < len(questions):
question = questions[current_q]
# Display question
st.markdown(f'', unsafe_allow_html=True)
st.markdown(f"### Question {current_q + 1}")
st.markdown(f"**{question['question']}**")
st.markdown('
', unsafe_allow_html=True)
# Display options
if quiz['mode'] == 'mcq':
display_mcq_options(question, current_q)
elif quiz['mode'] == 'flashcard':
display_flashcard(question, current_q)
else: # game mode
display_game_mode(question, current_q)
else:
# Quiz completed
display_quiz_results()
def display_mcq_options(question, current_q):
"""Display multiple choice options"""
options = question['options']
# Use unique key for each question
selected_option = st.radio(
"Select your answer:",
options=options,
key=f"q_{current_q}",
index=None
)
col1, col2 = st.columns([1, 1])
with col1:
if st.button("Submit Answer", key=f"submit_{current_q}"):
if selected_option is not None:
answer_index = options.index(selected_option)
is_correct = answer_index == question['correct_answer']
if is_correct:
st.success("โ
Correct!")
st.session_state.score += 1
else:
st.error(f"โ Incorrect! The correct answer is: {options[question['correct_answer']]}")
# Show explanation
if question.get('explanation'):
st.info(f"๐ก Explanation: {question['explanation']}")
st.session_state.user_answers.append({
'question': question['question'],
'user_answer': selected_option,
'correct_answer': options[question['correct_answer']],
'is_correct': is_correct
})
st.session_state.current_question += 1
# Auto-advance after 3 seconds
st.rerun()
else:
st.warning("Please select an answer!")
with col2:
if st.button("Skip Question", key=f"skip_{current_q}"):
st.session_state.user_answers.append({
'question': question['question'],
'user_answer': "Skipped",
'correct_answer': options[question['correct_answer']],
'is_correct': False
})
st.session_state.current_question += 1
st.rerun()
def display_flashcard(question, current_q):
"""Display flashcard mode"""
if f"show_answer_{current_q}" not in st.session_state:
st.session_state[f"show_answer_{current_q}"] = False
if not st.session_state[f"show_answer_{current_q}"]:
if st.button("๐ Show Answer", key=f"show_{current_q}"):
st.session_state[f"show_answer_{current_q}"] = True
st.rerun()
else:
st.success(f"**Answer:** {question['options'][question['correct_answer']]}")
if question.get('explanation'):
st.info(f"๐ก Explanation: {question['explanation']}")
col1, col2 = st.columns(2)
with col1:
if st.button("โ
I knew it!", key=f"correct_{current_q}"):
st.session_state.score += 1
st.session_state.current_question += 1
st.rerun()
with col2:
if st.button("โ I didn't know", key=f"incorrect_{current_q}"):
st.session_state.current_question += 1
st.rerun()
def display_game_mode(question, current_q):
"""Display game mode with timer"""
# Simple game mode - similar to MCQ but with time pressure
st.markdown("โฐ **Quick Answer Mode!**")
display_mcq_options(question, current_q)
def display_quiz_results():
"""Display final quiz results"""
quiz = st.session_state.current_quiz
total_questions = len(quiz['questions'])
score = st.session_state.score
percentage = (score / total_questions) * 100
st.balloons()
# Results header
st.markdown('', unsafe_allow_html=True)
st.markdown(f"## ๐ Quiz Completed!")
st.markdown(f"### Final Score: {score}/{total_questions} ({percentage:.1f}%)")
st.markdown('
', unsafe_allow_html=True)
# Performance message
if percentage >= 80:
st.success("๐ Excellent! You're a trivia master!")
elif percentage >= 60:
st.info("๐ Good job! Keep learning!")
else:
st.warning("๐ Keep studying! You'll do better next time!")
# Save to history
save_quiz_history(quiz, score, total_questions)
# Detailed results
st.subheader("๐ Detailed Results")
for i, answer in enumerate(st.session_state.user_answers):
with st.expander(f"Question {i+1}: {answer['question'][:50]}..."):
st.write(f"**Your Answer:** {answer['user_answer']}")
st.write(f"**Correct Answer:** {answer['correct_answer']}")
if answer['is_correct']:
st.success("โ
Correct")
else:
st.error("โ Incorrect")
# Reset button
if st.button("๐ Take Another Quiz", type="primary"):
st.session_state.current_quiz = None
st.session_state.current_question = 0
st.session_state.score = 0
st.session_state.user_answers = []
st.rerun()
def display_welcome_screen():
"""Display welcome screen when no quiz is active"""
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
st.markdown("""
๐ฏ Welcome to TriviaVerse!
Generate intelligent quizzes on any topic in multiple Indian languages
โจ Features
- ๐ Multi-language support (Hindi, Telugu, Tamil, Kannada, Bengali)
- ๐ Wikipedia & Wikidata integration
- ๐ง AI-powered question generation
- ๐ฎ Multiple quiz modes (MCQ, Flashcards, Games)
- ๐ Difficulty levels and progress tracking
- ๐พ Offline mode with caching
๐ Configure your quiz in the sidebar and click "Generate Quiz" to start!
""", unsafe_allow_html=True)
def load_cached_content(topic, language):
"""Load content from local cache"""
conn = sqlite3.connect('triviaverse.db')
cursor = conn.cursor()
cursor.execute("""
SELECT content FROM cached_content
WHERE topic = ? AND language = ?
ORDER BY created_at DESC LIMIT 1
""", (topic, language))
result = cursor.fetchone()
conn.close()
return result[0] if result else None
def cache_content(topic, language, content):
"""Cache content for offline use"""
conn = sqlite3.connect('triviaverse.db')
cursor = conn.cursor()
cursor.execute("""
INSERT INTO cached_content (topic, language, content)
VALUES (?, ?, ?)
""", (topic, language, content))
conn.commit()
conn.close()
def save_quiz_history(quiz, score, total_questions):
"""Save quiz results to history"""
conn = sqlite3.connect('triviaverse.db')
cursor = conn.cursor()
cursor.execute("""
INSERT INTO quiz_history (topic, language, difficulty, mode, score, total_questions)
VALUES (?, ?, ?, ?, ?, ?)
""", (quiz['topic'], quiz['language'], quiz['difficulty'],
quiz['mode'], score, total_questions))
conn.commit()
conn.close()
def display_quiz_history():
"""Display recent quiz history"""
conn = sqlite3.connect('triviaverse.db')
cursor = conn.cursor()
cursor.execute("""
SELECT topic, score, total_questions, created_at
FROM quiz_history
ORDER BY created_at DESC
LIMIT 5
""")
results = cursor.fetchall()
conn.close()
if results:
for result in results:
topic, score, total, created_at = result
percentage = (score / total) * 100
st.write(f"๐ {topic}: {score}/{total} ({percentage:.0f}%)")
else:
st.write("No quiz history yet!")
if __name__ == "__main__":
main()