From: W. Trevor King Date: Thu, 14 Mar 2013 12:13:08 +0000 (-0400) Subject: question: Move ChoiceQuestion.open_ended to Question.accept_all X-Git-Tag: v0.4~5 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=3fc4be57135e168ae5f53ea8e1784e5aac5ad64c;p=quizzer.git question: Move ChoiceQuestion.open_ended to Question.accept_all Accepting all answers is a more general case of an open ended multiple choice question. It also allows us to ask questions that are difficult or impossible to grade automatically. We just record the student's answer for the grader to look at later. --- diff --git a/quizzer/question.py b/quizzer/question.py index cc4cfff..95d9022 100644 --- a/quizzer/question.py +++ b/quizzer/question.py @@ -34,6 +34,7 @@ class Question (object): 'id', 'prompt', 'answer', + 'accept_all', 'multiline', 'help', 'dependencies', @@ -57,20 +58,26 @@ class Question (object): def __setstate__(self, state): if 'id' not in state: state['id'] = state.get('prompt', None) - if 'multiline' not in state: - state['multiline'] = False if 'dependencies' not in state: state['dependencies'] = [] if 'tags' not in state: state['tags'] = set() else: state['tags'] = set(state['tags']) + for attr in ['accept_all', 'multiline']: + if attr not in state: + state[attr] = False for attr in self._state_attributes: if attr not in state: state[attr] = None self.__dict__.update(state) def check(self, answer): + if self.accept_all: + return (True, None) + return self._check(answer) + + def _check(self, answer): correct = answer == self.answer details = None if not correct: @@ -95,7 +102,7 @@ class NormalizedStringQuestion (Question): def normalize(self, string): return string.strip().lower() - def check(self, answer): + def _check(self, answer): normalized_answer = self.normalize(answer) correct = normalized_answer == self.normalize(self.answer) details = None @@ -108,17 +115,16 @@ class NormalizedStringQuestion (Question): class ChoiceQuestion (Question): _state_attributes = Question._state_attributes + [ 'display_choices', - 'open_ended', ] def __setstate__(self, state): - for key in ['display_choices', 'open_ended']: + for key in ['display_choices']: if key not in state: state[key] = False super(ChoiceQuestion, self).__setstate__(state) - def check(self, answer): - correct = answer in self.answer or self.open_ended + def _check(self, answer): + correct = answer in self.answer details = None if not correct: details = 'answer ({}) is not in list of expected values'.format( @@ -229,7 +235,7 @@ class ScriptQuestion (Question): return (a_status,a_stdout,a_stderr, t_status,t_stdout,t_stderr) - def check(self, answer=None, tempdir=None): + def _check(self, answer=None, tempdir=None): """Compare the user's answer with expected values Arguments are passed through to ._invoke() for calculating the diff --git a/quizzer/ui/cli.py b/quizzer/ui/cli.py index e91a0dd..cbfa16d 100644 --- a/quizzer/ui/cli.py +++ b/quizzer/ui/cli.py @@ -90,7 +90,7 @@ class QuestionCommandLine (_cmd.Cmd): self.question.display_choices): for i,choice in enumerate(self.question.answer): yield '{}) {}'.format(i, choice) - if self.question.open_ended: + if self.question.accept_all: yield 'or fill in something else' return [] diff --git a/quizzer/ui/wsgi.py b/quizzer/ui/wsgi.py index de2c595..91f4321 100644 --- a/quizzer/ui/wsgi.py +++ b/quizzer/ui/wsgi.py @@ -248,9 +248,9 @@ class QuestionApp (WSGI_DataObject): ('{0}
' ).format(answer) for answer in question.answer] - if question.open_ended: + if question.accept_all: choices.extend([ - '', + '', '']) answer_element = '\n'.join(choices) elif question.multiline: @@ -300,8 +300,8 @@ class QuestionApp (WSGI_DataObject): raise HandlerError(404, 'Not Found') from e if (isinstance(question, _question.ChoiceQuestion) and question.display_choices and - question.open_ended and - raw_answer == 'open_ended'): + question.accept_all and + raw_answer == 'answer-other'): answer = print_answer = data.get('answer-other', None) elif question.multiline: answer = raw_answer.splitlines()