Beispiel #1
0
def test_overwrite_attribute():

    population = Population(circus=tc, size=10,
                            ids_gen=SequencialGenerator(prefix="u_", max_length=1))

    ages = [10, 20, 40, 10, 100, 98, 12, 39, 76, 23]
    age_attr = population.create_attribute("age", init_values=ages)

    # before modification
    ages = age_attr.get_values(["u_0", "u_4", "u_9"]).tolist()
    assert ages == [10, 100, 23]

    story_data = pd.DataFrame({
        # id of the populations to update
        "A_ID": ["u_4", "u_0"],

        # new values to copy
        "new_ages": [34, 30]},

        # index of the story data has, in general, nothing to do with the
        # updated population
        index=["cust_1", "cust_2"]
    )

    update = age_attr.ops.update(
        member_id_field="A_ID",
        copy_from_field="new_ages"
    )

    _, logs = update(story_data)

    assert logs == {}
    # before modification
    ages = age_attr.get_values(["u_0", "u_4", "u_9"]).tolist()
    assert ages == [30, 34, 23]
def test_creating_an_empty_population_and_adding_attributes_later_should_be_possible(
):

    # empty population
    a = Population(circus=None, size=0)
    assert a.ids.shape[0] == 0

    # empty attributes
    a.create_attribute("att1")
    a.create_attribute("att2")

    dynamically_created = pd.DataFrame(
        {
            "att1": [1, 2, 3],
            "att2": [11, 12, 13],
        },
        index=["ac1", "ac2", "ac3"])

    a.update(dynamically_created)

    assert a.ids.tolist() == ["ac1", "ac2", "ac3"]
    assert a.get_attribute_values("att1",
                                  ["ac1", "ac2", "ac3"]).tolist() == [1, 2, 3]
    assert a.get_attribute_values(
        "att2", ["ac1", "ac2", "ac3"]).tolist() == [11, 12, 13]
Beispiel #3
0
def test_initializing_attribute_from_relationship_must_have_a_value_for_all():

    population = Population(circus=tc, size=5, ids_gen=SequencialGenerator(
        prefix="abc", max_length=1))
    oneto1 = population.create_relationship("rel")
    oneto1.add_relations(from_ids=["abc0", "abc1", "abc2", "abc3", "abc4"],
                         to_ids=["ta", "tb", "tc", "td", "te"])

    attr = Attribute(population, init_relationship="rel")

    expected = pd.DataFrame({"value": ["ta", "tb", "tc", "td", "te"]},
                            index=["abc0", "abc1", "abc2", "abc3", "abc4"])

    assert attr._table.sort_index().equals(expected)
def test_population_constructor_should_refuse_duplicated_ids():
    with pytest.raises(ValueError):
        Population(
            circus=None,
            size=10,
            # these ids have duplicated values, that is not good
            ids=[1, 2, 3, 4, 5, 6, 7, 8, 9, 9])
Beispiel #5
0
def test_scenario_transiting_to_state_with_1_back_to_default_prob_should_go_back_to_normal(
):
    """
    similar test to above, though this time we are using
    back_to_normal_prob = 1 => all populations should be back to "normal" state
    at the end of the execution
    """

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    # this one is slightly tricky: populations
    active_ids_gens = ConstantsMockGenerator(values=[np.nan] * 5 +
                                             population.ids[:5].tolist())

    excited_state_gens = ConstantsMockGenerator(values=[np.nan] * 5 +
                                                ["excited"] * 5)

    excited_call_activity = ConstantGenerator(value=10)

    # this time we're forcing to stay in the transited state
    back_to_normal_prob = ConstantGenerator(value=1)

    story = Story(
        name="tested",
        initiating_population=population,
        member_id_field="ac_id",
        states={
            "excited": {
                "activity": excited_call_activity,
                "back_to_default_probability": back_to_normal_prob
            }
        },

        # forcing the timer of all populations to be initialized to 0
        timer_gen=ConstantDependentGenerator(value=0))

    story.set_operations(
        # first 5 population are "active"
        active_ids_gens.ops.generate(named_as="active_ids"),
        excited_state_gens.ops.generate(named_as="new_state"),

        # forcing a transition to "excited" state of the 5 populations
        story.ops.transit_to_state(member_id_field="active_ids",
                                   state_field="new_state"))

    # before any execution, the state should be default for all
    assert ["default"] * 10 == story.timer["state"].tolist()

    logs = story.execute()

    # no logs are expected as output
    assert logs == {}

    # this time, all populations should have transited back to "normal" at the end
    print(story.timer["state"].tolist())
    assert ["default"] * 10 == story.timer["state"].tolist()
Beispiel #6
0
def test_updating_non_existing_population_ids_should_add_them():
    population = Population(circus=tc, size=5, ids_gen=SequencialGenerator(
        prefix="abc", max_length=1))
    tested = Attribute(population, init_values=[10, 20, 30, 40, 50])

    tested.update(pd.Series([22, 1000, 44], index=["abc1", "not_yet_there", "abc3"]))

    assert tested.get_values(["not_yet_there", "abc0", "abc3", "abc4"]).tolist() == [1000, 10, 44, 50]
Beispiel #7
0
def test_added_and_read_values_in_attribute_should_be_equal():
    population = Population(circus=tc, size=5,
                            ids_gen=SequencialGenerator(prefix="abc", max_length=1))
    tested = Attribute(population, init_values=[10, 20, 30, 40, 50])

    tested.add(["abc1", "abc3"], [22, 44])

    assert tested.get_values(["abc0", "abc1", "abc2", "abc3", "abc4"]).tolist() == [10, 20 + 22, 30, 40 + 44, 50]
Beispiel #8
0
def test_adding_several_times_to_the_same_from_should_pile_up():
    population = Population(circus=tc, size=5,
                            ids_gen=SequencialGenerator(prefix="abc", max_length=1))
    tested = Attribute(population, init_values=[10, 20, 30, 40, 50])

    tested.add(["abc1", "abc3", "abc1"], [22, 44, 10])

    assert tested.get_values(["abc0", "abc1", "abc2", "abc3", "abc4"]).tolist() == [10, 20 + 22 + 10, 30, 40 + 44, 50]
Beispiel #9
0
def test_story_autoreset_false_and_dropping_rows_should_reset_all_timers():
    # in case an story is configured not to perform an auto-reset, after one
    # execution:
    #  - all executed rows should now be at -1 (dropped or not)
    #  - all non executed rows should have gone down one tick

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    # 5 populations should trigger in 2 ticks, and 5 more
    init_timers = pd.Series([2] * 5 + [1] * 5, index=population.ids)
    timers_gen = MockTimerGenerator(init_timers)

    story = Story(
        name="tested",
        initiating_population=population,
        member_id_field="ac_id",

        # forcing the timer of all populations to be initialized to 0
        timer_gen=timers_gen,
        auto_reset_timer=False)

    # empty operation list as initialization
    # simulating an operation that drop the last 2 rows
    story.set_operations(MockDropOp(0, 2))

    # we have no auto-reset => all timers should intially be at -1
    all_minus_1 = pd.Series([-1] * 10, index=population.ids)
    assert story.timer["remaining"].equals(all_minus_1)

    # executing once => should do nothing, and leave all timers at -1
    story.execute()
    assert story.timer["remaining"].equals(all_minus_1)

    # triggering explicitaly the story => timers should have the hard-coded
    # values from the mock generator
    story.reset_timers()
    assert story.timer["remaining"].equals(init_timers)

    # after one execution, no population id has been selected and all counters
    # are decreased by 1
    story.execute()
    assert story.timer["remaining"].equals(init_timers - 1)

    # this time, the last 5 should have executed, but we should not have
    # any timer reste => they should go to -1.
    # The other 5 should now be at 0, ready to execute at next step
    story.execute()
    expected_timers = pd.Series([0] * 5 + [-1] * 5, index=population.ids)
    assert story.timer["remaining"].equals(expected_timers)

    # executing once more: the previously at -1 should still be there, and the
    # just executed at this stage should be there too
    story.execute()
    expected_timers = pd.Series([-1] * 10, index=population.ids)
    assert story.timer["remaining"].equals(expected_timers)
Beispiel #10
0
def test_bugfix_collisions_force_act_next():
    # Previously, resetting the timer of reset populations was cancelling the reset.
    #
    # We typically want to reset the timer when we have change the activity
    # state => we want to generate new timer values that reflect the new state.
    #
    # But force_act_next should still have priority on that: if somewhere else
    # we force some populations to act at the next clock step (e.g. to re-try
    # buying an ER or so), the fact that their activity level changed should
    # not cancel the retry.

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    # 5 populations should trigger in 2 ticks, and 5 more
    init_timers = pd.Series([2] * 5 + [1] * 5, index=population.ids)
    timers_gen = MockTimerGenerator(init_timers)

    story = Story(
        name="tested",
        initiating_population=population,
        member_id_field="ac_id",

        # forcing the timer of all populations to be initialized to 0
        timer_gen=timers_gen)

    timer_values = story.timer["remaining"].copy()

    forced = pd.Index(["ac_1", "ac_3", "ac_7", "ac_8", "ac_9"])
    not_forced = pd.Index(["ac_0", "ac_2", "ac_4", "ac_4", "ac_6"])

    # force_act_next should only impact those ids
    story.force_act_next(forced)
    assert story.timer.loc[forced]["remaining"].tolist() == [0, 0, 0, 0, 0]
    assert story.timer.loc[not_forced]["remaining"].equals(
        timer_values[not_forced])

    # resetting the timers should not change the timers of the populations that
    # are being forced
    story.reset_timers()
    assert story.timer.loc[forced]["remaining"].tolist() == [0, 0, 0, 0, 0]

    # Ticking the timers should not change the timers of the populations that
    # are being forced.
    # This is important for population forcing themselves to act at the next
    # clock
    # step (typical scenario for retry) => the fact of thick the clock at the
    # end of the execution should not impact them.
    story.timer_tick(population.ids)
    assert story.timer.loc[forced]["remaining"].tolist() == [0, 0, 0, 0, 0]
    assert story.timer.loc[not_forced]["remaining"].equals(
        timer_values[not_forced] - 1)
Beispiel #11
0
def test_updated_and_read_values_in_attribute_should_be_equal():
    population = Population(circus=tc, size=5, ids_gen=SequencialGenerator(
        prefix="abc", max_length=1))
    tested = Attribute(population, init_values=[10, 20, 30, 40, 50])

    tested.update(pd.Series([22, 44], index=["abc1", "abc3"]))

    # value of a should untouched
    assert tested.get_values(["abc0"]).tolist() == [10]

    # arbitrary order should not be impacted
    assert tested.get_values(["abc0", "abc3", "abc1"]).tolist() == [10, 44, 22]
Beispiel #12
0
def test_set_and_read_values_in_attribute_should_be_equal():

    population = Population(circus=None, size=5,
                            ids_gen=SequencialGenerator(prefix="abc", max_length=1))

    tested = Attribute(population, init_values=[10, 20, 30, 40, 50])

    assert tested.get_values(["abc0"]).tolist() == [10]
    assert tested.get_values(["abc0", "abc3", "abc1"]).tolist() == [10, 40, 20]

    # getting no id should return empty list
    assert tested.get_values([]).tolist() == []
Beispiel #13
0
def test_get_activity_should_be_default_by_default():

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))
    story = Story(name="tested",
                  initiating_population=population,
                  member_id_field="")

    # by default, each population should be in the default state with activity 1
    assert [1.] * 10 == story.get_param("activity", population.ids).tolist()
    assert story.get_possible_states() == ["default"]
Beispiel #14
0
def test_empty_story_should_do_nothing_and_not_crash():

    customers = Population(circus=None,
                           size=1000,
                           ids_gen=SequencialGenerator(prefix="a"))
    empty_story = Story(name="purchase",
                        initiating_population=customers,
                        member_id_field="AGENT")

    logs = empty_story.execute()

    # no logs should be produced
    assert logs == {}
Beispiel #15
0
def test_insert_op_population_value_for_existing_populations_should_update_all_values(
):
    # same as test above but triggered as an Operation on story data

    # copy of dummy population that will be updated
    tested_population = Population(circus=None,
                                   size=10,
                                   ids_gen=SequencialGenerator(max_length=1,
                                                               prefix="a_"))
    ages = [10, 20, 40, 10, 100, 98, 12, 39, 76, 23]
    tested_population.create_attribute("age", init_values=ages)
    city = ["a", "b", "b", "a", "d", "e", "r", "a", "z", "c"]
    tested_population.create_attribute("city", init_values=city)

    story_data = pd.DataFrame(
        {
            "the_new_age": [139, 123, 1, 2],
            "location": ["city_7", "city_9", "city_11", "city_10"],
            "updated_populations": ["a_7", "a_9", "a_11", "a_10"]
        },
        index=["d_1", "d_2", "d_4", "d_3"])

    update_op = tested_population.ops.update(id_field="updated_populations",
                                             copy_attributes_from_fields={
                                                 "age": "the_new_age",
                                                 "city": "location"
                                             })

    story_data_2, logs = update_op(story_data)

    # there should be no impact on the story data
    assert story_data_2.shape == (4, 3)
    assert sorted(story_data_2.columns.tolist()) == [
        "location", "the_new_age", "updated_populations"
    ]

    # we should have 2 new populations
    assert tested_population.ids.shape[0] == 12

    updated_age = tested_population.get_attribute_values(
        "age", ["a_0", "a_7", "a_9", "a_10", "a_11"])
    updated_city = tested_population.get_attribute_values(
        "city", ["a_0", "a_7", "a_9", "a_10", "a_11"])

    assert updated_age.tolist() == [10, 139, 123, 2, 1]
    assert updated_city.tolist() == [
        "a", "city_7", "city_9", "city_10", "city_11"
    ]
Beispiel #16
0
def test_io_round_trip():

    with path.tempdir() as root_dir:

        population = Population(circus=tc, size=5,
                                ids_gen=SequencialGenerator(prefix="abc", max_length=1))
        orig = Attribute(population, init_values=[10, 20, 30, 40, 50])

        full_path = os.path.join(root_dir, "attribute.csv")

        orig.save_to(full_path)
        retrieved = Attribute.load_from(full_path)

        assert orig._table.equals(retrieved._table)
Beispiel #17
0
def test_get_activity_should_be_aligned_for_each_state():

    excited_call_activity = ConstantGenerator(value=10)
    back_to_normal_prob = ConstantGenerator(value=.3)

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))
    story = Story(name="tested",
                  initiating_population=population,
                  member_id_field="",
                  states={
                      "excited": {
                          "activity": excited_call_activity,
                          "back_to_default_probability": back_to_normal_prob
                      }
                  })

    # by default, each population should be in the default state with activity 1
    assert [1] * 10 == story.get_param("activity", population.ids).tolist()
    assert [1] * 10 == story.get_param("back_to_default_probability",
                                       population.ids).tolist()
    assert sorted(story.get_possible_states()) == ["default", "excited"]

    story.transit_to_state(["ac_2", "ac_5", "ac_9"],
                           ["excited", "excited", "excited"])

    # activity and probability of getting back to normal should now be updated
    expected_activity = [1, 1, 10, 1, 1, 10, 1, 1, 1, 10]
    assert expected_activity == story.get_param("activity",
                                                population.ids).tolist()

    # also, doing a get_param for some specific population ids should return the
    # correct values (was buggy if we requested sth else than the whole list)
    assert expected_activity[2:7] == story.get_param(
        "activity", population.ids[2:7]).tolist()

    assert [1, 10] == story.get_param("activity", population.ids[-2:]).tolist()

    expected_probs = [1, 1, .3, 1, 1, .3, 1, 1, 1, .3]
    assert expected_probs == story.get_param(
        "back_to_default_probability",
        population.ids,
    ).tolist()
Beispiel #18
0
def test_bugfix_force_populations_should_only_act_once():

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    # 5 populations should trigger in 2 ticks, and 5 more
    init_timers = pd.Series([2] * 5 + [5] * 5, index=population.ids)
    timers_gen = MockTimerGenerator(init_timers)

    story = Story(
        name="tested",
        initiating_population=population,
        member_id_field="ac_id",

        # forcing the timer of all populations to be initialized to 0
        timer_gen=timers_gen)

    recording_op = FakeRecording()
    story.set_operations(recording_op)

    forced = pd.Index(["ac_1", "ac_3", "ac_7", "ac_8", "ac_9"])

    # force_act_next should only impact those ids
    story.force_act_next(forced)

    assert story.timer["remaining"].tolist() == [2, 0, 2, 0, 2, 5, 5, 0, 0, 0]

    story.execute()
    assert recording_op.last_seen_population_ids == [
        "ac_1", "ac_3", "ac_7", "ac_8", "ac_9"
    ]
    print(story.timer["remaining"].tolist())
    assert story.timer["remaining"].tolist() == [1, 2, 1, 2, 1, 4, 4, 5, 5, 5]
    recording_op.reset()

    story.execute()
    assert recording_op.last_seen_population_ids == []
    assert story.timer["remaining"].tolist() == [0, 1, 0, 1, 0, 3, 3, 4, 4, 4]

    story.execute()
    assert recording_op.last_seen_population_ids == ["ac_0", "ac_2", "ac_4"]
    assert story.timer["remaining"].tolist() == [2, 0, 2, 0, 2, 2, 2, 3, 3, 3]
Beispiel #19
0
def test_io_round_trip():

    with path.tempdir() as p:

        population_path = os.path.join(p, "test_location")
        dummy_population.save_to(population_path)
        retrieved = Population.load_from(circus=None, folder=population_path)

        assert dummy_population.size == retrieved.size
        assert dummy_population.ids.tolist() == retrieved.ids.tolist()

        ids = dummy_population.ids.tolist()

        for att_name in dummy_population.attribute_names():
            assert dummy_population.get_attribute_values(att_name, ids).equals(
                retrieved.get_attribute_values(att_name, ids))

        for rel_name in dummy_population.relationship_names():
            assert dummy_population.get_relationship(rel_name)._table.equals(
                retrieved.get_relationship(rel_name)._table)
Beispiel #20
0
def test_active_inactive_ids_should_mark_all_populations_active_when_all_timers_0(
):
    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    # 5 populations should trigger in 2 ticks, and 5 more
    init_timers = pd.Series([0] * 10, index=population.ids)
    timers_gen = MockTimerGenerator(init_timers)

    story = Story(
        name="tested",
        initiating_population=population,
        member_id_field="ac_id",

        # forcing the timer of all populations to be initialized to 0
        timer_gen=timers_gen,
        auto_reset_timer=True)
    assert (population.ids.tolist(), []) == story.active_inactive_ids()
Beispiel #21
0
def test_story_autoreset_true_and_dropping_rows_should_reset_all_timers():
    # in case an story is configured to perform an auto-reset, but also
    # drops some rows, after one execution,
    #  - all executed rows (dropped or not) should have a timer back to some
    # positive value
    #  - all non executed rows should have gone down one tick

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    # 5 populations should trigger in 2 ticks, and 5 more
    init_timers = pd.Series([2] * 5 + [1] * 5, index=population.ids)
    timers_gen = MockTimerGenerator(init_timers)

    story = Story(
        name="tested",
        initiating_population=population,
        member_id_field="ac_id",

        # forcing the timer of all populations to be initialized to 0
        timer_gen=timers_gen,
        auto_reset_timer=True)

    # simulating an operation that drop the last 2 rows
    story.set_operations(MockDropOp(0, 2))

    # initial timers should be those provided by the generator
    assert story.timer["remaining"].equals(init_timers)

    # after one execution, no population id has been selected and all counters
    # are decreased by 1
    story.execute()
    assert story.timer["remaining"].equals(init_timers - 1)

    # this time, the last 5 should have executed => and the last 3 of them
    # should have been dropped. Nonetheless, all 5 of them should be back to 1
    story.execute()
    expected_timers = pd.Series([0] * 5 + [1] * 5, index=population.ids)
    assert story.timer["remaining"].equals(expected_timers)
Beispiel #22
0
def test_story_autoreset_true_not_dropping_rows_should_reset_all_timers():
    # in case an story is configured to perform an auto-reset, after one
    # execution,
    #  - all executed rows should have a timer back to some positive value
    #  - all non executed rows should have gone down one tick

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    # 5 populations should trigger in 2 ticks, and 5 more
    init_timers = pd.Series([2] * 5 + [1] * 5, index=population.ids)
    timers_gen = MockTimerGenerator(init_timers)

    story = Story(
        name="tested",
        initiating_population=population,
        member_id_field="ac_id",

        # forcing the timer of all populations to be initialized to 0
        timer_gen=timers_gen,
        auto_reset_timer=True)

    # empty operation list as initialization
    story.set_operations(Operation())

    # initial timers should be those provided by the generator
    assert story.timer["remaining"].equals(init_timers)

    # after one execution, no population id has been selected and all counters
    # are decreased by 1
    story.execute()
    assert story.timer["remaining"].equals(init_timers - 1)

    # this time, the last 5 should have executed => go back up to 1. The
    # other 5 should now be at 0, ready to execute at next step
    story.execute()
    expected_timers = pd.Series([0] * 5 + [1] * 5, index=population.ids)
    assert story.timer["remaining"].equals(expected_timers)
Beispiel #23
0
    def create_random_cells(self, n_cells):
        """
        Creation of a basic population for cells, with latitude and longitude
        """

        cells = Population(size=n_cells)

        latitude_generator = FakerGenerator(method="latitude",
                                            seed=next(self.seeder))
        longitude_generator = FakerGenerator(method="longitude",
                                             seed=next(self.seeder))

        cells.create_attribute("latitude", init_gen=latitude_generator)
        cells.create_attribute("longitude", init_gen=longitude_generator)

        return cells
Beispiel #24
0
def test_populations_with_zero_activity_should_never_have_positive_timer():

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    story = Story(
        name="tested",
        initiating_population=population,
        # fake generator that assign zero activity to 3 populations
        activity_gen=ConstantsMockGenerator([1, 1, 1, 1, 0, 1, 1, 0, 0, 1]),
        timer_gen=ConstantDependentGenerator(value=10),
        member_id_field="")

    story.reset_timers()

    # all non zero populations should have been through the profiler => timer to 10
    # all others should be locked to -1, to reflect that activity 0 never
    # triggers anything
    expected_timers = [10, 10, 10, 10, -1, 10, 10, -1, -1, 10]

    assert expected_timers == story.timer["remaining"].tolist()
Beispiel #25
0
def test_scenario_transiting_to_state_with_0_back_to_default_prob_should_remain_there(
):
    """
    we create an story with a transit_to_state operation and 0 probability
    of going back to normal => after the execution, all triggered populations should
    still be in that starte
    """

    population = Population(circus=None,
                            size=10,
                            ids_gen=SequencialGenerator(prefix="ac_",
                                                        max_length=1))

    # here we are saying that some story on populations 5 to 9 is triggering a
    # state change on populations 0 to 4
    active_ids_gens = ConstantsMockGenerator(values=[np.nan] * 5 +
                                             population.ids[:5].tolist())

    excited_state_gens = ConstantsMockGenerator(values=[np.nan] * 5 +
                                                ["excited"] * 5)

    excited_call_activity = ConstantGenerator(value=10)

    # forcing to stay excited
    back_to_normal_prob = ConstantGenerator(value=0)

    story = Story(
        name="tested",
        initiating_population=population,
        member_id_field="ac_id",
        states={
            "excited": {
                "activity": excited_call_activity,
                "back_to_default_probability": back_to_normal_prob
            }
        },

        # forcing the timer of all populations to be initialized to 0
        timer_gen=ConstantDependentGenerator(value=0))

    story.set_operations(
        # first 5 population are "active"
        active_ids_gens.ops.generate(named_as="active_ids"),
        excited_state_gens.ops.generate(named_as="new_state"),

        # forcing a transition to "excited" state of the 5 populations
        story.ops.transit_to_state(member_id_field="active_ids",
                                   state_field="new_state"))

    # before any execution, the state should be default for all
    assert ["default"] * 10 == story.timer["state"].tolist()

    logs = story.execute()

    # no logs are expected as output
    assert logs == {}

    # the first 5 populations should still be in "excited", since
    # "back_to_normal_probability" is 0, the other 5 should not have
    # moved
    expected_state = ["excited"] * 5 + ["default"] * 5
    assert expected_state == story.timer["state"].tolist()
Beispiel #26
0
def test_insert_population_value_for_existing_and_new_populations_should_update_and_add_values(
):

    # copy of dummy population that will be updated
    tested_population = Population(circus=None,
                                   size=10,
                                   ids_gen=SequencialGenerator(max_length=1,
                                                               prefix="a_"))
    ages = [10, 20, 40, 10, 100, 98, 12, 39, 76, 23]
    tested_population.create_attribute("age", init_values=ages)
    city = ["a", "b", "b", "a", "d", "e", "r", "a", "z", "c"]
    tested_population.create_attribute("city", init_values=city)

    current = tested_population.get_attribute_values("age",
                                                     ["a_0", "a_7", "a_9"])
    assert current.tolist() == [10, 39, 23]

    update = pd.DataFrame(
        {
            "age": [139, 123, 54, 25],
            "city": ["city_7", "city_9", "city_11", "city_10"]
        },
        index=["a_7", "a_9", "a_11", "a_10"])

    tested_population.update(update)

    # we should have 2 new populations
    assert tested_population.ids.shape[0] == 12

    updated_age = tested_population.get_attribute_values(
        "age", ["a_0", "a_7", "a_9", "a_10", "a_11"])
    updated_city = tested_population.get_attribute_values(
        "city", ["a_0", "a_7", "a_9", "a_10", "a_11"])

    assert updated_age.tolist() == [10, 139, 123, 25, 54]
    assert updated_city.tolist() == [
        "a", "city_7", "city_9", "city_10", "city_11"
    ]
Beispiel #27
0
import path
import pandas as pd
import os
import pytest

from trumania.core.random_generators import SequencialGenerator
from trumania.core.population import Population

dummy_population = Population(circus=None,
                              size=10,
                              ids_gen=SequencialGenerator(max_length=1,
                                                          prefix="id_"))

ages = [10, 20, 40, 10, 100, 98, 12, 39, 76, 23]
dummy_population.create_attribute("age", init_values=ages)

city = ["a", "b", "b", "a", "d", "e", "r", "a", "z", "c"]
dummy_population.create_attribute("city", init_values=city)

# some fake story data with an index corresponding to another population
# => simulates an story triggered by that other population
# the column "NEIGHBOUR" contains value that point to the dummy population, with
# a duplication (id2)
story_data = pd.DataFrame(
    {
        "A": ["a1", "a2", "a3", "a4"],
        "B": ["b1", "b2", "b3", "b4"],
        "NEIGHBOUR": ["id_2", "id_4", "id_7", "id_2"],
        "COUSINS": [
            ["id_2", "id_4", "id_7", "id_2"],
            ["id_3"],
Beispiel #28
0
def load_population(namespace, population_id, circus):
    return Population.load_from(population_folder(namespace, population_id),
                                circus)