[FIX] survey: allow partial scores to answers almost correct.

BEFORE THIS COMMIT / How to reproduce :

Consider a multiple choice question with single answer.

A. 2 points
B. 1 point
C. -1 point

Here, the user can only select one answer. He picks A. He only obtains 2/3 points.
This is because the maximum score was computed as the sum of all positive scores
for the question. It does not make sense, as the student can only pick one answer.
Therefore, the formula does not allow giving partial scores (here, answer B, close
to the correct answer) while maintaining correct score percentages.

AFTER THIS COMMIT:

The sum of positive scores is still used as maximum score for multiple choice
with multiple answers, as we want the student to pick all good answers for max score.

However, for multiple choice with single answer, we use the maximum positive score
(or 0, if none) among answers, as it the maximum score one can get while selecting
a single answer.

-> example above : I pick A, I obtain 2 points out of max(2, 1, (0)) = 2
-> I obtain max score for the question. 2/2.

ps: As the sum only uses striclty positive values, the negative points are still
operational and the flow is not changed.

TESTS:

A test test_partial_scores_simple_choice is added to make sure the simple_choice
is repaired and always gives 100% of points if the best answer is picked.

Task-2533836

closes odoo/odoo#77426

X-original-commit: 2cdfb7805564943ccf857e49b41d3b597fd727bb
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Noe Antoine
2021-09-30 10:38:15 +00:00
committed by Thibault Delavallée
parent 73188b0d7a
commit 01ffaea48b
2 changed files with 43 additions and 1 deletions
+3 -1
View File
@@ -63,7 +63,9 @@ class SurveyUserInput(models.Model):
# sum(multi-choice question scores) + sum(simple answer_type scores)
total_possible_score = 0
for question in user_input.predefined_question_ids:
if question.question_type in ['simple_choice', 'multiple_choice']:
if question.question_type == 'simple_choice':
total_possible_score += max([score for score in question.mapped('suggested_answer_ids.answer_score') if score > 0], default=0)
elif question.question_type == 'multiple_choice':
total_possible_score += sum(score for score in question.mapped('suggested_answer_ids.answer_score') if score > 0)
elif question.is_scored_question:
total_possible_score += question.answer_score
+40
View File
@@ -104,6 +104,46 @@ class TestSurveyInternals(common.TestSurveyCommon):
{}
)
def test_partial_scores_simple_choice(self):
"""" Check that if partial scores are given for partially correct answers, in the case of a multiple
choice question with single choice, choosing the answer with max score gives 100% of points. """
partial_scores_survey = self.env['survey.survey'].create({
'title': 'How much do you know about words?',
'scoring_type': 'scoring_with_answers',
'scoring_success_min': 90.0,
})
[a_01, a_02, a_03] = self.env['survey.question.answer'].create([{
'value': 'A thing full of letters.',
'answer_score': 1.0
}, {
'value': 'A unit of language, [...], carrying a meaning.',
'answer_score': 4.0,
'is_correct': True
}, {
'value': '42',
'answer_score': -4.0
}])
q_01 = self.env['survey.question'].create({
'survey_id': partial_scores_survey.id,
'title': 'What is a word?',
'sequence': 1,
'question_type': 'simple_choice',
'suggested_answer_ids': [(6, 0, (a_01 | a_02 | a_03).ids)]
})
user_input = self.env['survey.user_input'].create({'survey_id': partial_scores_survey.id})
self.env['survey.user_input.line'].create({
'user_input_id': user_input.id,
'question_id': q_01.id,
'answer_type': 'suggestion',
'suggested_answer_id': a_02.id
})
# Check that scoring is correct and survey is passed
self.assertEqual(user_input.scoring_percentage, 100)
self.assertTrue(user_input.scoring_success)
@users('survey_manager')
def test_skipped_values(self):
""" Create one question per type of questions.