TriviaVerse_38 / app.py
RaghavenderReddy's picture
Upload 13 files
33a2aaf verified
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("""
<style>
.main-header {
text-align: center;
background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
font-size: 3rem;
font-weight: bold;
margin-bottom: 2rem;
}
.quiz-card {
background: white;
padding: 2rem;
border-radius: 15px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
margin: 1rem 0;
}
.score-display {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1rem;
border-radius: 10px;
text-align: center;
font-size: 1.2rem;
font-weight: bold;
}
.question-card {
background: #f8f9fa;
padding: 1.5rem;
border-radius: 10px;
border-left: 4px solid #667eea;
margin: 1rem 0;
}
.sidebar-section {
background: #f0f2f6;
padding: 1rem;
border-radius: 10px;
margin: 1rem 0;
}
</style>
""", unsafe_allow_html=True)
# Main header
st.markdown('<h1 class="main-header">🧠 TriviaVerse</h1>', unsafe_allow_html=True)
st.markdown('<p style="text-align: center; font-size: 1.2rem; color: #666;">Multilingual AI-Powered Quiz Generator</p>', unsafe_allow_html=True)
# Sidebar configuration
with st.sidebar:
st.markdown('<div class="sidebar-section">', unsafe_allow_html=True)
st.header("🎯 Quiz Configuration")
# Language selection
languages = {
'en': 'English',
'hi': 'हिंदी (Hindi)',
'te': 'తెలుగు (Telugu)',
'ta': 'தமிழ் (Tamil)',
'kn': 'ಕನ್ನಡ (Kannada)',
'bn': 'বাংলা (Bengali)'
}
selected_language = st.selectbox(
"🌐 Select Language",
options=list(languages.keys()),
format_func=lambda x: languages[x],
index=0
)
# Topic input
topic = st.text_input("📚 Enter Topic", placeholder="e.g., Indian History, Science, Technology")
# Mode selection
mode = st.selectbox(
"🎮 Select Mode",
options=['mcq', 'flashcard', 'game'],
format_func=lambda x: {
'mcq': '📝 Multiple Choice Questions',
'flashcard': '🃏 Flashcards',
'game': '🎲 Quiz Game'
}[x]
)
# Difficulty level
difficulty = st.selectbox(
"⚡ Difficulty Level",
options=['easy', 'medium', 'hard'],
format_func=lambda x: {
'easy': '🟢 Easy',
'medium': '🟡 Medium',
'hard': '🔴 Hard'
}[x]
)
# Online/Offline toggle
is_online = st.toggle("🌐 Online Mode", value=True)
# Number of questions
num_questions = st.slider("📊 Number of Questions", min_value=5, max_value=20, value=10)
st.markdown('</div>', 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('<div class="sidebar-section">', unsafe_allow_html=True)
st.subheader("📈 Recent Quizzes")
display_quiz_history()
st.markdown('</div>', 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'<div class="score-display">Score: {st.session_state.score}/{current_q}</div>',
unsafe_allow_html=True)
if current_q < len(questions):
question = questions[current_q]
# Display question
st.markdown(f'<div class="question-card">', unsafe_allow_html=True)
st.markdown(f"### Question {current_q + 1}")
st.markdown(f"**{question['question']}**")
st.markdown('</div>', 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('<div class="score-display">', unsafe_allow_html=True)
st.markdown(f"## 🎉 Quiz Completed!")
st.markdown(f"### Final Score: {score}/{total_questions} ({percentage:.1f}%)")
st.markdown('</div>', 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("""
<div style="text-align: center; padding: 2rem;">
<h2>🎯 Welcome to TriviaVerse!</h2>
<p style="font-size: 1.1rem; color: #666;">
Generate intelligent quizzes on any topic in multiple Indian languages
</p>
<div style="margin: 2rem 0;">
<h3>✨ Features</h3>
<ul style="text-align: left; display: inline-block;">
<li>🌐 Multi-language support (Hindi, Telugu, Tamil, Kannada, Bengali)</li>
<li>📚 Wikipedia & Wikidata integration</li>
<li>🧠 AI-powered question generation</li>
<li>🎮 Multiple quiz modes (MCQ, Flashcards, Games)</li>
<li>📊 Difficulty levels and progress tracking</li>
<li>💾 Offline mode with caching</li>
</ul>
</div>
<p style="color: #667eea; font-weight: bold;">
👈 Configure your quiz in the sidebar and click "Generate Quiz" to start!
</p>
</div>
""", 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()