diff --git a/common/lib/capa/capa/graders/draganddrop.py b/common/lib/capa/capa/graders/draganddrop.py index 0d0750d970..e02304aef0 100644 --- a/common/lib/capa/capa/graders/draganddrop.py +++ b/common/lib/capa/capa/graders/draganddrop.py @@ -107,6 +107,7 @@ class DragAndDrop(object): self.correct_positions = OrderedDict() # positions of comparing self.user_groups = OrderedDict() self.user_positions = OrderedDict() + self.incorrect = False def grade(self): ''' @@ -129,9 +130,12 @@ class DragAndDrop(object): Returns: True or False. ''' - if sorted(self.correct_groups.keys()) != sorted(self.user_groups.keys()): + + if self.incorrect: return False + if sorted(self.correct_groups.keys()) != sorted(self.user_groups.keys()): + return False for groupname, draggable_ids in self.correct_groups.items(): if sorted(draggable_ids) != sorted(self.user_groups[groupname]): return False @@ -142,11 +146,10 @@ class DragAndDrop(object): # with positions # 'denied' rule - # import ipdb; ipdb.set_trace() - denied_positions = [self.correct_positions[g].get('denied', []) - for g in self.correct_groups.keys()] - all_user_positions = [self.user_positions[g]['user'] - for g in self.correct_groups.keys()] + denied_positions = [item for g in self.correct_groups.keys() + for item in self.correct_positions[g].get('denied', [])] + all_user_positions = [item for g in self.correct_groups.keys() + for item in self.user_positions[g]['user']] if not self.compare_positions(denied_positions, all_user_positions, flag='denied'): return False @@ -229,10 +232,12 @@ class DragAndDrop(object): user_answer = json.loads(user_answer) self.use_targets = user_answer.get('use_targets') + # check if we have draggables that are not in correct answer: + check_extra_draggables = {} + # create identical data structures # user groups must mirror correct_groups - # and positions must reflect order in groups - + # and positions must reflect order in group for groupname in self.correct_groups: self.user_groups[groupname] = [] self.user_positions[groupname] = {'user': []} @@ -243,7 +248,14 @@ class DragAndDrop(object): self.user_groups[groupname].append(draggable_name) self.user_positions[groupname]['user'].append( draggable_dict[draggable_name]) + check_extra_draggables[draggable_name] = True + else: + check_extra_draggables[draggable_name] = \ + check_extra_draggables.get(draggable_name, False) + for draggable in check_extra_draggables: + if not check_extra_draggables[draggable]: + self.incorrect = True # import ipdb; ipdb.set_trace() diff --git a/common/lib/capa/capa/graders/tests.py b/common/lib/capa/capa/graders/tests.py index 4ffee39aaa..0e95b810a9 100644 --- a/common/lib/capa/capa/graders/tests.py +++ b/common/lib/capa/capa/graders/tests.py @@ -86,6 +86,72 @@ class Test_DragAndDrop(unittest.TestCase): correct_answer = {'grass': [[300, 200], 200], 'ant': [[500, 0], 200]} self.assertTrue(draganddrop.grade(user_input, correct_answer)) + def test_lcao_correct(self): + """Describe carbon molecule in LCAO-MO""" + user_input = '{"use_targets":true,"draggables":[{"1":"s_left"}, \ + {"5":"s_right"},{"4":"s_sigma"},{"6":"s_sigma_star"},{"7":"p_left_1"}, \ + {"8":"p_left_2"},{"10":"p_right_1"},{"9":"p_right_2"}, \ + {"2":"p_pi_1"},{"3":"p_pi_2"},{"11":"s_sigma_name"}, \ + {"13":"s_sigma_star_name"},{"15":"p_pi_name"},{"16":"p_pi_star_name"}, \ + {"12":"p_sigma_name"},{"14":"p_sigma_star_name"}]}' + correct_answer = draganddrop.DragAndDrop() + correct_answer.correct_groups['filled_levels'] = ['1', '2', '3', '4', '5', '6'] + correct_answer.correct_positions['filled_levels'] = {'allowed': [ + 's_left', 's_right', 's_sigma', 's_sigma_star', 'p_pi_1', 'p_pi_2']} + + correct_answer.correct_groups['spin_up'] = ['7', '8', '9', '10'] + correct_answer.correct_positions['spin_up'] = {'allowed': + ['p_left_1', 'p_left_2', 'p_right_1', 'p_right_2']} + + correct_answer.correct_groups['sigma'] = ['11', '12'] + correct_answer.correct_positions['sigma'] = {'allowed': + ['s_sigma_name', 'p_sigma_name']} + + correct_answer.correct_groups['sigma_star'] = ['13', '14'] + correct_answer.correct_positions['sigma_star'] = {'allowed': + ['s_sigma_star_name', 'p_sigma_star_name']} + + correct_answer.correct_groups['pi'] = ['15'] + correct_answer.correct_positions['pi'] = {'allowed': ['p_pi_name']} + + correct_answer.correct_groups['pi_star'] = ['16'] + correct_answer.correct_positions['pi_star'] = {'allowed': ['p_pi_star_name']} + + self.assertTrue(draganddrop.grade(user_input, correct_answer)) + + def test_lcao_extra_element_incorrect(self): + """Describe carbon molecule in LCAO-MO""" + user_input = '{"use_targets":true,"draggables":[{"1":"s_left"}, \ + {"5":"s_right"},{"4":"s_sigma"},{"6":"s_sigma_star"},{"7":"p_left_1"}, \ + {"8":"p_left_2"},{"17":"p_left_3"},{"10":"p_right_1"},{"9":"p_right_2"}, \ + {"2":"p_pi_1"},{"3":"p_pi_2"},{"11":"s_sigma_name"}, \ + {"13":"s_sigma_star_name"},{"15":"p_pi_name"},{"16":"p_pi_star_name"}, \ + {"12":"p_sigma_name"},{"14":"p_sigma_star_name"}]}' + correct_answer = draganddrop.DragAndDrop() + correct_answer.correct_groups['filled_levels'] = ['1', '2', '3', '4', '5', '6'] + correct_answer.correct_positions['filled_levels'] = {'allowed': [ + 's_left', 's_right', 's_sigma', 's_sigma_star', 'p_pi_1', 'p_pi_2']} + + correct_answer.correct_groups['spin_up'] = ['7', '8', '9', '10'] + correct_answer.correct_positions['spin_up'] = {'allowed': + ['p_left_1', 'p_left_2', 'p_right_1', 'p_right_2']} + + correct_answer.correct_groups['sigma'] = ['11', '12'] + correct_answer.correct_positions['sigma'] = {'allowed': + ['s_sigma_name', 'p_sigma_name']} + + correct_answer.correct_groups['sigma_star'] = ['13', '14'] + correct_answer.correct_positions['sigma_star'] = {'allowed': + ['s_sigma_star_name', 'p_sigma_star_name']} + + correct_answer.correct_groups['pi'] = ['15'] + correct_answer.correct_positions['pi'] = {'allowed': ['p_pi_name']} + + correct_answer.correct_groups['pi_star'] = ['16'] + correct_answer.correct_positions['pi_star'] = {'allowed': ['p_pi_star_name']} + + self.assertFalse(draganddrop.grade(user_input, correct_answer)) + def suite():