/fstmerge/examples/eXe/rev3426-3457/right-branch-3457/exe/engine/quiztestidevice.py
Python | 306 lines | 299 code | 0 blank | 7 comment | 0 complexity | 7096130963d77b7819ab32dd561d332a MD5 | raw file
- """
- A QuizTest Idevice is one built up from TestQuestions
- """
- import logging
- from exe.engine.persist import Persistable
- from exe.engine.idevice import Idevice
- from exe.engine.translate import lateTranslate
- from exe.engine.field import TextAreaField
- import re
- log = logging.getLogger(__name__)
- class AnswerOption(Persistable):
- """
- A TestQuestion is built up of question and AnswerOptions. Each
- answerOption can be rendered as an XHTML element
- """
- def __init__(self, question, idevice, answer="", isCorrect=False):
- """
- Initialize
- """
- self.question = question
- self.idevice = idevice
- self.answerTextArea = TextAreaField(x_(u'Option'),
- self.question._optionInstruc,
- answer)
- self.answerTextArea.idevice = idevice
- self.isCorrect = isCorrect
- def getResourcesField(self, this_resource):
- """
- implement the specific resource finding mechanism for this iDevice:
- """
- if hasattr(self, 'answerTextArea')\
- and hasattr(self.answerTextArea, 'images'):
- for this_image in self.answerTextArea.images:
- if hasattr(this_image, '_imageResource') \
- and this_resource == this_image._imageResource:
- return self.answerTextArea
- return None
- def getRichTextFields(self):
- """
- Like getResourcesField(), a general helper to allow nodes to search
- through all of their fields without having to know the specifics of each
- iDevice type.
- """
- fields_list = []
- if hasattr(self, 'answerTextArea'):
- fields_list.append(self.answerTextArea)
- return fields_list
- def upgrade_setIdevice(self, idevice, question):
- """
- While some of this might typically be done in an automatic upgrade
- method called from in increased persistence version, the problem
- with that approach is that the idevice was not previously stored,
- and cannot easily be gotten at that stage of operation.
- Rather than making such an upgrade method more messy than necessary,
- this method allows the parent TestQuestion to merely set
- itself on each of its AnswerOptions during its own upgrade.
- Helps upgrade to somewhere before version 0.25 (post-v0.24),
- taking the old unicode string fields,
- and converting them into a image-enabled TextAreaFields:
- """
- self.idevice = idevice
- self.question = question
- self.answerTextArea = TextAreaField(x_(u'Option'),
- self.question._optionInstruc,
- self.answer)
- self.answerTextArea.idevice = self.idevice
- class TestQuestion(Persistable):
- """
- A TestQuestion is built up of question and AnswerOptions.
- """
- persistenceVersion = 3
- def __init__(self, idevice, question=""):
- """
- Initialize
- """
- self.idevice = idevice
- self.options = []
- self.correctAns = -2
- self.userAns = -1
- self._questionInstruc = x_(u"""Enter the question stem.
- The quest should be clear and unambiguous. Avoid negative premises
- as these can tend to be ambiguous.""")
- self._optionInstruc = x_(u"""Enter an answer option. Provide
- a range of plausible distractors (usually 3-4) as well as the correct answer.
- Click on the <Add another option> button to add another answer.""")
- self._correctAnswerInstruc = x_(u"""To indicate the correct answer,
- click the radio button next to the correct option.""")
- self.questionTextArea = TextAreaField(x_(u'Question:'),
- self._questionInstruc, u'')
- self.questionTextArea.idevice = self.idevice
- self.addOption()
- questionInstruc = lateTranslate('questionInstruc')
- optionInstruc = lateTranslate('optionInstruc')
- correctAnswerInstruc = lateTranslate('correctAnswerInstruc')
- def addOption(self):
- """
- Add a new option to this question.
- """
- self.options.append(AnswerOption(self, self.idevice))
- def getResourcesField(self, this_resource):
- """
- implement the specific resource finding mechanism for this iDevice:
- """
- if hasattr(self, 'questionTextArea')\
- and hasattr(self.questionTextArea, 'images'):
- for this_image in self.questionTextArea.images:
- if hasattr(this_image, '_imageResource') \
- and this_resource == this_image._imageResource:
- return self.questionTextArea
- for this_option in self.options:
- this_field = this_option.getResourcesField(this_resource)
- if this_field is not None:
- return this_field
- return None
- def getRichTextFields(self):
- """
- Like getResourcesField(), a general helper to allow nodes to search
- through all of their fields without having to know the specifics of each
- iDevice type.
- """
- fields_list = []
- if hasattr(self, 'questionTextArea'):
- fields_list.append(self.questionTextArea)
- for this_option in self.options:
- fields_list.extend(this_option.getRichTextFields())
- return fields_list
- def upgradeToVersion1(self):
- """
- Upgrades to v 0.13
- """
- self._optionInstruc = x_(u"""Enter an answer option. Provide
- a range of plausible distractors (usually 3-4) as well as the correct answer.
- Click on the <Add another option> button to add another answer.""")
- def upgradeToVersion2(self):
- """
- Upgrades to v 0.13
- """
- self._questionInstruc= x_(u"""Enter the question stem.
- The quest should be clear and unambiguous. Avoid negative premises
- as these can tend to be ambiguous.""")
- def upgradeToVersion3(self):
- """
- Upgrades to v 0.13
- """
- self._correctAnswerInstruc = x_(u"""To indicate the correct answer,
- click the radio button next to the correct option.""")
- def upgrade_setIdevice(self, idevice):
- """
- While some of this might typically be done in an automatic upgrade
- method called from in increased persistence version, the problem
- with that approach is that the idevice was not previously stored,
- and cannot easily be gotten at that stage of operation.
- Rather than making such an upgrade method more messy than necessary,
- this method allows the parent TestQuestionIdevice to merely set
- itself on each of its TestQuestions during its own upgrade.
- Helps upgrade to somewhere before version 0.25 (post-v0.24),
- taking the old unicode string fields,
- and converting them into a image-enabled TextAreaFields:
- """
- self.idevice = idevice
- self.questionTextArea = TextAreaField(x_(u'Question:'),
- self._questionInstruc,
- self.question)
- self.questionTextArea.idevice = self.idevice
- for option in self.options:
- option.upgrade_setIdevice(self.idevice, self)
- class QuizTestIdevice(Idevice):
- """
- A QuizTestIdevice Idevice is one built up from question and options
- """
- persistenceVersion = 8
- def __init__(self):
- """
- Initialize
- """
- Idevice.__init__(self,
- x_(u"SCORM Quiz"),
- x_(u"University of Auckland"),
- x_(u"""Unlike the MCQ the SCORM quiz is used to test
- the learners knowledge on a topic without providing the learner with feedback
- to the correct answer. The quiz will often be given once the learner has had
- time to learn and practice using the information or skill.
- """), u"", "question")
- self.isQuiz = True
- self.emphasis = Idevice.SomeEmphasis
- self.score = -1
- self.isAnswered = True
- self.passRate = "50"
- self.questions = []
- self.addQuestion()
- self.systemResources += ["common.js", "libot_drag.js"]
- def addQuestion(self):
- """
- Add a new question to this iDevice.
- """
- self.questions.append(TestQuestion(self))
- def getResourcesField(self, this_resource):
- """
- implement the specific resource finding mechanism for this iDevice:
- """
- for this_question in self.questions:
- this_field = this_question.getResourcesField(this_resource)
- if this_field is not None:
- return this_field
- return None
- def getRichTextFields(self):
- """
- Like getResourcesField(), a general helper to allow nodes to search
- through all of their fields without having to know the specifics of each
- iDevice type.
- """
- fields_list = []
- for this_question in self.questions:
- fields_list.extend(this_question.getRichTextFields())
- return fields_list
- def burstHTML(self, i):
- """
- takes a BeautifulSoup fragment (i) and bursts its contents to
- import this idevice from a CommonCartridge export
- """
- title = i.find(name='span', attrs={'class' : 'iDeviceTitle' })
- self.title = title.renderContents().decode('utf-8')
- inner = i.find(name='div', attrs={'class' : 'iDevice_inner' })
- passrate = inner.find(name='div', attrs={'class' : 'passrate' })
- self.passRate = passrate.attrMap['value'].decode('utf-8')
- sc_questions = inner.findAll(name='div', attrs={'class' : 'question'})
- if len(sc_questions) < 1:
- del self.questions[0]
- for question_num in range(len(sc_questions)):
- if question_num > 0:
- self.addQuestion()
- question = sc_questions[question_num]
- questions = question.findAll(name='div', attrs={'class' : 'block',
- 'id' : re.compile('^taquestion') })
- if len(questions) == 1:
- inner_question = questions[0]
- self.questions[question_num].questionTextArea.content_wo_resourcePaths \
- = inner_question.renderContents().decode('utf-8')
- self.questions[question_num].questionTextArea.content_w_resourcePaths \
- = self.questions[question_num].questionTextArea.MassageResourceDirsIntoContent( \
- self.questions[question_num].questionTextArea.content_wo_resourcePaths)
- self.questions[question_num].questionTextArea.content \
- = self.questions[question_num].questionTextArea.content_w_resourcePaths
- options = question.findAll(name='div', attrs={'class' : 'block',
- 'id' : re.compile('^taoptionAnswer') })
- answers = question.findAll(name='input', attrs={'type' : 'radio'})
- if len(options) < 1:
- del self.questions[question_num].options[0]
- for option_loop in range(0, len(options)):
- if option_loop >= 1:
- self.questions[question_num].addOption()
- self.questions[question_num].options[option_loop].answerTextArea.content_wo_resourcePaths \
- = options[option_loop].renderContents().decode('utf-8')
- self.questions[question_num].options[option_loop].answerTextArea.content_w_resourcePaths \
- = self.questions[question_num].options[option_loop].answerTextArea.MassageResourceDirsIntoContent( \
- self.questions[question_num].options[option_loop].answerTextArea.content_wo_resourcePaths)
- self.questions[question_num].options[option_loop].answerTextArea.content \
- = self.questions[question_num].options[option_loop].answerTextArea.content_w_resourcePaths
- this_answer = answers[option_loop].attrMap['value']
- if this_answer == "0":
- self.questions[question_num].options[option_loop].isCorrect\
- = True
- self.questions[question_num].correctAns = option_loop
- def upgradeToVersion2(self):
- """
- Upgrades the node from 1 (v0.5) to 2 (v0.6).
- Old packages will loose their icons, but they will load.
- """
- log.debug(u"Upgrading iDevice")
- self.emphasis = Idevice.SomeEmphasis
- def upgradeToVersion3(self):
- """
- Upgrades the node from 1 (v0.6) to 2 (v0.7).
- Change icon from 'multichoice' to 'question'
- """
- log.debug(u"Upgrading iDevice icon")
- self.icon = "question"
- def upgradeToVersion4(self):
- """
- Upgrades v0.6 to v0.7.
- """
- self.lastIdevice = False
- def upgradeToVersion5(self):
- """
- Upgrades to exe v0.10
- """
- self._upgradeIdeviceToVersion1()
- def upgradeToVersion6(self):
- """
- Upgrades to v0.12
- """
- self._upgradeIdeviceToVersion2()
- self.systemResources += ["common.js", "libot_drag.js"]
- def upgradeToVersion7(self):
- """
- Upgrades to v0.14
- """
- self.isQuiz = True
- def upgradeToVersion8(self):
- """
- Upgrades to somewhere before version 0.25 (post-v0.24)
- Taking the TestQuestions' old unicode string fields,
- and converting them into a image-enabled TextAreaFields:
- """
- for question in self.questions:
- question.upgrade_setIdevice(self)