diff --git a/perguntations/questions.py b/perguntations/questions.py index fc585df..c406607 100644 --- a/perguntations/questions.py +++ b/perguntations/questions.py @@ -32,44 +32,6 @@ QDict = NewType('QDict', Dict[str, Any]) class QuestionException(Exception): '''Exceptions raised in this module''' -# FIXME if this works, use it below -def QuestionFrom(question: dict): - types = { - 'radio': QuestionRadio, - 'checkbox': QuestionCheckbox, - 'text': QuestionText, - 'text-regex': QuestionTextRegex, - 'numeric-interval': QuestionNumericInterval, - 'textarea': QuestionTextArea, - # 'code': QuestionCode, - # -- informative panels -- - 'information': QuestionInformation, - 'success': QuestionInformation, - 'warning': QuestionInformation, - 'alert': QuestionInformation, - } - - # Get class for this question type - try: - qclass = types[question['type']] - except KeyError: - logger.error('Invalid type "%s" in "%s"', - question['type'], question['ref']) - raise - - # Finally create an instance of Question() - try: - qinstance = qclass(QDict(question)) - except QuestionException: - logger.error('Error generating question "%s". See "%s/%s"', - question['ref'], - question['path'], - question['filename']) - raise - - return qinstance - - # ============================================================================ # Questions derived from Question are already instantiated and ready to be @@ -769,6 +731,48 @@ class QuestionInformation(Question): super().correct() self['grade'] = 1.0 # always "correct" but points should be zero! + + + +# ============================================================================ +def question_from(qdict: dict): + ''' + Converts a question specified in a dict into an instance of Question() + ''' + types = { + 'radio': QuestionRadio, + 'checkbox': QuestionCheckbox, + 'text': QuestionText, + 'text-regex': QuestionTextRegex, + 'numeric-interval': QuestionNumericInterval, + 'textarea': QuestionTextArea, + # 'code': QuestionCode, + # -- informative panels -- + 'information': QuestionInformation, + 'success': QuestionInformation, + 'warning': QuestionInformation, + 'alert': QuestionInformation, + } + + # Get class for this question type + try: + qclass = types[qdict['type']] + except KeyError: + logger.error('Invalid type "%s" in "%s"', + qdict['type'], qdict['ref']) + raise + + # Create an instance of Question() of appropriate type + try: + qinstance = qclass(QDict(qdict)) + except QuestionException: + logger.error('Error generating "%s" in %s/%s', + qdict['ref'], qdict['path'], qdict['filename']) + raise + + return qinstance + + # ============================================================================ class QFactory(): ''' @@ -802,25 +806,8 @@ class QFactory(): grade = question['grade'] # get grade ''' - # Depending on the type of question, a different question class will be - # instantiated. All these classes derive from the base class `Question`. - _types = { - 'radio': QuestionRadio, - 'checkbox': QuestionCheckbox, - 'text': QuestionText, - 'text-regex': QuestionTextRegex, - 'numeric-interval': QuestionNumericInterval, - 'textarea': QuestionTextArea, - # 'code': QuestionCode, - # -- informative panels -- - 'information': QuestionInformation, - 'success': QuestionInformation, - 'warning': QuestionInformation, - 'alert': QuestionInformation, - } - def __init__(self, qdict: QDict = QDict({})) -> None: - self.question = qdict + self.qdict = qdict # ------------------------------------------------------------------------ async def gen_async(self) -> Question: @@ -829,44 +816,27 @@ class QFactory(): which is a descendent of base class Question. ''' - logger.debug('generating %s...', self.question["ref"]) + logger.debug('generating %s...', self.qdict["ref"]) # Shallow copy so that script generated questions will not replace # the original generators - question = self.question.copy() - question['qid'] = str(uuid.uuid4()) # unique for each question + qdict = self.qdict.copy() + qdict['qid'] = str(uuid.uuid4()) # unique for each question # If question is of generator type, an external program will be run # which will print a valid question in yaml format to stdout. This # output is then yaml parsed into a dictionary `q`. - if question['type'] == 'generator': - logger.debug(' \\_ Running "%s".', question['script']) - question.setdefault('args', []) - question.setdefault('stdin', '') - script = path.join(question['path'], question['script']) + if qdict['type'] == 'generator': + logger.debug(' \\_ Running "%s".', qdict['script']) + qdict.setdefault('args', []) + qdict.setdefault('stdin', '') + script = path.join(qdict['path'], qdict['script']) out = await run_script_async(script=script, - args=question['args'], - stdin=question['stdin']) - question.update(out) - - # Get class for this question type - try: - qclass = self._types[question['type']] - except KeyError: - logger.error('Invalid type "%s" in "%s"', - question['type'], question['ref']) - raise + args=qdict['args'], + stdin=qdict['stdin']) + qdict.update(out) - # Finally create an instance of Question() - try: - qinstance = qclass(QDict(question)) - except QuestionException: - logger.error('Error generating question "%s". See "%s/%s"', - question['ref'], - question['path'], - question['filename']) - raise - - return qinstance + question = question_from(qdict) # returns a Question instance + return question # ------------------------------------------------------------------------ def generate(self) -> Question: -- libgit2 0.21.2