Spaces:
Sleeping
Sleeping
File size: 6,013 Bytes
5775a1b |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# 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
|