PageRenderTime 27ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/fstmerge/examples/eXe/rev3426-3457/right-branch-3457/exe/engine/quiztestidevice.py

https://github.com/RoDaniel/featurehouse
Python | 306 lines | 299 code | 0 blank | 7 comment | 0 complexity | 7096130963d77b7819ab32dd561d332a MD5 | raw file
  1. """
  2. A QuizTest Idevice is one built up from TestQuestions
  3. """
  4. import logging
  5. from exe.engine.persist import Persistable
  6. from exe.engine.idevice import Idevice
  7. from exe.engine.translate import lateTranslate
  8. from exe.engine.field import TextAreaField
  9. import re
  10. log = logging.getLogger(__name__)
  11. class AnswerOption(Persistable):
  12. """
  13. A TestQuestion is built up of question and AnswerOptions. Each
  14. answerOption can be rendered as an XHTML element
  15. """
  16. def __init__(self, question, idevice, answer="", isCorrect=False):
  17. """
  18. Initialize
  19. """
  20. self.question = question
  21. self.idevice = idevice
  22. self.answerTextArea = TextAreaField(x_(u'Option'),
  23. self.question._optionInstruc,
  24. answer)
  25. self.answerTextArea.idevice = idevice
  26. self.isCorrect = isCorrect
  27. def getResourcesField(self, this_resource):
  28. """
  29. implement the specific resource finding mechanism for this iDevice:
  30. """
  31. if hasattr(self, 'answerTextArea')\
  32. and hasattr(self.answerTextArea, 'images'):
  33. for this_image in self.answerTextArea.images:
  34. if hasattr(this_image, '_imageResource') \
  35. and this_resource == this_image._imageResource:
  36. return self.answerTextArea
  37. return None
  38. def getRichTextFields(self):
  39. """
  40. Like getResourcesField(), a general helper to allow nodes to search
  41. through all of their fields without having to know the specifics of each
  42. iDevice type.
  43. """
  44. fields_list = []
  45. if hasattr(self, 'answerTextArea'):
  46. fields_list.append(self.answerTextArea)
  47. return fields_list
  48. def upgrade_setIdevice(self, idevice, question):
  49. """
  50. While some of this might typically be done in an automatic upgrade
  51. method called from in increased persistence version, the problem
  52. with that approach is that the idevice was not previously stored,
  53. and cannot easily be gotten at that stage of operation.
  54. Rather than making such an upgrade method more messy than necessary,
  55. this method allows the parent TestQuestion to merely set
  56. itself on each of its AnswerOptions during its own upgrade.
  57. Helps upgrade to somewhere before version 0.25 (post-v0.24),
  58. taking the old unicode string fields,
  59. and converting them into a image-enabled TextAreaFields:
  60. """
  61. self.idevice = idevice
  62. self.question = question
  63. self.answerTextArea = TextAreaField(x_(u'Option'),
  64. self.question._optionInstruc,
  65. self.answer)
  66. self.answerTextArea.idevice = self.idevice
  67. class TestQuestion(Persistable):
  68. """
  69. A TestQuestion is built up of question and AnswerOptions.
  70. """
  71. persistenceVersion = 3
  72. def __init__(self, idevice, question=""):
  73. """
  74. Initialize
  75. """
  76. self.idevice = idevice
  77. self.options = []
  78. self.correctAns = -2
  79. self.userAns = -1
  80. self._questionInstruc = x_(u"""Enter the question stem.
  81. The quest should be clear and unambiguous. Avoid negative premises
  82. as these can tend to be ambiguous.""")
  83. self._optionInstruc = x_(u"""Enter an answer option. Provide
  84. a range of plausible distractors (usually 3-4) as well as the correct answer.
  85. Click on the <Add another option> button to add another answer.""")
  86. self._correctAnswerInstruc = x_(u"""To indicate the correct answer,
  87. click the radio button next to the correct option.""")
  88. self.questionTextArea = TextAreaField(x_(u'Question:'),
  89. self._questionInstruc, u'')
  90. self.questionTextArea.idevice = self.idevice
  91. self.addOption()
  92. questionInstruc = lateTranslate('questionInstruc')
  93. optionInstruc = lateTranslate('optionInstruc')
  94. correctAnswerInstruc = lateTranslate('correctAnswerInstruc')
  95. def addOption(self):
  96. """
  97. Add a new option to this question.
  98. """
  99. self.options.append(AnswerOption(self, self.idevice))
  100. def getResourcesField(self, this_resource):
  101. """
  102. implement the specific resource finding mechanism for this iDevice:
  103. """
  104. if hasattr(self, 'questionTextArea')\
  105. and hasattr(self.questionTextArea, 'images'):
  106. for this_image in self.questionTextArea.images:
  107. if hasattr(this_image, '_imageResource') \
  108. and this_resource == this_image._imageResource:
  109. return self.questionTextArea
  110. for this_option in self.options:
  111. this_field = this_option.getResourcesField(this_resource)
  112. if this_field is not None:
  113. return this_field
  114. return None
  115. def getRichTextFields(self):
  116. """
  117. Like getResourcesField(), a general helper to allow nodes to search
  118. through all of their fields without having to know the specifics of each
  119. iDevice type.
  120. """
  121. fields_list = []
  122. if hasattr(self, 'questionTextArea'):
  123. fields_list.append(self.questionTextArea)
  124. for this_option in self.options:
  125. fields_list.extend(this_option.getRichTextFields())
  126. return fields_list
  127. def upgradeToVersion1(self):
  128. """
  129. Upgrades to v 0.13
  130. """
  131. self._optionInstruc = x_(u"""Enter an answer option. Provide
  132. a range of plausible distractors (usually 3-4) as well as the correct answer.
  133. Click on the <Add another option> button to add another answer.""")
  134. def upgradeToVersion2(self):
  135. """
  136. Upgrades to v 0.13
  137. """
  138. self._questionInstruc= x_(u"""Enter the question stem.
  139. The quest should be clear and unambiguous. Avoid negative premises
  140. as these can tend to be ambiguous.""")
  141. def upgradeToVersion3(self):
  142. """
  143. Upgrades to v 0.13
  144. """
  145. self._correctAnswerInstruc = x_(u"""To indicate the correct answer,
  146. click the radio button next to the correct option.""")
  147. def upgrade_setIdevice(self, idevice):
  148. """
  149. While some of this might typically be done in an automatic upgrade
  150. method called from in increased persistence version, the problem
  151. with that approach is that the idevice was not previously stored,
  152. and cannot easily be gotten at that stage of operation.
  153. Rather than making such an upgrade method more messy than necessary,
  154. this method allows the parent TestQuestionIdevice to merely set
  155. itself on each of its TestQuestions during its own upgrade.
  156. Helps upgrade to somewhere before version 0.25 (post-v0.24),
  157. taking the old unicode string fields,
  158. and converting them into a image-enabled TextAreaFields:
  159. """
  160. self.idevice = idevice
  161. self.questionTextArea = TextAreaField(x_(u'Question:'),
  162. self._questionInstruc,
  163. self.question)
  164. self.questionTextArea.idevice = self.idevice
  165. for option in self.options:
  166. option.upgrade_setIdevice(self.idevice, self)
  167. class QuizTestIdevice(Idevice):
  168. """
  169. A QuizTestIdevice Idevice is one built up from question and options
  170. """
  171. persistenceVersion = 8
  172. def __init__(self):
  173. """
  174. Initialize
  175. """
  176. Idevice.__init__(self,
  177. x_(u"SCORM Quiz"),
  178. x_(u"University of Auckland"),
  179. x_(u"""Unlike the MCQ the SCORM quiz is used to test
  180. the learners knowledge on a topic without providing the learner with feedback
  181. to the correct answer. The quiz will often be given once the learner has had
  182. time to learn and practice using the information or skill.
  183. """), u"", "question")
  184. self.isQuiz = True
  185. self.emphasis = Idevice.SomeEmphasis
  186. self.score = -1
  187. self.isAnswered = True
  188. self.passRate = "50"
  189. self.questions = []
  190. self.addQuestion()
  191. self.systemResources += ["common.js", "libot_drag.js"]
  192. def addQuestion(self):
  193. """
  194. Add a new question to this iDevice.
  195. """
  196. self.questions.append(TestQuestion(self))
  197. def getResourcesField(self, this_resource):
  198. """
  199. implement the specific resource finding mechanism for this iDevice:
  200. """
  201. for this_question in self.questions:
  202. this_field = this_question.getResourcesField(this_resource)
  203. if this_field is not None:
  204. return this_field
  205. return None
  206. def getRichTextFields(self):
  207. """
  208. Like getResourcesField(), a general helper to allow nodes to search
  209. through all of their fields without having to know the specifics of each
  210. iDevice type.
  211. """
  212. fields_list = []
  213. for this_question in self.questions:
  214. fields_list.extend(this_question.getRichTextFields())
  215. return fields_list
  216. def burstHTML(self, i):
  217. """
  218. takes a BeautifulSoup fragment (i) and bursts its contents to
  219. import this idevice from a CommonCartridge export
  220. """
  221. title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
  222. self.title = title.renderContents().decode('utf-8')
  223. inner = i.find(name='div', attrs={'class' : 'iDevice_inner' })
  224. passrate = inner.find(name='div', attrs={'class' : 'passrate' })
  225. self.passRate = passrate.attrMap['value'].decode('utf-8')
  226. sc_questions = inner.findAll(name='div', attrs={'class' : 'question'})
  227. if len(sc_questions) < 1:
  228. del self.questions[0]
  229. for question_num in range(len(sc_questions)):
  230. if question_num > 0:
  231. self.addQuestion()
  232. question = sc_questions[question_num]
  233. questions = question.findAll(name='div', attrs={'class' : 'block',
  234. 'id' : re.compile('^taquestion') })
  235. if len(questions) == 1:
  236. inner_question = questions[0]
  237. self.questions[question_num].questionTextArea.content_wo_resourcePaths \
  238. = inner_question.renderContents().decode('utf-8')
  239. self.questions[question_num].questionTextArea.content_w_resourcePaths \
  240. = self.questions[question_num].questionTextArea.MassageResourceDirsIntoContent( \
  241. self.questions[question_num].questionTextArea.content_wo_resourcePaths)
  242. self.questions[question_num].questionTextArea.content \
  243. = self.questions[question_num].questionTextArea.content_w_resourcePaths
  244. options = question.findAll(name='div', attrs={'class' : 'block',
  245. 'id' : re.compile('^taoptionAnswer') })
  246. answers = question.findAll(name='input', attrs={'type' : 'radio'})
  247. if len(options) < 1:
  248. del self.questions[question_num].options[0]
  249. for option_loop in range(0, len(options)):
  250. if option_loop >= 1:
  251. self.questions[question_num].addOption()
  252. self.questions[question_num].options[option_loop].answerTextArea.content_wo_resourcePaths \
  253. = options[option_loop].renderContents().decode('utf-8')
  254. self.questions[question_num].options[option_loop].answerTextArea.content_w_resourcePaths \
  255. = self.questions[question_num].options[option_loop].answerTextArea.MassageResourceDirsIntoContent( \
  256. self.questions[question_num].options[option_loop].answerTextArea.content_wo_resourcePaths)
  257. self.questions[question_num].options[option_loop].answerTextArea.content \
  258. = self.questions[question_num].options[option_loop].answerTextArea.content_w_resourcePaths
  259. this_answer = answers[option_loop].attrMap['value']
  260. if this_answer == "0":
  261. self.questions[question_num].options[option_loop].isCorrect\
  262. = True
  263. self.questions[question_num].correctAns = option_loop
  264. def upgradeToVersion2(self):
  265. """
  266. Upgrades the node from 1 (v0.5) to 2 (v0.6).
  267. Old packages will loose their icons, but they will load.
  268. """
  269. log.debug(u"Upgrading iDevice")
  270. self.emphasis = Idevice.SomeEmphasis
  271. def upgradeToVersion3(self):
  272. """
  273. Upgrades the node from 1 (v0.6) to 2 (v0.7).
  274. Change icon from 'multichoice' to 'question'
  275. """
  276. log.debug(u"Upgrading iDevice icon")
  277. self.icon = "question"
  278. def upgradeToVersion4(self):
  279. """
  280. Upgrades v0.6 to v0.7.
  281. """
  282. self.lastIdevice = False
  283. def upgradeToVersion5(self):
  284. """
  285. Upgrades to exe v0.10
  286. """
  287. self._upgradeIdeviceToVersion1()
  288. def upgradeToVersion6(self):
  289. """
  290. Upgrades to v0.12
  291. """
  292. self._upgradeIdeviceToVersion2()
  293. self.systemResources += ["common.js", "libot_drag.js"]
  294. def upgradeToVersion7(self):
  295. """
  296. Upgrades to v0.14
  297. """
  298. self.isQuiz = True
  299. def upgradeToVersion8(self):
  300. """
  301. Upgrades to somewhere before version 0.25 (post-v0.24)
  302. Taking the TestQuestions' old unicode string fields,
  303. and converting them into a image-enabled TextAreaFields:
  304. """
  305. for question in self.questions:
  306. question.upgrade_setIdevice(self)