# 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