def test_delta_threshold_check_handles_negatives(self): """Check that the scoring continues if a list has a large negative delta - we are interested in abs() values""" __MAX_ITERATIONS = 10 __THRESHOLD = 0.1 __SUPRA_THRESHOLD = 2.0 __SUPRA_NEGATIVE_THRESHOLD = -2.0 __SUB_THRESHOLD = 0.0001 __SUB_NEGATIVE_THRESHOLD = -0.0001 __EXPECTED_ITERATIONS = 6 # Create two mock entities ent1 = mock.create_autospec(Entity) ent2 = mock.create_autospec(Entity) # Create a mock EntityList. Set the calculate_new_weight attribute # to be another mock, then set a side_effect to fake out successive # return values. The first one is above threshold values and then we # drop below threshold for subsequent calls. entity_list1 = mock.create_autospec(EntityList) entity_list1.calculate_new_weight = Mock() entity_list1.calculate_new_weight.side_effect = [ __SUPRA_THRESHOLD, __SUB_THRESHOLD, __SUB_THRESHOLD, __SUB_THRESHOLD, __SUB_THRESHOLD, __SUB_THRESHOLD, __SUB_THRESHOLD, __SUB_THRESHOLD ] # Repeat for a second mock EntityList # NOTE - the second list returns __SUPRA_NEGATIVE_THRESHOLD for five # iterations and then reports __SUB_NEGATIVE_THRESHOLD after that entity_list2 = mock.create_autospec(EntityList) entity_list2.calculate_new_weight = Mock() entity_list2.calculate_new_weight.side_effect = [ __SUPRA_NEGATIVE_THRESHOLD, __SUPRA_NEGATIVE_THRESHOLD, __SUPRA_NEGATIVE_THRESHOLD, __SUPRA_NEGATIVE_THRESHOLD, __SUPRA_NEGATIVE_THRESHOLD, __SUB_NEGATIVE_THRESHOLD, __SUB_NEGATIVE_THRESHOLD, __SUB_NEGATIVE_THRESHOLD ] entities = [ent1, ent2] entity_lists = [entity_list1, entity_list2] tested_object = CrossValidation(entities, entity_lists, __THRESHOLD, __MAX_ITERATIONS) tested_object.run_analysis() expected_calls = list(itertools.repeat(call(), __EXPECTED_ITERATIONS)) ent1.calculate_new_score.assert_has_calls(expected_calls) self.assertEqual(__EXPECTED_ITERATIONS, ent1.calculate_new_score.call_count) ent2.calculate_new_score.assert_has_calls(expected_calls) self.assertEqual(__EXPECTED_ITERATIONS, ent2.calculate_new_score.call_count) entity_list1.calculate_new_weight.assert_has_calls(expected_calls) self.assertEqual(__EXPECTED_ITERATIONS, entity_list1.calculate_new_weight.call_count) entity_list2.calculate_new_weight.assert_has_calls(expected_calls) self.assertEqual(__EXPECTED_ITERATIONS, entity_list2.calculate_new_weight.call_count)
def test_stop_on_max_iterations(self): """If the EntityLists never get their delta down below the threshold then we are not converging so we continue to process. Eventually we need to stop after the specified number of iterations """ __MAX_ITERATIONS = 10 __THRESHOLD = 0.1 __SUPRA_THRESHOLD = 2.0 __EXPECTED_ITERATIONS = __MAX_ITERATIONS # Create two mock entities ent1 = mock.create_autospec(Entity) ent2 = mock.create_autospec(Entity) # Create a mock EntityList. Set the calculate_new_weight attribute # to be another mock, then set a side_effect to fake out successive # return values. All of them are above threshold values entity_list1 = mock.create_autospec(EntityList) entity_list1.calculate_new_weight = Mock() entity_list1.calculate_new_weight.side_effect = list( itertools.repeat(__SUPRA_THRESHOLD, __MAX_ITERATIONS)) # Repeat for a second mock EntityList entity_list2 = mock.create_autospec(EntityList) entity_list2.calculate_new_weight = Mock() entity_list2.calculate_new_weight.side_effect = list( itertools.repeat(__SUPRA_THRESHOLD, __MAX_ITERATIONS)) entities = [ent1, ent2] entity_lists = [entity_list1, entity_list2] tested_object = CrossValidation(entities, entity_lists, __THRESHOLD, __MAX_ITERATIONS) tested_object.run_analysis() expected_calls = list(itertools.repeat(call(), __MAX_ITERATIONS)) ent1.calculate_new_score.assert_has_calls(expected_calls) self.assertEqual(__EXPECTED_ITERATIONS, ent1.calculate_new_score.call_count) ent2.calculate_new_score.assert_has_calls(expected_calls) entity_list1.calculate_new_weight.assert_has_calls(expected_calls) entity_list2.calculate_new_weight.assert_has_calls(expected_calls)
def test_one_list_never_hits_delta_threshold(self): """Check that the scoring continues for __MAX_ITERATIONS when one list fails to converge below __THRESHOLD. (i.e. all but one list are below the threshold but one remains stubbornly above and hence we continue to go around the loop.""" __MAX_ITERATIONS = 10 __THRESHOLD = 0.1 __SUPRA_THRESHOLD = 2.0 __SUB_THRESHOLD = 0.0001 # Create two mock entities ent1 = mock.create_autospec(Entity) ent2 = mock.create_autospec(Entity) # Create a mock EntityList. Set the calculate_new_weight attribute # to be another mock, then set a side_effect to fake out successive # return values. All of them are above threshold values entity_list1 = mock.create_autospec(EntityList) entity_list1.calculate_new_weight = Mock() entity_list1.calculate_new_weight.side_effect = list( itertools.repeat(__SUPRA_THRESHOLD, __MAX_ITERATIONS)) # Repeat for a second mock EntityList # NOTE - the second list returns __SUB_THRESHOLD entity_list2 = mock.create_autospec(EntityList) entity_list2.calculate_new_weight = Mock() entity_list2.calculate_new_weight.side_effect = list( itertools.repeat(__SUB_THRESHOLD, __MAX_ITERATIONS)) entities = [ent1, ent2] entity_lists = [entity_list1, entity_list2] tested_object = CrossValidation(entities, entity_lists, __THRESHOLD, __MAX_ITERATIONS) tested_object.run_analysis() expected_calls = list(itertools.repeat(call(), __MAX_ITERATIONS)) ent1.calculate_new_score.assert_has_calls(expected_calls) ent2.calculate_new_score.assert_has_calls(expected_calls) entity_list1.calculate_new_weight.assert_has_calls(expected_calls) entity_list2.calculate_new_weight.assert_has_calls(expected_calls)