def test_PersonProbability_defaults_to_empty_kwargs_with_custom_distros(): def custom_sampler(x): return 0.5 prob = modify.PersonProbability(custom_sampler) assert prob.kwargs == {} custom_sampler('', **prob.kwargs)
def test_verify_probability_defaults_float_in_list_to_simple_probability( mocker): mocker.patch.object(modify.SimpleProbability, '__init__', return_value=None) modify.verify_probability([0.3, modify.PersonProbability(0.01)], (float, list, modify.PersonProbability)) modify.SimpleProbability.__init__.assert_called_once_with(0.3)
def test_PersonProbability_p_delegates_to_compute_probability_for_person_for_each_person_in_Household( mocker, SmithHousehold_alt): mocker.patch.object(modify.PersonProbability, 'compute_probability_for_person', return_value=0.25) prob = modify.PersonProbability(0.25) p = prob.p(SmithHousehold_alt) assert modify.PersonProbability.compute_probability_for_person.call_count == 2 assert p == 0.4375
def test_PersonProbability_p_delegates_to_compute_probability_for_person_for_Person( mocker): mocker.patch.object(modify.PersonProbability, 'compute_probability_for_person', return_value=None) prob = modify.PersonProbability(0.5) person = Person(1) prob.p(person) modify.PersonProbability.compute_probability_for_person.assert_called_once_with( person)
def test_PersonProbability_compute_probability_for_person_delegates_p_to_custom_callable( mocker): called = None def custom_sampler(x, kwarg): nonlocal called called = True return 0.5 prob = modify.PersonProbability(custom_sampler, {'kwarg': 'kwarg'}) person = Person(1) assert prob.compute_probability_for_person(person) == 0.5 assert called
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_person_based_probability(mocker, SmithHousehold): mocker.patch.object(modify.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 = modify.PersonPolicy( modify.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), modify.PersonProbability(0.5)) bobby = household.people['4'] policy.apply_to(household) modify.RemoveActivity.remove_person_activities.assert_called_once_with( bobby)
def test_household_policy_with_person_based_probability( SmithHousehold, mocker): mocker.patch.object(modify.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 = modify.HouseholdPolicy( modify.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), modify.PersonProbability(0.5)) policy.apply_to(household) modify.RemoveActivity.remove_household_activities.assert_called_once_with( household)
def test_person_policy_with_person_based_probability_with_a_satisfied_person_attribute( mocker, SmithHousehold): mocker.patch.object(modify.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 = modify.PersonPolicy( modify.RemoveActivity( ['education', 'escort', 'leisure', 'shop', 'work']), modify.PersonProbability(discrete_sampler, { 'mapping': age_mapping, 'distribution': age_distribution })) bobby = household.people['4'] policy.apply_to(household) modify.RemoveActivity.remove_person_activities.assert_called_once_with( bobby)
def test_MoveActivityToHomeLocation_moves_shop_to_home_location(): Hilda = Person(1, attributes={ 'age': 45, 'job': 'influencer', 'gender': 'female' }) Hilda.add( Activity(1, 'home', 'a', start_time=mtdt(0), end_time=mtdt(8 * 60))) Hilda.add( Leg(1, 'car', 'a', 'b', start_time=mtdt(8 * 60), end_time=mtdt(8 * 60 + 30))) Hilda.add( Activity(2, 'shop', 'b', start_time=mtdt(8 * 60 + 30), end_time=mtdt(16 * 60 + 30))) Hilda.add( Leg(1, 'car', 'b', 'a', start_time=mtdt(16 * 60 + 30), end_time=mtdt(17 * 60))) Hilda.add( Activity(5, 'home', 'a', start_time=mtdt(17 * 60), end_time=END_OF_DAY)) hhld = instantiate_household_with([Hilda]) policy = modify.PersonPolicy( modify.MoveActivityTourToHomeLocation(['shop']), modify.PersonProbability(1)) policy.apply_to(hhld) assert Hilda.plan[2].location == Hilda.home assert Hilda.plan[2].is_exact( Activity(2, 'shop', 'a', start_time=mtdt(8 * 60 + 30), end_time=mtdt(16 * 60 + 30)))
def test_MoveActivityToHomeLocation_performs_mode_shift_to_walk_due_to_lack_of_driving_licence( ): Hilda = Person(1, attributes={ 'age': 45, 'job': 'influencer', 'gender': 'female', 'driving_licence': False }) Hilda.add( Activity(1, 'home', 'a', start_time=mtdt(0), end_time=mtdt(8 * 60))) Hilda.add( Leg(1, 'pt', 'a', 'b', start_time=mtdt(8 * 60), end_time=mtdt(8 * 60 + 30))) Hilda.add( Activity(2, 'shop', 'b', start_time=mtdt(8 * 60 + 30), end_time=mtdt(16 * 60 + 30))) Hilda.add( Leg(1, 'pt', 'b', 'a', start_time=mtdt(16 * 60 + 30), end_time=mtdt(17 * 60))) Hilda.add( Activity(5, 'home', 'a', start_time=mtdt(17 * 60), end_time=END_OF_DAY)) hhld = instantiate_household_with([Hilda]) policy = modify.PersonPolicy( modify.MoveActivityTourToHomeLocation(['shop']), modify.PersonProbability(1)) policy.apply_to(hhld) assert Hilda.plan[1].mode == 'walk' assert Hilda.plan[3].mode == 'walk'
def test_MoveActivityToHomeLocation_does_moves_only_valid_shopping_tour( SmithHousehold): household = SmithHousehold Hilda = Person(2, attributes={ 'age': 45, 'job': 'influencer', 'gender': 'female' }) Hilda.add( Activity(1, 'home', 'a', start_time=mtdt(0), end_time=mtdt(8 * 60))) Hilda.add( Leg(1, 'walk', 'a', 'b', start_time=mtdt(8 * 60), end_time=mtdt(8 * 60 + 30))) Hilda.add( Activity(2, 'shop', 'b', start_time=mtdt(8 * 60 + 30), end_time=mtdt(10 * 60 + 30))) Hilda.add( Leg(2, 'walk', 'a', 'a', start_time=mtdt(10 * 60 + 30), end_time=mtdt(11 * 60))) Hilda.add( Activity(3, 'home', 'a', start_time=mtdt(11 * 60), end_time=mtdt(12 * 60))) Hilda.add( Leg(3, 'walk', 'a', 'c', start_time=mtdt(12 * 60), end_time=mtdt(12 * 60 + 30))) Hilda.add( Activity(4, 'shop', 'c', start_time=mtdt(12 * 60 + 30), end_time=mtdt(16 * 60 + 30))) Hilda.add( Leg(4, 'walk', 'a', 'c', start_time=mtdt(16 * 60 + 30), end_time=mtdt(17 * 60))) Hilda.add( Activity(5, 'leisure', 'c', start_time=mtdt(17 * 60), end_time=mtdt(17 * 60 + 30))) Hilda.add( Leg(5, 'walk', 'c', 'a', start_time=mtdt(17 * 60 + 30), end_time=mtdt(18 * 60))) Hilda.add( Activity(6, 'home', 'a', start_time=mtdt(18 * 60), end_time=END_OF_DAY)) household.people['2'] = Hilda assert_correct_activities(person=Hilda, ordered_activities_list=[ 'home', 'shop', 'home', 'shop', 'leisure', 'home' ]) assert_correct_activities_locations( person=Hilda, ordered_activities_locations_list=['a', 'b', 'a', 'c', 'c', 'a']) policy = modify.PersonPolicy( modify.MoveActivityTourToHomeLocation(['shop']), modify.PersonProbability(1)) policy.apply_to(household) assert_correct_activities(person=Hilda, ordered_activities_list=[ 'home', 'shop', 'home', 'shop', 'leisure', 'home' ]) assert_correct_activities_locations( person=Hilda, ordered_activities_locations_list=['a', 'a', 'a', 'c', 'c', 'a'])
def test_PersonProbability_fails_non_probability_integers(): with pytest.raises(AssertionError): modify.PersonProbability(2)
def test_PersonProbability_compute_probability_for_household_returns_same_level_p_for_floats( ): prob = modify.PersonProbability(0.5) assert prob.compute_probability_for_person(Person(1)) == 0.5
def test_PersonProbability_p_throws_exception_when_given_whatever(): prob = modify.PersonProbability(0.5) with pytest.raises(NotImplementedError) as e: prob.p(None)
def test_PersonProbability_accepts_integer(): modify.PersonProbability(1)
def test_apply_person_based_full_hh_quarantine_doesnt_create_or_delete_households( population): policy = modify.HouseholdQuarantined(modify.PersonProbability(1)) modify.apply_policies(population, [policy]) assert len(population.households) == 20
def test_MoveActivityToHomeLocation_moves_shopping_tour_to_home_location( SmithHousehold): household = SmithHousehold Steve = household.people['1'] Timmy = household.people['3'] Timmy.plan[4].act = 'shop_1' Bobby = household.people['4'] Hilda = Person(2, attributes={ 'age': 45, 'job': 'influencer', 'gender': 'female' }) Hilda.add( Activity(1, 'home', 'a', start_time=mtdt(0), end_time=mtdt(8 * 60))) Hilda.add( Leg(1, 'walk', 'a', 'b', start_time=mtdt(8 * 60), end_time=mtdt(8 * 60 + 30))) Hilda.add( Activity(2, 'shop_1', 'b', start_time=mtdt(8 * 60 + 30), end_time=mtdt(16 * 60 + 30))) Hilda.add( Leg(2, 'walk', 'b', 'c', start_time=mtdt(8 * 60), end_time=mtdt(8 * 60 + 30))) Hilda.add( Activity(3, 'shop_2', 'c', start_time=mtdt(8 * 60 + 30), end_time=mtdt(16 * 60 + 30))) Hilda.add( Leg(3, 'walk', 'c', 'a', start_time=mtdt(16 * 60 + 30), end_time=mtdt(17 * 60))) Hilda.add( Activity(4, 'home', 'a', start_time=mtdt(17 * 60), end_time=END_OF_DAY)) household.people['2'] = Hilda assert_correct_activities( person=Steve, ordered_activities_list=['home', 'work', 'leisure', 'work', 'home']) assert_correct_activities_locations( person=Steve, ordered_activities_locations_list=['a', 'b', 'c', 'b', 'a']) assert_correct_activities( person=Hilda, ordered_activities_list=['home', 'shop_1', 'shop_2', 'home']) assert_correct_activities_locations( person=Hilda, ordered_activities_locations_list=['a', 'b', 'c', 'a']) assert_correct_activities(person=Timmy, ordered_activities_list=[ 'home', 'education', 'shop_1', 'education', 'leisure', 'home' ]) assert_correct_activities_locations( person=Timmy, ordered_activities_locations_list=['a', 'b', 'c', 'b', 'd', 'a']) assert_correct_activities( person=Bobby, ordered_activities_list=['home', 'education', 'home']) assert_correct_activities_locations( person=Bobby, ordered_activities_locations_list=['a', 'b', 'a']) policy = modify.PersonPolicy( modify.MoveActivityTourToHomeLocation(['shop_1', 'shop_2']), modify.PersonProbability(1)) policy.apply_to(household) assert_correct_activities( person=Steve, ordered_activities_list=['home', 'work', 'leisure', 'work', 'home']) assert_correct_activities_locations( person=Steve, ordered_activities_locations_list=['a', 'b', 'c', 'b', 'a']) assert_correct_activities( person=Hilda, ordered_activities_list=['home', 'shop_1', 'shop_2', 'home']) assert_correct_activities_locations( person=Hilda, ordered_activities_locations_list=['a', 'a', 'a', 'a']) assert_correct_activities(person=Timmy, ordered_activities_list=[ 'home', 'education', 'shop_1', 'education', 'leisure', 'home' ]) assert_correct_activities_locations( person=Timmy, ordered_activities_locations_list=['a', 'b', 'c', 'b', 'd', 'a']) assert_correct_activities( person=Bobby, ordered_activities_list=['home', 'education', 'home']) assert_correct_activities_locations( person=Bobby, ordered_activities_locations_list=['a', 'b', 'a'])
def test_apply_person_based_full_quarantine(population): policy = modify.HouseholdQuarantined(modify.PersonProbability(1)) modify.apply_policies(population, [policy]) for hid, household in population.households.items(): for pid, person in household.people.items(): assert_single_home_activity(person)
def test_PersonProbability_accepts_functions(): def custom_sampler(x, kwarg): return 0.5 prob = modify.PersonProbability(custom_sampler, {'kwarg': 'kwarg'}) assert prob.kwargs == {'kwarg': 'kwarg'}