def test_update_from_correctmap(self):
        # Initialize a CorrectMap with some properties
        self.cmap.set(
            answer_id='1_2_1',
            correctness='correct',
            npoints=5,
            msg='Test message',
            hint='Test hint',
            hintmode='always',
            queuestate={
                'key': 'secretstring',
                'time': '20130228100026'
            }
        )

        self.cmap.set_overall_message("Test message")

        # Create a second cmap, then update it to have the same properties
        # as the first cmap
        other_cmap = CorrectMap()
        other_cmap.update(self.cmap)

        # Assert that it has all the same properties
        self.assertEqual(
            other_cmap.get_overall_message(),
            self.cmap.get_overall_message()
        )

        self.assertEqual(
            other_cmap.get_dict(),
            self.cmap.get_dict()
        )
Example #2
0
    def update_score(self, score_msg, queuekey):
        """
        Deliver grading response (e.g. from async code checking) to
            the specific ResponseType that requested grading

        Returns an updated CorrectMap
        """
        cmap = CorrectMap()
        cmap.update(self.correct_map)
        for responder in self.responders.values():
            if hasattr(responder, "update_score"):
                # Each LoncapaResponse will update its specific entries in cmap
                #   cmap is passed by reference
                responder.update_score(score_msg, cmap, queuekey)
        self.correct_map.set_dict(cmap.get_dict())
        return cmap
Example #3
0
    def update_score(self, score_msg, queuekey):
        """
        Deliver grading response (e.g. from async code checking) to
            the specific ResponseType that requested grading

        Returns an updated CorrectMap
        """
        cmap = CorrectMap()
        cmap.update(self.correct_map)
        for responder in self.responders.values():
            if hasattr(responder, 'update_score'):
                # Each LoncapaResponse will update its specific entries in cmap
                #   cmap is passed by reference
                responder.update_score(score_msg, cmap, queuekey)
        self.correct_map.set_dict(cmap.get_dict())
        return cmap
Example #4
0
    def _grade_answers(self, student_answers):
        """
        Internal grading call used for checking new 'student_answers' and also
        rescoring existing student_answers.

        For new student_answers being graded, `student_answers` is a dict of all the
        entries from request.POST, but with the first part of each key removed
        (the string before the first "_").  Thus, for example,
        input_ID123 -> ID123, and input_fromjs_ID123 -> fromjs_ID123.

        For rescoring, `student_answers` is None.

        Calls the Response for each question in this problem, to do the actual grading.
        """
        # old CorrectMap
        oldcmap = self.correct_map

        # start new with empty CorrectMap
        newcmap = CorrectMap()
        # Call each responsetype instance to do actual grading
        for responder in self.responders.values():
            # File objects are passed only if responsetype explicitly allows
            # for file submissions.  But we have no way of knowing if
            # student_answers contains a proper answer or the filename of
            # an earlier submission, so for now skip these entirely.
            # TODO: figure out where to get file submissions when rescoring.
            if 'filesubmission' in responder.allowed_inputfields and student_answers is None:
                _ = self.capa_system.i18n.ugettext
                raise Exception(
                    _(u"Cannot rescore problems with possible file submissions"
                      ))

            # use 'student_answers' only if it is provided, and if it might contain a file
            # submission that would not exist in the persisted "student_answers".
            if 'filesubmission' in responder.allowed_inputfields and student_answers is not None:
                results = responder.evaluate_answers(student_answers, oldcmap)
            else:
                results = responder.evaluate_answers(self.student_answers,
                                                     oldcmap)
            newcmap.update(results)

        self.correct_map = newcmap
        return newcmap
Example #5
0
    def _grade_answers(self, student_answers):
        """
        Internal grading call used for checking new 'student_answers' and also
        rescoring existing student_answers.

        For new student_answers being graded, `student_answers` is a dict of all the
        entries from request.POST, but with the first part of each key removed
        (the string before the first "_").  Thus, for example,
        input_ID123 -> ID123, and input_fromjs_ID123 -> fromjs_ID123.

        For rescoring, `student_answers` is None.

        Calls the Response for each question in this problem, to do the actual grading.
        """
        # old CorrectMap
        oldcmap = self.correct_map

        # start new with empty CorrectMap
        newcmap = CorrectMap()
        # Call each responsetype instance to do actual grading
        for responder in self.responders.values():
            # File objects are passed only if responsetype explicitly allows
            # for file submissions.  But we have no way of knowing if
            # student_answers contains a proper answer or the filename of
            # an earlier submission, so for now skip these entirely.
            # TODO: figure out where to get file submissions when rescoring.
            if "filesubmission" in responder.allowed_inputfields and student_answers is None:
                _ = self.capa_system.i18n.ugettext
                raise Exception(_(u"Cannot rescore problems with possible file submissions"))

            # use 'student_answers' only if it is provided, and if it might contain a file
            # submission that would not exist in the persisted "student_answers".
            if "filesubmission" in responder.allowed_inputfields and student_answers is not None:
                results = responder.evaluate_answers(student_answers, oldcmap)
            else:
                results = responder.evaluate_answers(self.student_answers, oldcmap)
            newcmap.update(results)

        self.correct_map = newcmap
        return newcmap
    def test_update_from_correctmap(self):
        # Initialize a CorrectMap with some properties
        self.cmap.set(answer_id='1_2_1',
                    correctness='correct',
                    npoints=5,
                    msg='Test message',
                    hint='Test hint',
                    hintmode='always',
                    queuestate={'key':'secretstring',
                                'time':'20130228100026'})

        self.cmap.set_overall_message("Test message")

        # Create a second cmap, then update it to have the same properties
        # as the first cmap
        other_cmap = CorrectMap()
        other_cmap.update(self.cmap)
        
        # Assert that it has all the same properties
        self.assertEqual(other_cmap.get_overall_message(),
                        self.cmap.get_overall_message())

        self.assertEqual(other_cmap.get_dict(),
                        self.cmap.get_dict())
Example #7
0
 def _build_correct_map(self, *args):
     cmap = CorrectMap()
     for index, correctness in enumerate(args):
         cmap.update(CorrectMap(answer_id=self._build_question_id(index),
                                correctness=correctness))
     return cmap.cmap
class CorrectMapTest(unittest.TestCase):
    """
    Tests to verify that CorrectMap behaves correctly
    """
    def setUp(self):
        self.cmap = CorrectMap()

    def test_set_input_properties(self):
        # Set the correctmap properties for two inputs
        self.cmap.set(answer_id='1_2_1',
                      correctness='correct',
                      npoints=5,
                      msg='Test message',
                      hint='Test hint',
                      hintmode='always',
                      queuestate={
                          'key': 'secretstring',
                          'time': '20130228100026'
                      })

        self.cmap.set(answer_id='2_2_1',
                      correctness='incorrect',
                      npoints=None,
                      msg=None,
                      hint=None,
                      hintmode=None,
                      queuestate=None)

        # Assert that each input has the expected properties
        self.assertTrue(self.cmap.is_correct('1_2_1'))
        self.assertFalse(self.cmap.is_correct('2_2_1'))

        self.assertEqual(self.cmap.get_correctness('1_2_1'), 'correct')
        self.assertEqual(self.cmap.get_correctness('2_2_1'), 'incorrect')

        self.assertEqual(self.cmap.get_npoints('1_2_1'), 5)
        self.assertEqual(self.cmap.get_npoints('2_2_1'), 0)

        self.assertEqual(self.cmap.get_msg('1_2_1'), 'Test message')
        self.assertEqual(self.cmap.get_msg('2_2_1'), None)

        self.assertEqual(self.cmap.get_hint('1_2_1'), 'Test hint')
        self.assertEqual(self.cmap.get_hint('2_2_1'), None)

        self.assertEqual(self.cmap.get_hintmode('1_2_1'), 'always')
        self.assertEqual(self.cmap.get_hintmode('2_2_1'), None)

        self.assertTrue(self.cmap.is_queued('1_2_1'))
        self.assertFalse(self.cmap.is_queued('2_2_1'))

        self.assertEqual(self.cmap.get_queuetime_str('1_2_1'),
                         '20130228100026')
        self.assertEqual(self.cmap.get_queuetime_str('2_2_1'), None)

        self.assertTrue(self.cmap.is_right_queuekey('1_2_1', 'secretstring'))
        self.assertFalse(self.cmap.is_right_queuekey('1_2_1', 'invalidstr'))
        self.assertFalse(self.cmap.is_right_queuekey('1_2_1', ''))
        self.assertFalse(self.cmap.is_right_queuekey('1_2_1', None))

        self.assertFalse(self.cmap.is_right_queuekey('2_2_1', 'secretstring'))
        self.assertFalse(self.cmap.is_right_queuekey('2_2_1', 'invalidstr'))
        self.assertFalse(self.cmap.is_right_queuekey('2_2_1', ''))
        self.assertFalse(self.cmap.is_right_queuekey('2_2_1', None))

    def test_get_npoints(self):
        # Set the correctmap properties for 4 inputs
        # 1) correct, 5 points
        # 2) correct, None points
        # 3) incorrect, 5 points
        # 4) incorrect, None points
        # 5) correct, 0 points
        self.cmap.set(answer_id='1_2_1', correctness='correct', npoints=5)

        self.cmap.set(answer_id='2_2_1', correctness='correct', npoints=None)

        self.cmap.set(answer_id='3_2_1', correctness='incorrect', npoints=5)

        self.cmap.set(answer_id='4_2_1', correctness='incorrect', npoints=None)

        self.cmap.set(answer_id='5_2_1', correctness='correct', npoints=0)

        # Assert that we get the expected points
        # If points assigned --> npoints
        # If no points assigned and correct --> 1 point
        # If no points assigned and incorrect --> 0 points
        self.assertEqual(self.cmap.get_npoints('1_2_1'), 5)
        self.assertEqual(self.cmap.get_npoints('2_2_1'), 1)
        self.assertEqual(self.cmap.get_npoints('3_2_1'), 5)
        self.assertEqual(self.cmap.get_npoints('4_2_1'), 0)
        self.assertEqual(self.cmap.get_npoints('5_2_1'), 0)

    def test_set_overall_message(self):

        # Default is an empty string string
        self.assertEqual(self.cmap.get_overall_message(), "")

        # Set a message that applies to the whole question
        self.cmap.set_overall_message("Test message")

        # Retrieve the message
        self.assertEqual(self.cmap.get_overall_message(), "Test message")

        # Setting the message to None --> empty string
        self.cmap.set_overall_message(None)
        self.assertEqual(self.cmap.get_overall_message(), "")

    def test_update_from_correctmap(self):
        # Initialize a CorrectMap with some properties
        self.cmap.set(answer_id='1_2_1',
                      correctness='correct',
                      npoints=5,
                      msg='Test message',
                      hint='Test hint',
                      hintmode='always',
                      queuestate={
                          'key': 'secretstring',
                          'time': '20130228100026'
                      })

        self.cmap.set_overall_message("Test message")

        # Create a second cmap, then update it to have the same properties
        # as the first cmap
        other_cmap = CorrectMap()
        other_cmap.update(self.cmap)

        # Assert that it has all the same properties
        self.assertEqual(other_cmap.get_overall_message(),
                         self.cmap.get_overall_message())

        self.assertEqual(other_cmap.get_dict(), self.cmap.get_dict())

    def test_update_from_invalid(self):
        # Should get an exception if we try to update() a CorrectMap
        # with a non-CorrectMap value
        invalid_list = [None, "string", 5, datetime.datetime.today()]

        for invalid in invalid_list:
            with self.assertRaises(Exception):
                self.cmap.update(invalid)
class CorrectMapTest(unittest.TestCase):
    """
    Tests to verify that CorrectMap behaves correctly
    """

    def setUp(self):
        super(CorrectMapTest, self).setUp()
        self.cmap = CorrectMap()

    def test_set_input_properties(self):
        # Set the correctmap properties for two inputs
        self.cmap.set(
            answer_id='1_2_1',
            correctness='correct',
            npoints=5,
            msg='Test message',
            hint='Test hint',
            hintmode='always',
            queuestate={
                'key': 'secretstring',
                'time': '20130228100026'
            }
        )

        self.cmap.set(
            answer_id='2_2_1',
            correctness='incorrect',
            npoints=None,
            msg=None,
            hint=None,
            hintmode=None,
            queuestate=None
        )

        # Assert that each input has the expected properties
        self.assertTrue(self.cmap.is_correct('1_2_1'))
        self.assertFalse(self.cmap.is_correct('2_2_1'))

        self.assertEqual(self.cmap.get_correctness('1_2_1'), 'correct')
        self.assertEqual(self.cmap.get_correctness('2_2_1'), 'incorrect')

        self.assertEqual(self.cmap.get_npoints('1_2_1'), 5)
        self.assertEqual(self.cmap.get_npoints('2_2_1'), 0)

        self.assertEqual(self.cmap.get_msg('1_2_1'), 'Test message')
        self.assertEqual(self.cmap.get_msg('2_2_1'), None)

        self.assertEqual(self.cmap.get_hint('1_2_1'), 'Test hint')
        self.assertEqual(self.cmap.get_hint('2_2_1'), None)

        self.assertEqual(self.cmap.get_hintmode('1_2_1'), 'always')
        self.assertEqual(self.cmap.get_hintmode('2_2_1'), None)

        self.assertTrue(self.cmap.is_queued('1_2_1'))
        self.assertFalse(self.cmap.is_queued('2_2_1'))

        self.assertEqual(self.cmap.get_queuetime_str('1_2_1'), '20130228100026')
        self.assertEqual(self.cmap.get_queuetime_str('2_2_1'), None)

        self.assertTrue(self.cmap.is_right_queuekey('1_2_1', 'secretstring'))
        self.assertFalse(self.cmap.is_right_queuekey('1_2_1', 'invalidstr'))
        self.assertFalse(self.cmap.is_right_queuekey('1_2_1', ''))
        self.assertFalse(self.cmap.is_right_queuekey('1_2_1', None))

        self.assertFalse(self.cmap.is_right_queuekey('2_2_1', 'secretstring'))
        self.assertFalse(self.cmap.is_right_queuekey('2_2_1', 'invalidstr'))
        self.assertFalse(self.cmap.is_right_queuekey('2_2_1', ''))
        self.assertFalse(self.cmap.is_right_queuekey('2_2_1', None))

    def test_get_npoints(self):
        # Set the correctmap properties for 4 inputs
        # 1) correct, 5 points
        # 2) correct, None points
        # 3) incorrect, 5 points
        # 4) incorrect, None points
        # 5) correct, 0 points
        self.cmap.set(
            answer_id='1_2_1',
            correctness='correct',
            npoints=5.3
        )

        self.cmap.set(
            answer_id='2_2_1',
            correctness='correct',
            npoints=None
        )

        self.cmap.set(
            answer_id='3_2_1',
            correctness='incorrect',
            npoints=5
        )

        self.cmap.set(
            answer_id='4_2_1',
            correctness='incorrect',
            npoints=None
        )

        self.cmap.set(
            answer_id='5_2_1',
            correctness='correct',
            npoints=0
        )

        # Assert that we get the expected points
        # If points assigned --> npoints
        # If no points assigned and correct --> 1 point
        # If no points assigned and incorrect --> 0 points
        self.assertEqual(self.cmap.get_npoints('1_2_1'), 5.3)
        self.assertEqual(self.cmap.get_npoints('2_2_1'), 1)
        self.assertEqual(self.cmap.get_npoints('3_2_1'), 5)
        self.assertEqual(self.cmap.get_npoints('4_2_1'), 0)
        self.assertEqual(self.cmap.get_npoints('5_2_1'), 0)

    def test_set_overall_message(self):

        # Default is an empty string string
        self.assertEqual(self.cmap.get_overall_message(), "")

        # Set a message that applies to the whole question
        self.cmap.set_overall_message("Test message")

        # Retrieve the message
        self.assertEqual(self.cmap.get_overall_message(), "Test message")

        # Setting the message to None --> empty string
        self.cmap.set_overall_message(None)
        self.assertEqual(self.cmap.get_overall_message(), "")

    def test_update_from_correctmap(self):
        # Initialize a CorrectMap with some properties
        self.cmap.set(
            answer_id='1_2_1',
            correctness='correct',
            npoints=5,
            msg='Test message',
            hint='Test hint',
            hintmode='always',
            queuestate={
                'key': 'secretstring',
                'time': '20130228100026'
            }
        )

        self.cmap.set_overall_message("Test message")

        # Create a second cmap, then update it to have the same properties
        # as the first cmap
        other_cmap = CorrectMap()
        other_cmap.update(self.cmap)

        # Assert that it has all the same properties
        self.assertEqual(
            other_cmap.get_overall_message(),
            self.cmap.get_overall_message()
        )

        self.assertEqual(
            other_cmap.get_dict(),
            self.cmap.get_dict()
        )

    def test_update_from_invalid(self):
        # Should get an exception if we try to update() a CorrectMap
        # with a non-CorrectMap value
        invalid_list = [None, "string", 5, datetime.datetime.today()]

        for invalid in invalid_list:
            with self.assertRaises(Exception):
                self.cmap.update(invalid)
class CorrectMapTest(unittest.TestCase):
    """
    Tests to verify that CorrectMap behaves correctly
    """

    def setUp(self):
        super(CorrectMapTest, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
        self.cmap = CorrectMap()

    def test_set_input_properties(self):
        # Set the correctmap properties for three inputs
        self.cmap.set(
            answer_id='1_2_1',
            correctness='correct',
            npoints=5,
            msg='Test message',
            hint='Test hint',
            hintmode='always',
            queuestate={
                'key': 'secretstring',
                'time': '20130228100026'
            }
        )

        self.cmap.set(
            answer_id='2_2_1',
            correctness='incorrect',
            npoints=None,
            msg=None,
            hint=None,
            hintmode=None,
            queuestate=None
        )

        self.cmap.set(
            answer_id='3_2_1',
            correctness='partially-correct',
            npoints=3,
            msg=None,
            hint=None,
            hintmode=None,
            queuestate=None
        )

        # Assert that each input has the expected properties
        assert self.cmap.is_correct('1_2_1')
        assert not self.cmap.is_correct('2_2_1')
        assert self.cmap.is_correct('3_2_1')

        assert self.cmap.is_partially_correct('3_2_1')
        assert not self.cmap.is_partially_correct('2_2_1')

        # Intentionally testing an item that's not in cmap.
        assert not self.cmap.is_partially_correct('9_2_1')

        assert self.cmap.get_correctness('1_2_1') == 'correct'
        assert self.cmap.get_correctness('2_2_1') == 'incorrect'
        assert self.cmap.get_correctness('3_2_1') == 'partially-correct'

        assert self.cmap.get_npoints('1_2_1') == 5
        assert self.cmap.get_npoints('2_2_1') == 0
        assert self.cmap.get_npoints('3_2_1') == 3

        assert self.cmap.get_msg('1_2_1') == 'Test message'
        assert self.cmap.get_msg('2_2_1') is None

        assert self.cmap.get_hint('1_2_1') == 'Test hint'
        assert self.cmap.get_hint('2_2_1') is None

        assert self.cmap.get_hintmode('1_2_1') == 'always'
        assert self.cmap.get_hintmode('2_2_1') is None

        assert self.cmap.is_queued('1_2_1')
        assert not self.cmap.is_queued('2_2_1')

        assert self.cmap.get_queuetime_str('1_2_1') == '20130228100026'
        assert self.cmap.get_queuetime_str('2_2_1') is None

        assert self.cmap.is_right_queuekey('1_2_1', 'secretstring')
        assert not self.cmap.is_right_queuekey('1_2_1', 'invalidstr')
        assert not self.cmap.is_right_queuekey('1_2_1', '')
        assert not self.cmap.is_right_queuekey('1_2_1', None)

        assert not self.cmap.is_right_queuekey('2_2_1', 'secretstring')
        assert not self.cmap.is_right_queuekey('2_2_1', 'invalidstr')
        assert not self.cmap.is_right_queuekey('2_2_1', '')
        assert not self.cmap.is_right_queuekey('2_2_1', None)

    def test_get_npoints(self):
        # Set the correctmap properties for 4 inputs
        # 1) correct, 5 points
        # 2) correct, None points
        # 3) incorrect, 5 points
        # 4) incorrect, None points
        # 5) correct, 0 points
        # 4) partially correct, 2.5 points
        # 5) partially correct, None points
        self.cmap.set(
            answer_id='1_2_1',
            correctness='correct',
            npoints=5.3
        )

        self.cmap.set(
            answer_id='2_2_1',
            correctness='correct',
            npoints=None
        )

        self.cmap.set(
            answer_id='3_2_1',
            correctness='incorrect',
            npoints=5
        )

        self.cmap.set(
            answer_id='4_2_1',
            correctness='incorrect',
            npoints=None
        )

        self.cmap.set(
            answer_id='5_2_1',
            correctness='correct',
            npoints=0
        )

        self.cmap.set(
            answer_id='6_2_1',
            correctness='partially-correct',
            npoints=2.5
        )

        self.cmap.set(
            answer_id='7_2_1',
            correctness='partially-correct',
            npoints=None
        )

        # Assert that we get the expected points
        # If points assigned --> npoints
        # If no points assigned and correct --> 1 point
        # If no points assigned and partially correct --> 1 point
        # If no points assigned and incorrect --> 0 points
        assert self.cmap.get_npoints('1_2_1') == 5.3
        assert self.cmap.get_npoints('2_2_1') == 1
        assert self.cmap.get_npoints('3_2_1') == 5
        assert self.cmap.get_npoints('4_2_1') == 0
        assert self.cmap.get_npoints('5_2_1') == 0
        assert self.cmap.get_npoints('6_2_1') == 2.5
        assert self.cmap.get_npoints('7_2_1') == 1

    def test_set_overall_message(self):

        # Default is an empty string string
        assert self.cmap.get_overall_message() == ''

        # Set a message that applies to the whole question
        self.cmap.set_overall_message("Test message")

        # Retrieve the message
        assert self.cmap.get_overall_message() == 'Test message'

        # Setting the message to None --> empty string
        self.cmap.set_overall_message(None)
        assert self.cmap.get_overall_message() == ''

    def test_update_from_correctmap(self):
        # Initialize a CorrectMap with some properties
        self.cmap.set(
            answer_id='1_2_1',
            correctness='correct',
            npoints=5,
            msg='Test message',
            hint='Test hint',
            hintmode='always',
            queuestate={
                'key': 'secretstring',
                'time': '20130228100026'
            }
        )

        self.cmap.set_overall_message("Test message")

        # Create a second cmap, then update it to have the same properties
        # as the first cmap
        other_cmap = CorrectMap()
        other_cmap.update(self.cmap)

        # Assert that it has all the same properties
        assert other_cmap.get_overall_message() == self.cmap.get_overall_message()

        assert other_cmap.get_dict() == self.cmap.get_dict()

    def test_update_from_invalid(self):
        # Should get an exception if we try to update() a CorrectMap
        # with a non-CorrectMap value
        invalid_list = [None, "string", 5, datetime.datetime.today()]

        for invalid in invalid_list:
            with pytest.raises(Exception):
                self.cmap.update(invalid)

    def test_set_none_state(self):
        """
        Test that if an invalid state is set to correct map, the state does not
        update at all.
        """
        invalid_list = [None, "", False, 0]
        for invalid in invalid_list:
            self.cmap.set_dict(invalid)
            assert self.cmap.get_dict() == {}