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