Commit 9f9c3fafd7f8bbafd569b126a81969f241f5643b

Authored by Miguel Barão
1 parent 93c4dec9
Exists in master and in 1 other branch dev

minor refactor of questions.py

Showing 1 changed file with 56 additions and 86 deletions   Show diff stats
perguntations/questions.py
... ... @@ -32,44 +32,6 @@ QDict = NewType('QDict', Dict[str, Any])
32 32 class QuestionException(Exception):
33 33 '''Exceptions raised in this module'''
34 34  
35   -# FIXME if this works, use it below
36   -def QuestionFrom(question: dict):
37   - types = {
38   - 'radio': QuestionRadio,
39   - 'checkbox': QuestionCheckbox,
40   - 'text': QuestionText,
41   - 'text-regex': QuestionTextRegex,
42   - 'numeric-interval': QuestionNumericInterval,
43   - 'textarea': QuestionTextArea,
44   - # 'code': QuestionCode,
45   - # -- informative panels --
46   - 'information': QuestionInformation,
47   - 'success': QuestionInformation,
48   - 'warning': QuestionInformation,
49   - 'alert': QuestionInformation,
50   - }
51   -
52   - # Get class for this question type
53   - try:
54   - qclass = types[question['type']]
55   - except KeyError:
56   - logger.error('Invalid type "%s" in "%s"',
57   - question['type'], question['ref'])
58   - raise
59   -
60   - # Finally create an instance of Question()
61   - try:
62   - qinstance = qclass(QDict(question))
63   - except QuestionException:
64   - logger.error('Error generating question "%s". See "%s/%s"',
65   - question['ref'],
66   - question['path'],
67   - question['filename'])
68   - raise
69   -
70   - return qinstance
71   -
72   -
73 35  
74 36 # ============================================================================
75 37 # Questions derived from Question are already instantiated and ready to be
... ... @@ -769,6 +731,48 @@ class QuestionInformation(Question):
769 731 super().correct()
770 732 self['grade'] = 1.0 # always "correct" but points should be zero!
771 733  
  734 +
  735 +
  736 +
  737 +# ============================================================================
  738 +def question_from(qdict: dict):
  739 + '''
  740 + Converts a question specified in a dict into an instance of Question()
  741 + '''
  742 + types = {
  743 + 'radio': QuestionRadio,
  744 + 'checkbox': QuestionCheckbox,
  745 + 'text': QuestionText,
  746 + 'text-regex': QuestionTextRegex,
  747 + 'numeric-interval': QuestionNumericInterval,
  748 + 'textarea': QuestionTextArea,
  749 + # 'code': QuestionCode,
  750 + # -- informative panels --
  751 + 'information': QuestionInformation,
  752 + 'success': QuestionInformation,
  753 + 'warning': QuestionInformation,
  754 + 'alert': QuestionInformation,
  755 + }
  756 +
  757 + # Get class for this question type
  758 + try:
  759 + qclass = types[qdict['type']]
  760 + except KeyError:
  761 + logger.error('Invalid type "%s" in "%s"',
  762 + qdict['type'], qdict['ref'])
  763 + raise
  764 +
  765 + # Create an instance of Question() of appropriate type
  766 + try:
  767 + qinstance = qclass(QDict(qdict))
  768 + except QuestionException:
  769 + logger.error('Error generating "%s" in %s/%s',
  770 + qdict['ref'], qdict['path'], qdict['filename'])
  771 + raise
  772 +
  773 + return qinstance
  774 +
  775 +
772 776 # ============================================================================
773 777 class QFactory():
774 778 '''
... ... @@ -802,25 +806,8 @@ class QFactory():
802 806 grade = question['grade'] # get grade
803 807 '''
804 808  
805   - # Depending on the type of question, a different question class will be
806   - # instantiated. All these classes derive from the base class `Question`.
807   - _types = {
808   - 'radio': QuestionRadio,
809   - 'checkbox': QuestionCheckbox,
810   - 'text': QuestionText,
811   - 'text-regex': QuestionTextRegex,
812   - 'numeric-interval': QuestionNumericInterval,
813   - 'textarea': QuestionTextArea,
814   - # 'code': QuestionCode,
815   - # -- informative panels --
816   - 'information': QuestionInformation,
817   - 'success': QuestionInformation,
818   - 'warning': QuestionInformation,
819   - 'alert': QuestionInformation,
820   - }
821   -
822 809 def __init__(self, qdict: QDict = QDict({})) -> None:
823   - self.question = qdict
  810 + self.qdict = qdict
824 811  
825 812 # ------------------------------------------------------------------------
826 813 async def gen_async(self) -> Question:
... ... @@ -829,44 +816,27 @@ class QFactory():
829 816 which is a descendent of base class Question.
830 817 '''
831 818  
832   - logger.debug('generating %s...', self.question["ref"])
  819 + logger.debug('generating %s...', self.qdict["ref"])
833 820 # Shallow copy so that script generated questions will not replace
834 821 # the original generators
835   - question = self.question.copy()
836   - question['qid'] = str(uuid.uuid4()) # unique for each question
  822 + qdict = self.qdict.copy()
  823 + qdict['qid'] = str(uuid.uuid4()) # unique for each question
837 824  
838 825 # If question is of generator type, an external program will be run
839 826 # which will print a valid question in yaml format to stdout. This
840 827 # output is then yaml parsed into a dictionary `q`.
841   - if question['type'] == 'generator':
842   - logger.debug(' \\_ Running "%s".', question['script'])
843   - question.setdefault('args', [])
844   - question.setdefault('stdin', '')
845   - script = path.join(question['path'], question['script'])
  828 + if qdict['type'] == 'generator':
  829 + logger.debug(' \\_ Running "%s".', qdict['script'])
  830 + qdict.setdefault('args', [])
  831 + qdict.setdefault('stdin', '')
  832 + script = path.join(qdict['path'], qdict['script'])
846 833 out = await run_script_async(script=script,
847   - args=question['args'],
848   - stdin=question['stdin'])
849   - question.update(out)
850   -
851   - # Get class for this question type
852   - try:
853   - qclass = self._types[question['type']]
854   - except KeyError:
855   - logger.error('Invalid type "%s" in "%s"',
856   - question['type'], question['ref'])
857   - raise
  834 + args=qdict['args'],
  835 + stdin=qdict['stdin'])
  836 + qdict.update(out)
858 837  
859   - # Finally create an instance of Question()
860   - try:
861   - qinstance = qclass(QDict(question))
862   - except QuestionException:
863   - logger.error('Error generating question "%s". See "%s/%s"',
864   - question['ref'],
865   - question['path'],
866   - question['filename'])
867   - raise
868   -
869   - return qinstance
  838 + question = question_from(qdict) # returns a Question instance
  839 + return question
870 840  
871 841 # ------------------------------------------------------------------------
872 842 def generate(self) -> Question:
... ...