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
|
'''
quizdata.Question implementation and support functions
'''
class Question(object):
'''
Base question type, abstract(-ish).
Required attributes for 'concrete' implementations:
:Attributes:
answered : boolean
True if the student has selected an answer (if the answer
attribute is valid)
correct : boolean
True if the answer currently selected is correct. (may, in the
future, expand to include a fractional value for partial
credit.) Only valid if answered is True.
answer : marktup_type
The answer selected by the student, or None if no answer
selected. (None is not guaranteed as a value, so use the
answered attribute to determine the validity of this
attribute's value.)
'''
def __init__(self, *args, **kwargs):
'''
Takes all a the data elements for the construction of the question
object.
:Parameters:
title : str or unicode
the title of the question. optional. if not supplied, set
to None.
markup_type : type or factory
the type used to coerce or adapt the raw 'markup' supplied
by the backend to the correct format for use by the
application. if not supplied a default of 'str' is used.
text : str or unicode
the text of the question, assigned the result of
markup_type(text)
tags : list of str or unicode
a list of textual tags used to categorize or filter the
question.
'''
if 'title' in kwargs:
self.title = kwargs['title']
else:
self.title = None
if 'markup_type' in kwargs:
self.markup_type = kwargs['markup_type']
else:
self.markup_type = str
if 'text' in kwargs:
self.text = self.markup_type(kwargs['text'])
else:
raise Exception("Questions must have text!")
if 'tags' in kwargs:
self.tags = kwargs['tags']
else:
self.tags = []
def __repr__(self):
if self.title:
txt = self.title
else:
txt = self.text
return "<%s %r>" % (self.__class__.__name__, txt)
class MultipleChoiceQuestion(Question):
def __init__(self, *args, **kwargs):
super(MultipleChoiceQuestion, self).__init__(*args, **kwargs)
if 'answers' in kwargs:
self.answers = []
for ans in kwargs['answers']:
self.answers.append(self.markup_type(ans))
else:
raise Exception("MultipleChoiceQuestion requires answers!")
if 'correct' in kwargs:
self._correct = self.markup_type(kwargs['correct'])
else:
raise Exception("MultipleChoiceQuestion requires a correct answer!")
self.answered = False
self._answer = None
def answer():
def _fget(self):
return self._answer
def _fset(self, val):
if self.markup_type(val) in self.answers:
self._answer = val
self.answered = True
else:
self.answered = False
self._answer = None
raise ValueError("answer supplied not valid for this question.")
def _fdel(self):
self.answered = False
self._answer = None
return property(_fget, _fset, _fdel)
answer = answer()
@property
def correct(self):
#print "DEBUG: self.answer: ", self.answer
#print "DEBUG: self._correct: ", self._correct
return self.answer == self._correct
class TrueFalseQuestion(MultipleChoiceQuestion):
def __init__(self, *args, **kwargs):
kwargs['answers'] = ['True', 'False']
super(TrueFalseQuestion, self).__init__(*args, **kwargs)
@property
def correct(self):
#print "DEBUG: self.answer: ", self.answer
#print "DEBUG: self._correct: ", self._correct
return self.answer.lower().startswith(self._correct.lower()) #XXX: hack?
#### XXX: The below classes aren't completely implemented. ####
class MissingWordQuestion(MultipleChoiceQuestion):
def __init__(self, *args, **kwargs):
super(MissingWordQuestion, self).__init__(*args, **kwargs)
if 'tail_text' in kwargs:
self.tail_text = self.markup_type(kwargs['tail_text'])
else:
raise Exception("MissingWordQuestion requires a tail_text!")
class ShortAnswerQuestion(Question):
def __init__(self, *args, **kwargs):
super(ShortAnswerQuestion, self).__init__(*args, **kwargs)
if 'correct' in kwargs:
self.correct = self.markup_type(kwargs['correct'])
else:
raise Exception("ShortAnswerQuestion requires a correct answer!")
class NumericalQuestion(Question):
def __init__(self, *args, **kwargs):
super(NumericalQuestion, self).__init__(self, *args, **kwargs)
raise NotImplementedError("Not implemented yet!")
class MatchingQuestion(Question):
def __init__(self, *args, **kwargs):
super(MatchingQuestion, self).__init__(*args, **kwargs)
if 'answers' in kwargs:
ans = []
for a1, a2 in kwargs['answers']:
ans.append((self.markup_type(a1), self.markup_type(a2)))
self.answers = ans
else:
raise Exception("MatchingQuestion must have answers!")
|