3 from karmaworld.apps.quizzes.models import Keyword
6 class BaseQuizQuestion(object):
8 def question_type(self):
9 return self.__class__.__name__
12 class MultipleChoiceQuestion(BaseQuizQuestion):
13 def __init__(self, question_text, choices):
14 self.question_text = question_text
15 self.choices = choices
17 def __unicode__(self):
18 return u"Multiple choice: {0}: {1}".format(self.question_text, ", ".join(map(str, self.choices)))
27 class MultipleChoiceOption(object):
28 def __init__(self, text, correct):
30 self.correct = correct
32 def __unicode__(self):
42 class TrueFalseQuestion(BaseQuizQuestion):
43 def __init__(self, question_text, true):
44 self.question_text = question_text
47 def __unicode__(self):
48 return u"True or false: {0}".format(self.question_text)
57 class MatchingQuestion(BaseQuizQuestion):
58 def __init__(self, question_text, left_column, right_column, left_right_mapping):
59 self.question_text = question_text
60 self.left_column = left_column
61 self.right_column = right_column
62 self.left_right_mapping = left_right_mapping
65 return zip(self.left_column, self.right_column)
67 def __unicode__(self):
68 return u"Matching question: {0} / {1}".format(self.left_column, self.right_column)
77 KEYWORD_MULTIPLE_CHOICE = 1
78 DEFINITION_MULTIPLE_CHOICE = 2
79 KEYWORD_DEFINITION_TRUE_FALSE = 3
80 KEYWORD_DEFINITION_MATCHING = 4
81 GENERATED_QUESTION_TYPE = (
82 KEYWORD_MULTIPLE_CHOICE,
83 DEFINITION_MULTIPLE_CHOICE,
84 KEYWORD_DEFINITION_TRUE_FALSE,
85 KEYWORD_DEFINITION_MATCHING,
88 MULTIPLE_CHOICE_CHOICES = 4
91 def _create_keyword_multiple_choice(keyword, keywords):
92 choices = [MultipleChoiceOption(text=keyword.word, correct=True)]
94 for other_keyword in random.sample(keywords.exclude(id=keyword.id), MULTIPLE_CHOICE_CHOICES - 1):
95 choices.append(MultipleChoiceOption(
96 text=other_keyword.word,
99 question_text = u'Pick the keyword to match "{d}"'.format(d=keyword.definition)
101 return MultipleChoiceQuestion(question_text, choices)
104 def _create_definition_multiple_choice(keyword, keywords):
105 choices = [MultipleChoiceOption(text=keyword.definition, correct=True)]
107 for other_keyword in random.sample(keywords.exclude(id=keyword.id), MULTIPLE_CHOICE_CHOICES - 1):
108 choices.append(MultipleChoiceOption(
109 text=other_keyword.definition,
112 question_text = u'Pick the definition to match "{w}"'.format(w=keyword.word)
114 return MultipleChoiceQuestion(question_text, choices)
117 def _create_keyword_definition_true_false(keyword, keywords):
118 true = random.choice((True, False))
121 definition = keyword.definition
123 other_keyword = random.choice(keywords.exclude(id=keyword.id))
124 definition = other_keyword.definition
126 question_text = u'The keyword "{w}" matches the definition "{d}"'. \
127 format(w=keyword.word, d=definition)
129 return TrueFalseQuestion(question_text, true)
132 def _create_keyword_definition_matching(keyword, keywords):
133 question_keywords = [keyword]
134 question_keywords.extend(random.sample(keywords.exclude(id=keyword.id), MULTIPLE_CHOICE_CHOICES - 1))
136 answer_mapping = {k.word: k.definition for k in question_keywords}
137 word_column = [k.word for k in question_keywords]
138 random.shuffle(word_column)
139 definition_column = [k.definition for k in question_keywords]
140 random.shuffle(definition_column)
142 question_text = u'Match the words with their definitions'
144 return MatchingQuestion(question_text, left_column=word_column,
145 right_column=definition_column, left_right_mapping=answer_mapping)
148 def quiz_from_keywords(note):
149 keywords = Keyword.objects.filter(note=note).exclude(word__iexact='').exclude(definition__iexact='')
152 if len(keywords) < 4:
155 for keyword in keywords:
156 if keyword.word and keyword.definition:
157 question_type = random.choice(GENERATED_QUESTION_TYPE)
159 if question_type is KEYWORD_MULTIPLE_CHOICE:
160 questions.append(_create_keyword_multiple_choice(keyword, keywords))
162 elif question_type is DEFINITION_MULTIPLE_CHOICE:
163 questions.append(_create_definition_multiple_choice(keyword, keywords))
165 elif question_type is KEYWORD_DEFINITION_TRUE_FALSE:
166 questions.append(_create_keyword_definition_true_false(keyword, keywords))
168 elif question_type is KEYWORD_DEFINITION_MATCHING:
169 questions.append(_create_keyword_definition_matching(keyword, keywords))