def test_ActivityPolicy_verifies_for_appropriate_probabilities(mocker): mocker.patch.object(probability_samplers, 'verify_probability') policies.ActivityPolicy(modifiers.RemoveActivity(['']), 0.5) probability_samplers.verify_probability.assert_called_once_with( 0.5, (probability_samplers.HouseholdProbability, probability_samplers.PersonProbability))
def test_attribute_based_remove_activity_policy_removes_all_matching_activities_from_strictly_relevant_people( home_education_home_university_student): household = instantiate_household_with( [home_education_home_university_student]) def age_condition_over_17(attribute_value): return attribute_value > 17 def job_condition_education(attribute_value): return attribute_value == 'education' assert_correct_activities( person=household.people[1], ordered_activities_list=['home', 'education', 'home']) assert age_condition_over_17(household.people[1].attributes['age']) assert job_condition_education(household.people[1].attributes['job']) policy_remove_higher_education = policies.ActivityPolicy( modifiers.RemoveActivity(['education']), probability_samplers.ActivityProbability(['education'], 1), filters.PersonAttributeFilter(conditions={ 'age': age_condition_over_17, 'job': job_condition_education }, how='all')) policy_remove_higher_education.apply_to(household) assert_correct_activities(person=household.people[1], ordered_activities_list=['home'])
def __init__(self, activities: list, probability: Union[float, int, probability_samplers.SamplingProbability], attribute_filter: filters.Filter = None): super().__init__(modifiers.RemoveActivity(activities), probability, attribute_filter)
def test_attribute_based_remove_activity_policy_does_not_remove_matching_activities_from_non_strictly_irrelevant_people( home_education_home_university_student): household = instantiate_household_with( [home_education_home_university_student]) def age_condition_under_0(attribute_value): return attribute_value < 0 def job_condition_wasevrrr(attribute_value): return attribute_value == 'wasevrrr' assert_correct_activities( person=household.people['1'], ordered_activities_list=['home', 'education', 'home']) assert not age_condition_under_0(household.people['1'].attributes['age']) assert not job_condition_wasevrrr(household.people['1'].attributes['job']) policy_remove_higher_education = policies.ActivityPolicy( modifiers.RemoveActivity(['education']), probability_samplers.ActivityProbability(['education'], 1), filters.PersonAttributeFilter(conditions={ 'age': age_condition_under_0, 'job': job_condition_wasevrrr }, how='any')) policy_remove_higher_education.apply_to(household) assert_correct_activities( person=household.people['1'], ordered_activities_list=['home', 'education', 'home'])
def test_remove_person_activities_delegates_to_remove_activities_for_Bobbys_activities( mocker, Bobby): mocker.patch.object(modifiers.RemoveActivity, 'remove_activities') policy = modifiers.RemoveActivity(['']) policy.remove_person_activities(Bobby) modifiers.RemoveActivity.remove_activities.assert_called_once()
def test_remove_household_activities_delegates_to_remove_person_activities_for_persons_in_household( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'remove_person_activities') policy = modifiers.RemoveActivity(['']) policy.remove_household_activities(SmithHousehold) assert modifiers.RemoveActivity.remove_person_activities.call_count == 4
def test_RemoveActivity_apply_to_delegates_to_remove_person_activities_when_given_person( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'remove_person_activities') policy = modifiers.RemoveActivity(['']) policy.apply_to(SmithHousehold, SmithHousehold[4]) modifiers.RemoveActivity.remove_person_activities.assert_called_once_with( SmithHousehold[4])
def test_remove_activities_removes_Bobbys_education(Bobby): policy = modifiers.RemoveActivity(['education']) def fnc(act): return True policy.remove_activities(Bobby, fnc) assert_correct_activities(Bobby, ['home'])
def test_HouseholdPolicy_does_nothing_if_not_selected_for_single_probability( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'apply_to') mocker.patch.object(random, 'random', return_value=0.7) policy = policies.HouseholdPolicy(modifiers.RemoveActivity(['']), 0.5) household = SmithHousehold policy.apply_to(household) assert not modifiers.RemoveActivity.apply_to.called, 'method should not have been called'
def test_HouseholdPolicy_apply_to_delegates_to_modifier_policy_apply_to_for_list_of_probabilities( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'apply_to') policy = policies.HouseholdPolicy(modifiers.RemoveActivity( ['']), [1., probability_samplers.SimpleProbability(1.)]) household = SmithHousehold policy.apply_to(household) modifiers.RemoveActivity.apply_to.assert_called_once_with(household)
def test_ActivityPolicy_does_nothing_if_not_selected_for_list_of_probabilities( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'apply_to') mocker.patch.object(random, 'random', return_value=0.7) policy = policies.ActivityPolicy(modifiers.RemoveActivity( ['']), [0.5, probability_samplers.SimpleProbability(0.5)]) household = SmithHousehold policy.apply_to(household) assert not modifiers.RemoveActivity.apply_to.called, 'method should not have been called'
def test_home_education_home_removal_of_education_act( person_home_education_home): household = instantiate_household_with([person_home_education_home]) assert_correct_activities( person=household.people['1'], ordered_activities_list=['home', 'education', 'home']) policy = policies.ActivityPolicy( modifiers.RemoveActivity(activities=['education']), 1) policy.apply_to(household) assert_correct_activities(person=household.people['1'], ordered_activities_list=['home'])
def test_person_policy_with_activity_based_probability_with_a_satisfied_person_attribute( SmithHousehold, mocker): mocker.patch.object(modifiers.RemoveActivity, 'remove_person_activities') mocker.patch.object(random, 'random', side_effect=[0] + [1] * 11) household = SmithHousehold # i.e. First of Steve's work activities is affected and affects all listed activities for just Steve def discrete_sampler(obj, mapping, distribution): p = distribution for key in mapping: value = obj.attributes.get(key) if value is None: raise KeyError( f"Cannot find mapping: {key} in sampling features: {obj.attributes}" ) p = p.get(value) if p is None: raise KeyError( f"Cannot find feature for {key}: {value} in distribution: {p}" ) return p age_mapping = ['age'] below_20 = [i for i in range(21)] above_20 = [i for i in range(21, 101)] age_distribution = { **dict(zip(below_20, [0] * len(below_20))), **dict(zip(above_20, [1] * len(above_20))) } people_satisfying_age_condition_over_20 = 0 for pid, person in household.people.items(): people_satisfying_age_condition_over_20 += discrete_sampler( person, age_mapping, age_distribution) assert people_satisfying_age_condition_over_20 == 2 policy = policies.PersonPolicy( modifiers.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), [ probability_samplers.ActivityProbability( ['education', 'escort', 'leisure', 'shop', 'work'], 0.5), probability_samplers.PersonProbability( discrete_sampler, { 'mapping': age_mapping, 'distribution': age_distribution }) ]) policy.apply_to(household) steve = household.people['1'] modifiers.RemoveActivity.remove_person_activities.assert_called_once_with( steve)
def test_PersonPolicy_apply_to_delegates_to_modifier_policy_apply_to_for_single_probability( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'apply_to') mocker.patch.object(probability_samplers.SimpleProbability, 'sample', return_value=True) policy = policies.PersonPolicy(modifiers.RemoveActivity(['']), probability_samplers.SimpleProbability(1.)) household = SmithHousehold policy.apply_to(household) assert modifiers.RemoveActivity.apply_to.call_count == 4
def test_person_policy_with_person_based_probability(mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'remove_person_activities') mocker.patch.object(random, 'random', side_effect=[1, 1, 1, 0]) household = SmithHousehold # i.e. Bobby is affected and his activities are the only one affected in household policy = policies.PersonPolicy( modifiers.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), probability_samplers.PersonProbability(0.5)) bobby = household.people['4'] policy.apply_to(household) modifiers.RemoveActivity.remove_person_activities.assert_called_once_with( bobby)
def test_HouseholdPolicy_does_nothing_if_attribute_filter_condition_not_satisfied( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'apply_to') mocker.patch.object(filters.Filter, 'satisfies_conditions', return_value=False) policy = policies.HouseholdPolicy(modifiers.RemoveActivity(['']), 0.5, filters.Filter()) household = SmithHousehold policy.apply_to(household) assert not modifiers.RemoveActivity.apply_to.called, 'method should not have been called'
def test_ActivityPolicy_apply_to_delegates_to_modifier_policy_apply_to_for_list_of_probabilities( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'apply_to') mocker.patch.object(probability_samplers.SimpleProbability, 'p', return_value=1) policy = policies.ActivityPolicy(modifiers.RemoveActivity( ['']), [1., probability_samplers.SimpleProbability(1.)]) household = SmithHousehold policy.apply_to(household) assert modifiers.RemoveActivity.apply_to.call_count == 4
def test_household_policy_with_person_based_probability( SmithHousehold, mocker): mocker.patch.object(modifiers.RemoveActivity, 'remove_household_activities') mocker.patch.object(random, 'random', side_effect=[0.06249]) household = SmithHousehold # i.e. Bobby is affected and affects activities on household level policy = policies.HouseholdPolicy( modifiers.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), probability_samplers.PersonProbability(0.5)) policy.apply_to(household) modifiers.RemoveActivity.remove_household_activities.assert_called_once_with( household)
def test_person_policy_with_activity_based_probability(SmithHousehold, mocker): mocker.patch.object(modifiers.RemoveActivity, 'remove_person_activities') mocker.patch.object(random, 'random', side_effect=[0] + [1] * 11) household = SmithHousehold # i.e. First of Steve's work activities is affected and affects all listed activities for just Steve policy = policies.PersonPolicy( modifiers.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), probability_samplers.ActivityProbability( ['education', 'escort', 'leisure', 'shop', 'work'], 0.5)) policy.apply_to(household) steve = household.people['1'] modifiers.RemoveActivity.remove_person_activities.assert_called_once_with( steve)
def test_evaluate_activity_policy_selects_steve_for_individual_activity_removal( mocker, SmithHousehold): mocker.patch.object(random, 'random', side_effect=[1] + [0] + [1] * 18) household = SmithHousehold steve = household.people['1'] hilda = household.people['2'] timmy = household.people['3'] bobby = household.people['4'] assert_correct_activities( person=steve, ordered_activities_list=['home', 'work', 'leisure', 'work', 'home']) assert_correct_activities(person=hilda, ordered_activities_list=[ 'home', 'escort_education', 'shop', 'leisure', 'escort_education', 'home' ]) assert_correct_activities(person=timmy, ordered_activities_list=[ 'home', 'education', 'shop', 'education', 'leisure', 'home' ]) assert_correct_activities( person=bobby, ordered_activities_list=['home', 'education', 'home']) # i.e. First of Steve's work activities is affected and only that activity is affected policy = policies.ActivityPolicy( modifiers.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), probability_samplers.ActivityProbability( ['education', 'escort', 'leisure', 'shop', 'work'], 0.5)) policy.apply_to(household) assert_correct_activities( person=steve, ordered_activities_list=['home', 'leisure', 'work', 'home']) assert_correct_activities(person=hilda, ordered_activities_list=[ 'home', 'escort_education', 'shop', 'leisure', 'escort_education', 'home' ]) assert_correct_activities(person=timmy, ordered_activities_list=[ 'home', 'education', 'shop', 'education', 'leisure', 'home' ]) assert_correct_activities( person=bobby, ordered_activities_list=['home', 'education', 'home'])
def test_person_policy_with_person_based_probability_with_a_satisfied_person_attribute( mocker, SmithHousehold): mocker.patch.object(modifiers.RemoveActivity, 'remove_person_activities') mocker.patch.object(random, 'random', side_effect=[1, 1, 1, 0]) household = SmithHousehold # i.e. Bobby is affected and his activities are the only one affected in household def discrete_sampler(obj, mapping, distribution): p = distribution for key in mapping: value = obj.attributes.get(key) if value is None: raise KeyError( f"Cannot find mapping: {key} in sampling features: {obj.attributes}" ) p = p.get(value) if p is None: raise KeyError( f"Cannot find feature for {key}: {value} in distribution: {p}" ) return p age_mapping = ['age'] below_10 = [i for i in range(11)] above_10 = [i for i in range(11, 101)] age_distribution = { **dict(zip(below_10, [1] * len(below_10))), **dict(zip(above_10, [0] * len(above_10))) } people_satisfying_age_condition_under_10 = 0 for pid, person in household.people.items(): people_satisfying_age_condition_under_10 += discrete_sampler( person, age_mapping, age_distribution) assert people_satisfying_age_condition_under_10 == 1 policy = policies.PersonPolicy( modifiers.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), probability_samplers.PersonProbability(discrete_sampler, { 'mapping': age_mapping, 'distribution': age_distribution })) bobby = household.people['4'] policy.apply_to(household) modifiers.RemoveActivity.remove_person_activities.assert_called_once_with( bobby)
def test_remove_activity_policy_only_removes_individual_activities( mocker, home_education_shop_education_home): person = home_education_shop_education_home assert_correct_activities(person=person, ordered_activities_list=[ 'home', 'education', 'shop', 'education', 'home' ]) act_to_remove = list(person.activities)[3] policy_remove_education = modifiers.RemoveActivity(['education']) policy_remove_education.remove_individual_activities( person, [act_to_remove]) assert_correct_activities( person=person, ordered_activities_list=['home', 'education', 'shop', 'home'])
def test_is_activity_for_removal_activity_does_not_match_RemoveActivity_activities( ): activity = Activity(act='other_activity') policy_remove_activity = modifiers.RemoveActivity(['some_activity']) assert not policy_remove_activity.is_activity_for_removal(activity)
def test_is_activity_for_removal_activity_matches_RemoveActivity_activities(): activity = Activity(act='some_activity') policy_remove_activity = modifiers.RemoveActivity(['some_activity']) assert policy_remove_activity.is_activity_for_removal(activity)
def test_RemoveActivity_throws_exception_if_apply_to_given_wrong_input(Bobby): policy = modifiers.RemoveActivity(['']) with pytest.raises(TypeError) as e: policy.apply_to(Bobby) assert 'Types passed incorrectly: <class \'pam.core.Person\'>, <class \'NoneType\'>, <class \'NoneType\'>. You need <class \'type\'> at the very least.' \ in str(e.value)
def test_home_work_home_education_home_removal_of_education_act(): person = Person(1) person.add( Activity(seq=1, act='home', area='a', start_time=mtdt(0), end_time=mtdt(60))) person.add( Leg(seq=1, mode='car', start_area='a', end_area='b', start_time=mtdt(60), end_time=mtdt(90))) person.add( Activity(seq=2, act='work', area='b', start_time=mtdt(90), end_time=mtdt(120))) person.add( Leg(seq=2, mode='car', start_area='b', end_area='a', start_time=mtdt(120), end_time=mtdt(180))) person.add( Activity(seq=3, act='home', area='a', start_time=mtdt(180), end_time=mtdt(300))) person.add( Leg(seq=3, mode='car', start_area='a', end_area='b', start_time=mtdt(300), end_time=mtdt(390))) person.add( Activity(seq=2, act='education', area='b', start_time=mtdt(390), end_time=mtdt(520))) person.add( Leg(seq=2, mode='car', start_area='b', end_area='a', start_time=mtdt(520), end_time=mtdt(580))) person.add( Activity(seq=3, act='home', area='a', start_time=mtdt(680), end_time=END_OF_DAY)) household = instantiate_household_with([person]) assert_correct_activities( person=household.people['1'], ordered_activities_list=['home', 'work', 'home', 'education', 'home']) policy = policies.ActivityPolicy( modifiers.RemoveActivity(activities=['education']), 1) policy.apply_to(household) assert_correct_activities(person=household.people['1'], ordered_activities_list=['home', 'work', 'home'])