Trivia1 / modules /mcq_generator.py
Bharath370's picture
Upload 16 files
5775a1b verified
# modules/mcq_generator.py
"""Enhanced MCQ Quiz Generator Module"""
import random
from typing import Dict, List, Tuple
from modules.api_utils import (
fetch_wikipedia_summary,
search_wikipedia,
fetch_related_topics,
fetch_wikipedia_categories,
)
def generate_smart_distractors(
correct_answer: str, topic: str, context: str
) -> List[str]:
"""Generate intelligent distractor options"""
distractors = set()
# Get related topics
related = fetch_related_topics(topic, 10)
distractors.update(related)
# Get categories and use them for distractors
categories = fetch_wikipedia_categories(topic)
if categories:
# Search for other items in the same categories
for category in categories[:2]:
similar_items = search_wikipedia(category, 5)
distractors.update(similar_items)
# Remove the correct answer and topic
distractors.discard(correct_answer)
distractors.discard(topic)
# Convert to list and shuffle
distractor_list = list(distractors)
random.shuffle(distractor_list)
# If not enough distractors, add generic ones
if len(distractor_list) < 3:
generic_distractors = [
"Scientific Theory",
"Historical Event",
"Mathematical Concept",
"Geographical Location",
"Literary Work",
"Technological Innovation",
"Cultural Phenomenon",
"Economic System",
"Political Movement",
]
distractor_list.extend(generic_distractors)
return distractor_list[:3]
def generate_question_types(topic: str, summary_data: Dict, difficulty: str) -> Dict:
"""Generate different types of questions based on difficulty"""
title = summary_data.get("title", topic)
extract = summary_data.get("extract", "")
description = summary_data.get("description", "")
question_templates = {
"Easy": [
f"What is {title}?",
f"Which of the following best describes {title}?",
f"What category does {title} belong to?",
],
"Medium": [
f"What is the primary characteristic of {title}?",
f"How is {title} commonly defined?",
f"Which statement about {title} is most accurate?",
],
"Hard": [
f"What distinguishes {title} from related concepts?",
f"In what context is {title} most significant?",
f"What is the key principle underlying {title}?",
],
}
# Select appropriate question
questions = question_templates.get(difficulty, question_templates["Easy"])
question = random.choice(questions)
# For harder difficulties, extract a more specific answer from the text
if difficulty == "Easy":
correct_answer = title
elif difficulty == "Medium":
# Try to find a defining characteristic
sentences = extract.split(".")
if len(sentences) > 1:
correct_answer = description if description else title
else:
correct_answer = title
else: # Hard
# Use a more complex answer
correct_answer = description if description else title
return {"question": question, "correct_answer": correct_answer, "context": extract}
def generate_mcq(topic: str, difficulty: str) -> Dict:
"""Generate an enhanced multiple choice question"""
summary_data = fetch_wikipedia_summary(topic)
if not summary_data:
# Try searching for the topic
search_results = search_wikipedia(topic, 3)
if search_results:
# Try the first search result
topic = search_results[0]
summary_data = fetch_wikipedia_summary(topic)
if not summary_data:
return {
"error": "Topic not found on Wikipedia. Try a different topic or check spelling.",
"status": False,
"suggestions": search_results if search_results else [],
}
# Generate question based on difficulty
question_data = generate_question_types(topic, summary_data, difficulty)
# Generate smart distractors
distractors = generate_smart_distractors(
question_data["correct_answer"], topic, question_data["context"]
)
# Create options
options = [question_data["correct_answer"]] + distractors[:3]
random.shuffle(options)
# Create explanation
extract = summary_data.get("extract", "")
explanation = extract[:300] + "..." if len(extract) > 300 else extract
return {
"question": question_data["question"],
"options": options,
"correct_answer": question_data["correct_answer"],
"explanation": explanation,
"topic": summary_data.get("title", topic),
"difficulty": difficulty,
"status": True,
}
def generate_quiz_set(
topic: str, difficulty: str, num_questions: int = 5
) -> List[Dict]:
"""Generate a set of questions for a complete quiz"""
questions = []
used_topics = set()
# Get related topics for variety
related_topics = [topic] + fetch_related_topics(topic, 10)
for i in range(num_questions):
# Try to use different related topics
for related_topic in related_topics:
if related_topic not in used_topics:
question = generate_mcq(related_topic, difficulty)
if question.get("status"):
questions.append(question)
used_topics.add(related_topic)
break
# If we couldn't get enough questions, try the main topic again
if len(questions) <= i:
question = generate_mcq(topic, difficulty)
if question.get("status"):
questions.append(question)
return questions