PageRenderTime 51ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/fstmerge/examples/eXe/rev3426-3513/right-branch-3513/exe/engine/clozeidevice.py

https://github.com/RoDaniel/featurehouse
Python | 240 lines | 231 code | 0 blank | 9 comment | 0 complexity | 1041a4c7ac123d70a29d7d5627c9df09 MD5 | raw file
  1. """
  2. Cloze Idevice. Shows a paragraph where the student must fill in the blanks
  3. """
  4. import logging
  5. from exe.engine.idevice import Idevice
  6. from exe.engine.path import Path
  7. from exe.engine.field import ClozeField, TextAreaField
  8. from exe.engine.persist import Persistable
  9. import Image
  10. import re
  11. log = logging.getLogger(__name__)
  12. class ClozeIdevice(Idevice):
  13. """
  14. Holds a paragraph with words missing that the student must fill in
  15. """
  16. persistenceVersion = 4
  17. def __init__(self, parentNode=None):
  18. """
  19. Sets up the idevice title and instructions etc
  20. """
  21. Idevice.__init__(self, x_(u"Cloze Activity"),
  22. x_(u"University of Auckland"),
  23. x_(u"<p>Cloze exercises are texts or "
  24. "sentences where students must fill in "
  25. "missing words. They are often used for the "
  26. "following purposes:</p>"
  27. "<ol>"
  28. "<li>To check knowledge of core course "
  29. "concepts (this could be a pre-check, "
  30. "formative exercise, or summative check).</li>"
  31. "<li>To check reading comprehension.</li>"
  32. "<li>To check vocabulary knowledge.</li>"
  33. "<li>To check word formation and/or grammatical "
  34. "competence. </li></ol>"),
  35. x_(u"<dl>"
  36. " <dt>If your goal is to test understanding "
  37. "of core concepts or reading comprehension"
  38. " </dt>"
  39. " <dd>"
  40. " <p>"
  41. " Write a summary of the concept or reading long "
  42. " enough to adequately test the target's "
  43. "knowledge, but short enough not to "
  44. "induce fatigue. Less than one typed page is "
  45. "probably adequate, but probably "
  46. "considerably less for young students or "
  47. "beginners."
  48. " </p>"
  49. " <p>"
  50. "Select words in the text that"
  51. "are key to understanding the concepts. These"
  52. "will probably be verbs, nouns, and key adverbs."
  53. "Choose alternatives with one clear answer."
  54. " </p>"
  55. " </dd>"
  56. " <dt>"
  57. "If your goal is to test vocabulary knowledge"
  58. " </dt>"
  59. " <dd>"
  60. "<p>Write a text using the target vocabulary. This "
  61. "text should be coherent and cohesive, and be of "
  62. "an appropriate length. Highlight the target "
  63. "words in the text. Choose alternatives with one "
  64. "clear answer.</p>"
  65. " </dd>"
  66. " <dt>"
  67. "If your goal is to test word "
  68. "formation/grammar:"
  69. " </dt>"
  70. " <dd>"
  71. " <p>"
  72. "Write a text using the "
  73. "target forms. This text should be coherent and "
  74. "cohesive, and be of an appropriate length. "
  75. "Remember that the goal is not vocabulary "
  76. "knowledge, so the core meanings of the stem "
  77. "words should be well known to the students."
  78. " </p>"
  79. " <p>"
  80. "Highlight the target words in the text. Provide "
  81. "alternatives with the same word stem, but "
  82. "different affixes. It is a good idea to get a "
  83. "colleague to test the test/exercise to make "
  84. "sure there are no surprises!"
  85. " </p>"
  86. " </dd>"
  87. "</dl>"),
  88. u"question",
  89. parentNode)
  90. self.instructionsForLearners = TextAreaField(
  91. x_(u'Instructions'),
  92. x_(u"""Provide instruction on how the cloze activity should be
  93. completed. Default text will be entered if there are no changes to this field.
  94. """),
  95. x_(u'Read the paragraph below and '
  96. 'fill in the missing words.'))
  97. self.instructionsForLearners.idevice = self
  98. self._content = ClozeField(x_(u'Cloze'),
  99. x_(u"""<p>Enter the text for the cloze activity in to the cloze field
  100. by either pasting text from another source or by typing text directly into the
  101. field.</p><p> To select words to hide, double click on the word to select it and
  102. click on the Hide/Show Word button below.</p>"""))
  103. self._content.idevice = self
  104. self.feedback = TextAreaField(x_(u'Feedback'),
  105. x_(u'Enter any feedback you wish to provide the learner '
  106. 'with-in the feedback field. This field can be left blank.'))
  107. self.feedback.idevice = self
  108. self.emphasis = Idevice.SomeEmphasis
  109. self.systemResources += ["common.js"]
  110. self.isCloze = True
  111. content = property(lambda self: self._content,
  112. doc="Read only, use 'self.content.encodedContent = x' "
  113. "instead")
  114. def getResourcesField(self, this_resource):
  115. """
  116. implement the specific resource finding mechanism for this iDevice:
  117. """
  118. if hasattr(self, '_content') and hasattr(self._content, 'images'):
  119. for this_image in self._content.images:
  120. if hasattr(this_image, '_imageResource') \
  121. and this_resource == this_image._imageResource:
  122. return self._content
  123. if hasattr(self, 'instructionsForLearners')\
  124. and hasattr(self.instructionsForLearners, 'images'):
  125. for this_image in self.instructionsForLearners.images:
  126. if hasattr(this_image, '_imageResource') \
  127. and this_resource == this_image._imageResource:
  128. return self.instructionsForLearners
  129. if hasattr(self, 'feedback') and hasattr(self.feedback, 'images'):
  130. for this_image in self.feedback.images:
  131. if hasattr(this_image, '_imageResource') \
  132. and this_resource == this_image._imageResource:
  133. return self.feedback
  134. return None
  135. def getRichTextFields(self):
  136. """
  137. Like getResourcesField(), a general helper to allow nodes to search
  138. through all of their fields without having to know the specifics of each
  139. iDevice type.
  140. """
  141. fields_list = []
  142. if hasattr(self, '_content'):
  143. fields_list.append(self._content)
  144. if hasattr(self, 'instructionsForLearners'):
  145. fields_list.append(self.instructionsForLearners)
  146. if hasattr(self, 'feedback'):
  147. fields_list.append(self.feedback)
  148. return fields_list
  149. def burstHTML(self, i):
  150. """
  151. takes a BeautifulSoup fragment (i) and bursts its contents to
  152. import this idevice from a CommonCartridge export
  153. """
  154. title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
  155. self.title = title.renderContents().decode('utf-8')
  156. inner = i.find(name='div', attrs={'class' : 'iDevice_inner' })
  157. instruct = inner.find(name='div',
  158. attrs={'class' : 'block' , 'style' : 'display:block' })
  159. self.instructionsForLearners.content_wo_resourcePaths = \
  160. instruct.renderContents().decode('utf-8')
  161. self.instructionsForLearners.content_w_resourcePaths = \
  162. self.instructionsForLearners.MassageResourceDirsIntoContent( \
  163. self.instructionsForLearners.content_wo_resourcePaths)
  164. self.instructionsForLearners.content = \
  165. self.instructionsForLearners.content_w_resourcePaths
  166. content = inner.find(name='div', attrs={'id' : re.compile('^cloze') })
  167. rebuilt_contents = ""
  168. for this_content in content.contents:
  169. if not this_content.__str__().startswith('<input'):
  170. if this_content.__str__().startswith('<span'):
  171. answer = ""
  172. code_key = 'X'
  173. code = this_content.renderContents()
  174. code = code.decode('base64')
  175. char_pos = 0
  176. while char_pos < len(code):
  177. this_code_char = "0x" + code[char_pos+2 : char_pos+6]
  178. this_code_ord = int(this_code_char, 16)
  179. letter = chr(ord(code_key)^this_code_ord)
  180. answer += letter
  181. code_key = letter
  182. char_pos += 6
  183. rebuilt_contents += "<U>" + answer + "</U>"
  184. elif not this_content.__str__().startswith('<div'):
  185. rebuilt_contents += this_content.__str__()
  186. self._content.content_wo_resourcePaths = rebuilt_contents
  187. self._content.content_w_resourcePaths = \
  188. self._content.MassageResourceDirsIntoContent( \
  189. self._content.content_wo_resourcePaths)
  190. self._content.content = self._content.content_w_resourcePaths
  191. feedback = inner.find(name='div', attrs={'class' : 'feedback' })
  192. self.feedback.content_wo_resourcePaths = \
  193. feedback.renderContents().decode('utf-8')
  194. self.feedback.content_w_resourcePaths = \
  195. self.feedback.MassageResourceDirsIntoContent( \
  196. self.feedback.content_wo_resourcePaths)
  197. self.feedback.content = self.feedback.content_w_resourcePaths
  198. flag_strict = inner.find(name='input',
  199. attrs={'id' : re.compile('^clozeFlag.*strictMarking$') })
  200. if flag_strict.attrMap['value']=="true":
  201. self._content.strictMarking = True
  202. flag_caps = inner.find(name='input',
  203. attrs={'id' : re.compile('^clozeFlag.*checkCaps$') })
  204. if flag_caps.attrMap['value']=="true":
  205. self._content.checkCaps = True
  206. flag_instant = inner.find(name='input',
  207. attrs={'id' : re.compile('^clozeFlag.*instantMarking$') })
  208. if flag_instant.attrMap['value']=="true":
  209. self._content.instantMarking = True
  210. def upgradeToVersion1(self):
  211. """
  212. Upgrades exe to v0.10
  213. """
  214. self._upgradeIdeviceToVersion1()
  215. self.instructionsForLearners = TextAreaField(
  216. x_(u'Instructions For Learners'),
  217. x_(u'Put instructions for learners here'),
  218. x_(u'Read the paragraph below and '
  219. 'fill in the missing words'))
  220. self.instructionsForLearners.idevice = self
  221. self.feedback = TextAreaField(x_(u'Feedback'))
  222. self.feedback.idevice = self
  223. def upgradeToVersion2(self):
  224. """
  225. Upgrades exe to v0.11
  226. """
  227. self.content.autoCompletion = True
  228. self.content.autoCompletionInstruc = _(u"Allow auto completion when "
  229. u"user filling the gaps.")
  230. def upgradeToVersion3(self):
  231. """
  232. Upgrades to v0.12
  233. """
  234. self._upgradeIdeviceToVersion2()
  235. self.systemResources += ["common.js"]
  236. def upgradeToVersion4(self):
  237. """
  238. Upgrades to v0.20.3
  239. """
  240. self.isCloze = True