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 | 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: | ... | ... |