cd3bb6c1e6c0db193d79acd94413de84ac83b6e9
[oweals/karmaworld.git] / karmaworld / apps / quizzes / create_quiz.py
1 import random
2 from karmaworld.apps.quizzes.models import Keyword
3
4
5 class BaseQuizQuestion(object):
6
7     def question_type(self):
8         return self.__class__.__name__
9
10
11 class MultipleChoiceQuestion(BaseQuizQuestion):
12     def __init__(self, question_text, choices):
13         self.question_text = question_text
14         self.choices = choices
15
16     def __unicode__(self):
17         return u"Multiple choice: {0}: {1}".format(self.question_text, ", ".join(map(str, self.choices)))
18
19     def __str__(self):
20         return unicode(self)
21
22     def __repr__(self):
23         return str(self)
24
25
26 class MultipleChoiceOption(object):
27     def __init__(self, text, correct):
28         self.text = text
29         self.correct = correct
30
31     def __unicode__(self):
32         return self.text
33
34     def __str__(self):
35         return unicode(self)
36
37     def __repr__(self):
38         return str(self)
39
40
41 class TrueFalseQuestion(BaseQuizQuestion):
42     def __init__(self, question_text, true):
43         self.question_text = question_text
44         self.true = true
45
46     def __unicode__(self):
47         return u"True or false: {0}".format(self.question_text)
48
49     def __str__(self):
50         return unicode(self)
51
52     def __repr__(self):
53         return str(self)
54
55
56 KEYWORD_MULTIPLE_CHOICE = 1
57 DEFINITION_MULTIPLE_CHOICE = 2
58 KEYWORD_DEFINITION_TRUE_FALSE = 3
59 GENERATED_QUESTION_TYPE = (
60     KEYWORD_MULTIPLE_CHOICE,
61     DEFINITION_MULTIPLE_CHOICE,
62     KEYWORD_DEFINITION_TRUE_FALSE,
63 )
64
65 MULTIPLE_CHOICE_CHOICES = 4
66
67
68 def _create_keyword_multiple_choice(keyword, keywords):
69     choices = [MultipleChoiceOption(text=keyword.word, correct=True)]
70
71     for other_keyword in random.sample(keywords.exclude(id=keyword.id), MULTIPLE_CHOICE_CHOICES - 1):
72         choices.append(MultipleChoiceOption(
73                        text=other_keyword.word,
74                        correct=False))
75
76     question_text = u'Pick the keyword to match "{d}"'.format(d=keyword.definition)
77
78     return MultipleChoiceQuestion(question_text, choices)
79
80
81 def _create_definition_multiple_choice(keyword, keywords):
82     choices = [MultipleChoiceOption(text=keyword.definition, correct=True)]
83
84     for other_keyword in random.sample(keywords.exclude(id=keyword.id), MULTIPLE_CHOICE_CHOICES - 1):
85         choices.append(MultipleChoiceOption(
86                        text=other_keyword.definition,
87                        correct=False))
88
89     question_text = u'Pick the definition to match "{w}"'.format(w=keyword.word)
90
91     return MultipleChoiceQuestion(question_text, choices)
92
93
94 def _create_keyword_definition_true_false(keyword, keywords):
95     true = random.choice((True, False))
96
97     if true:
98         definition = keyword.definition
99     else:
100         other_keyword = random.choice(keywords.exclude(id=keyword.id))
101         definition = other_keyword.definition
102
103     question_text = u'The keyword "{w}" matches the definition "{d}"'. \
104         format(w=keyword.word, d=definition)
105
106     return TrueFalseQuestion(question_text, true)
107
108
109 def quiz_from_keywords(note):
110     keywords = Keyword.objects.filter(note=note)
111     questions = []
112
113     if len(keywords) < 4:
114         return []
115
116     for keyword in keywords:
117         if keyword.word and keyword.definition:
118             question_type = random.choice(GENERATED_QUESTION_TYPE)
119
120             if question_type is KEYWORD_MULTIPLE_CHOICE:
121                 questions.append(_create_keyword_multiple_choice(keyword, keywords))
122
123             elif question_type is DEFINITION_MULTIPLE_CHOICE:
124                 questions.append(_create_definition_multiple_choice(keyword, keywords))
125
126             elif question_type is KEYWORD_DEFINITION_TRUE_FALSE:
127                 questions.append(_create_keyword_definition_true_false(keyword, keywords))
128
129     return questions
130
131