def test_ActivityProbability_defaults_to_empty_kwargs_with_custom_distros(): def custom_sampler(x): return 0.5 prob = modify.ActivityProbability([''], custom_sampler) assert prob.kwargs == {} custom_sampler('', **prob.kwargs)
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 = modify.ActivityPolicy( modify.RemoveActivity(['education']), modify.ActivityProbability(['education'], 1), modify.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_ActivityProbability_p_returns_0_for_activity_for_irrelevant_Activity( mocker, Steve): prob = modify.ActivityProbability(['work'], 0.25) act = [act for act in Steve.activities][2] p = prob.p(act) assert p == 0
def test_ActivityProbability_p_delegates_to_compute_probability_for_activity_for_each_activity_for_person_in_Household( mocker, SmithHousehold_alt): mocker.patch.object(modify.ActivityProbability, 'compute_probability_for_activity', return_value=0.25) prob = modify.ActivityProbability(['work', 'escort'], 0.25) p = prob.p(SmithHousehold_alt) assert modify.ActivityProbability.compute_probability_for_activity.call_count == 4 assert p == 0.68359375
def test_ActivityProbability_p_delegates_to_compute_probability_for_activity_for_each_Activity_for_Person( mocker, Steve): mocker.patch.object(modify.ActivityProbability, 'compute_probability_for_activity', return_value=0.25) prob = modify.ActivityProbability(['work', 'escort'], 0.25) person = Steve p = prob.p(person) assert modify.ActivityProbability.compute_probability_for_activity.call_count == 2 assert p == 0.4375
def test_ActivityProbability_compute_probability_for_activity_delegates_p_to_custom_callable( ): called = None def custom_sampler(x, kwarg): nonlocal called called = True return 0.5 prob = modify.ActivityProbability([''], custom_sampler, {'kwarg': 'kwarg'}) assert prob.compute_probability_for_activity(Activity(1)) == 0.5 assert called
def test_ActivityProbability_p_delegates_to_compute_probability_for_activity_for_relevant_Activity( mocker, Steve): mocker.patch.object(modify.ActivityProbability, 'compute_probability_for_activity', return_value=0.25) prob = modify.ActivityProbability(['work'], 0.25) act = [act for act in Steve.activities][1] p = prob.p(act) modify.ActivityProbability.compute_probability_for_activity.assert_called_once_with( act) assert p == 0.25
def test_verify_probability_check_list_of_probabilities(): p_list = [ modify.HouseholdProbability(0.5), modify.ActivityProbability([''], 0.5), modify.SimpleProbability(0.5), 0.2 ] verified_p_list = modify.verify_probability( p_list, (float, list, modify.HouseholdProbability, modify.ActivityProbability, modify.SimpleProbability)) assert p_list[:-1] == verified_p_list[:-1] assert isinstance(verified_p_list[-1], modify.SimpleProbability) assert verified_p_list[-1].p(None) == 0.2
def test_person_policy_with_activity_based_probability_with_a_satisfied_person_attribute( SmithHousehold, mocker): mocker.patch.object(modify.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 = modify.PersonPolicy( modify.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), [ modify.ActivityProbability( ['education', 'escort', 'leisure', 'shop', 'work'], 0.5), modify.PersonProbability(discrete_sampler, { 'mapping': age_mapping, 'distribution': age_distribution }) ]) policy.apply_to(household) steve = household.people['1'] modify.RemoveActivity.remove_person_activities.assert_called_once_with( steve)
def test_person_policy_with_activity_based_probability(SmithHousehold, mocker): mocker.patch.object(modify.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 = modify.PersonPolicy( modify.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), modify.ActivityProbability( ['education', 'escort', 'leisure', 'shop', 'work'], 0.5)) policy.apply_to(household) steve = household.people['1'] modify.RemoveActivity.remove_person_activities.assert_called_once_with( steve)
def test_household_policy_with_activity_based_probability( SmithHousehold, mocker): mocker.patch.object(modify.RemoveActivity, 'remove_household_activities') mocker.patch.object(random, 'random', side_effect=[0.000244140624]) household = SmithHousehold # i.e. Bobby's education activity is affected and affects activities on household level policy = modify.HouseholdPolicy( modify.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), modify.ActivityProbability( ['education', 'escort', 'leisure', 'shop', 'work'], 0.5)) policy.apply_to(household) modify.RemoveActivity.remove_household_activities.assert_called_once_with( household)
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', 'shop', 'leisure', 'escort', '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 = modify.ActivityPolicy( modify.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), modify.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', 'shop', 'leisure', 'escort', '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_ActivityProbability_compute_probability_for_household_returns_same_level_p_for_floats( ): prob = modify.ActivityProbability([''], 0.5) assert prob.compute_probability_for_activity(Activity(1)) == 0.5
def test_ActivityProbability_p_throws_exception_when_given_whatever(): prob = modify.ActivityProbability([''], 0.5) with pytest.raises(NotImplementedError) as e: prob.p(None)
def test_ActivityProbability_accepts_functions(): def custom_sampler(x, kwarg): return 0.5 prob = modify.ActivityProbability([''], custom_sampler, {'kwarg': 'kwarg'}) assert prob.kwargs == {'kwarg': 'kwarg'}
def test_ActivityProbability_fails_non_probability_integers(): with pytest.raises(AssertionError): modify.ActivityProbability([''], 2)
def test_ActivityProbability_accepts_integer(): modify.ActivityProbability([''], 1)