File size: 6,424 Bytes
15b8ff9
f6df526
 
ddafacb
 
 
f6df526
 
 
ddafacb
 
 
 
 
 
f6df526
ddafacb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f6df526
15b8ff9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ddafacb
15b8ff9
ddafacb
 
f6df526
ddafacb
15b8ff9
ddafacb
 
 
 
 
 
15b8ff9
 
 
 
 
 
 
ddafacb
15b8ff9
ddafacb
f6df526
15b8ff9
ddafacb
 
 
 
 
f6df526
ddafacb
f6df526
ddafacb
f6df526
15b8ff9
 
 
 
 
f6df526
15b8ff9
ddafacb
f6df526
ddafacb
f6df526
 
ddafacb
f6df526
ddafacb
 
15b8ff9
 
 
ddafacb
 
 
 
 
 
 
f6df526
ddafacb
 
 
 
 
 
 
 
 
 
 
 
 
f6df526
 
 
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

import random
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import sent_tokenize, word_tokenize
from transformers import pipeline

class AdvancedMCQGenerator:
    def __init__(self):
        nltk.download('punkt', quiet=True)
        nltk.download('stopwords', quiet=True)
        
        # Initialize NLP models
        self.qa_pipeline = pipeline("question-answering")
        self.stop_words = set(stopwords.words('english'))

    def extract_key_concepts(self, context):
        """Extract key concepts and important phrases"""
        # Tokenize sentences
        sentences = sent_tokenize(context)
        
        # Extract potential key concepts
        key_concepts = []
        for sentence in sentences:
            # Look for sentences with unique, meaningful content
            words = word_tokenize(sentence)
            filtered_words = [word.lower() for word in words if word.isalnum() and word.lower() not in self.stop_words and len(word) > 2]
            # Prioritize sentences with named entities or specific concepts
            if len(filtered_words) > 3:
                key_concepts.append(sentence)
        return key_concepts[:5]  # Return top 5 key concepts

    def generate_intelligent_question(self, concept, context, difficulty):
            if difficulty == 'easy':
                templates = [
                    f"What is {concept}?",
                    f"Describe {concept}.",
                    f"Define {concept}.",
                    f"What do you understand by {concept}?",
                    f"Give a simple explanation of {concept}."
                ]
            elif difficulty == 'hard':
                templates = [
                    f"In what way does {concept} reflect a broader implication?",
                    f"Critically analyze the role of {concept} in the given context.",
                    f"How can {concept} be interpreted in complex scenarios?",
                    f"What deeper insights does {concept} provide?",
                    f"Discuss the nuanced impact of {concept} in this context."
                ]
            else:  # medium
                templates = [
                    f"What is the primary significance of {concept}?",
                    f"How does {concept} impact the broader context?",
                    f"What key role does {concept} play in the narrative?",
                    f"Explain the importance of {concept} in this context.",
                    f"What makes {concept} crucial to understanding the situation?"
                ]
            return random.choice(templates)

    def generate_contextual_distractors(self, correct_answer, context, difficulty):
        """Create semantically related but incorrect distractors"""
        sentences = sent_tokenize(context)
        distractors = []
        potential_distractors = [sent for sent in sentences if correct_answer.lower() not in sent.lower() and len(sent.split()) > 3]
        fallback_distractors = ["A partially related historical context","An alternative interpretation","A peripheral aspect of the main theme"]
        # Generating diverse distractors
        while len(distractors) < 3:
            if potential_distractors:
                distractor = random.choice(potential_distractors)
                potential_distractors.remove(distractor)
                words = word_tokenize(distractor)
                if difficulty == 'easy':
                    phrase = ' '.join([w for w in words if w.lower() not in self.stop_words][:2])
                elif difficulty == 'hard':
                    phrase = ' '.join([w for w in words if w.lower() not in self.stop_words][:5])
                else:  # medium
                    phrase = ' '.join([w for w in words if w.lower() not in self.stop_words][:3])
                distractors.append(phrase.strip())
            else:
                distractors.append(random.choice(fallback_distractors))
        return distractors

    def generate_mcq(self, context, num_questions=3, difficulty='medium'):
        """Generate Multiple Choice Questions"""
        # Validate context
        if not context or len(context.split()) < 30:
            raise ValueError("Context is too short. Provide more detailed text.")
        
        mcq_questions = []
        key_concepts = self.extract_key_concepts(context)
        
        for concept in key_concepts[:num_questions]:
            try:
                question = self.generate_intelligent_question(concept, context, difficulty)
                answer_result = self.qa_pipeline(question=question, context=context)
                correct_answer = answer_result['answer']
                distractors = self.generate_contextual_distractors(correct_answer, context, difficulty)
                all_options = [correct_answer] + distractors
                random.shuffle(all_options)
                correct_index = all_options.index(correct_answer)  # Determine correct option index
                mcq_questions.append({"question": question,"options": all_options,"correct_answer": correct_index})     # Create MCQ
            except Exception as e:
                print(f"Error generating question: {e}")
        return mcq_questions
def main():
    # Create generator instance
    generator = AdvancedMCQGenerator()
    context = input("Enter context text: ")
    num_questions = int(input("How many questions do you want? "))
    difficulty = input("Choose difficulty (easy / medium / hard): ").lower().strip()

    questions = generator.generate_mcq(context, num_questions, difficulty)
    # Display and solve quiz
    print("\n--- Quiz Started ---")
    score = 0
    for i, q in enumerate(questions, 1):
        print(f"\nQuestion {i}: {q['question']}")
        for j, option in enumerate(q['options']):
            print(f"{chr(65+j)}. {option}")
        
        while True:
            user_answer = input("\nYour Answer (A/B/C/D): ").upper()
            if user_answer in ['A', 'B', 'C', 'D']:
                break
            print("Invalid input. Please enter A, B, C, or D.")
        
        user_index = ord(user_answer) - 65
        if user_index == q['correct_answer']:
            print("Correct!")
            score += 1
        else:
            print(f"Incorrect. Correct answer was: {chr(65 + q['correct_answer'])}")
    print(f"\nFinal Score: {score}/{len(questions)}")

if __name__ == "__main__":
    main()