Commit 9f9c3fafd7f8bbafd569b126a81969f241f5643b
1 parent
93c4dec9
Exists in
master
and in
1 other branch
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,44 +32,6 @@ QDict = NewType('QDict', Dict[str, Any]) | ||
32 | class QuestionException(Exception): | 32 | class QuestionException(Exception): |
33 | '''Exceptions raised in this module''' | 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 | # Questions derived from Question are already instantiated and ready to be | 37 | # Questions derived from Question are already instantiated and ready to be |
@@ -769,6 +731,48 @@ class QuestionInformation(Question): | @@ -769,6 +731,48 @@ class QuestionInformation(Question): | ||
769 | super().correct() | 731 | super().correct() |
770 | self['grade'] = 1.0 # always "correct" but points should be zero! | 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 | class QFactory(): | 777 | class QFactory(): |
774 | ''' | 778 | ''' |
@@ -802,25 +806,8 @@ class QFactory(): | @@ -802,25 +806,8 @@ class QFactory(): | ||
802 | grade = question['grade'] # get grade | 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 | def __init__(self, qdict: QDict = QDict({})) -> None: | 809 | def __init__(self, qdict: QDict = QDict({})) -> None: |
823 | - self.question = qdict | 810 | + self.qdict = qdict |
824 | 811 | ||
825 | # ------------------------------------------------------------------------ | 812 | # ------------------------------------------------------------------------ |
826 | async def gen_async(self) -> Question: | 813 | async def gen_async(self) -> Question: |
@@ -829,44 +816,27 @@ class QFactory(): | @@ -829,44 +816,27 @@ class QFactory(): | ||
829 | which is a descendent of base class Question. | 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 | # Shallow copy so that script generated questions will not replace | 820 | # Shallow copy so that script generated questions will not replace |
834 | # the original generators | 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 | # If question is of generator type, an external program will be run | 825 | # If question is of generator type, an external program will be run |
839 | # which will print a valid question in yaml format to stdout. This | 826 | # which will print a valid question in yaml format to stdout. This |
840 | # output is then yaml parsed into a dictionary `q`. | 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 | out = await run_script_async(script=script, | 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 | def generate(self) -> Question: | 842 | def generate(self) -> Question: |