def test_death_z_test(self, reset_herbivore_params, omega_dict):
        """
        Based on H.E. Plesser: biolab/test_bacteria.py

        Probabilistic test of death function. Testing on herbivores.

        Given that the sample size is large. Under the Z-test the distribution under the null
        hypothesis can be estimated approximately by the normal distribution.
        See https://en.wikipedia.org/wiki/Z-test.

        Assuming low fitness of animals such that omega can be interpreted as an approximation of
        the death probability. Testing with different values of omega
        We compute the number of dead animals returned by our death function from class Animal.
        Then we compare this value to the mean of dead animals derived from a fixed probability.


        Null hypothesis: The number of dead animals returned by the death function is
        statistically significant with a p-value greater than the alpha parameter.
        Alternative hypothesis: The number of dead animals returned is not statistically
        significant and we reject the null hypothesis.
        """
        random.seed(123)
        # High age ensures low fitness
        herb = Herbivore(age=100, weight=10)
        # with low fitness we assume that the death probability is the same as omega
        herb.set_params(omega_dict)
        # death probability set equal to omega
        p = Herbivore.p["omega"]
        # Number of animals
        N = 1000
        # Number of dead animals
        n = sum(herb.death() for _ in range(N))
        # Performing the z-test
        assert phi_z_test(N, p, n) > TestAnimal.alpha
class TestAnimal:
    @pytest.fixture(autouse=True)
    def create_herb(self):
        """Creates a Herbivore object"""
        self.herb1 = Herbivore(5, 10)
        self.herb2 = Herbivore(5, 10)
        _w = Herbivore._params['zeta'] * (Herbivore._params['w_birth'] +
                                          Herbivore._params['sigma_birth'])
        self.enuf_weight_for_mum = _w
        self.mum_check_herb = Herbivore(5, self.enuf_weight_for_mum)
        self.death_prob_herb1 = Herbivore._params['omega'] * (
            1 - self.herb1.fitness())

    def test_animal_fitness(self):
        f1 = self.herb1.fitness()
        f2 = self.herb2.fitness()
        assert f1 == pytest.approx(
            f2), "fitness should be same for same age and weight"

    def test_animal_dies(self):
        death_prob = self.death_prob_herb1
        print('\n\n Death Probability: ', death_prob)
        N = 500
        n_deaths = sum(self.herb1.dies() for _ in range(N))
        print("Number of deaths:", n_deaths)

        assert binom_test(n_deaths, N, death_prob) > ALPHA
 def test_set_params(self):
     """
     Test that parameters can be set
     """
     my_params = {"w_birth": 10, "sigma_birth": 2.5}
     Herbivore.set_params(my_params)
     assert Herbivore.p["w_birth"] == 10
     assert Herbivore.p["sigma_birth"] == 2.5
 def test_aging(self):
     """
     Test that the animal age increases
     """
     herb = Herbivore(weight=10, age=0)
     carn = Carnivore(weight=10)
     herb.aging()
     carn.aging()
     assert herb.age > 0, carn.age > 0
 def create_herb(self):
     """Creates a Herbivore object"""
     self.herb1 = Herbivore(5, 10)
     self.herb2 = Herbivore(5, 10)
     _w = Herbivore._params['zeta'] * (Herbivore._params['w_birth'] +
                                       Herbivore._params['sigma_birth'])
     self.enuf_weight_for_mum = _w
     self.mum_check_herb = Herbivore(5, self.enuf_weight_for_mum)
     self.death_prob_herb1 = Herbivore._params['omega'] * (
         1 - self.herb1.fitness())
 def test_add_remove_animals(self, highland_cell):
     """
     :method: LandscapeCell.add_animals
     :method: LandscapeCell.remove_animals
     :property: LandscapeCell.animal_count
     Test that animals can be added and removed correctly
     """
     animals = [Herbivore(), Carnivore(), Herbivore()]
     highland_cell.add_animals(animals)
     highland_cell.remove_animals([animals[0], animals[1]])
     assert highland_cell.herb_count == 1
    def test_eat_fodder(self):
        """
        Weight of animal shall increase after eating fodder

        """
        herb = Herbivore(weight=10, age=0)
        herb_weight = herb.weight
        herb.eat_fodder(cell=Lowland())
        # new weight
        herb_weight_after = herb.weight
        assert herb_weight < herb_weight_after
    def test_certain_birth(self, mocker, reset_herbivore_params):
        """
        test give birth function
        Mock the random number generator to always return one.
        Then as long as weight is not zero. give_birth function shall return True.

        """
        herb = Herbivore(weight=800, age=5)
        num_herbs = 10
        mocker.patch("random.random", return_value=0)
        give_birth, _ = herb.give_birth(num_herbs)
        assert give_birth is True
 def test_lose_weight(self, reset_herbivore_params, reset_carnivore_params):
     """
     Test that animals lose weight
     """
     herb, carn = Herbivore(weight=20), Carnivore(weight=20)
     # Decreasing parameters
     herb.p['eta'] = 0.1
     carn.p['eta'] = 0.2
     herb_initial_weight, carn_initial_weight = herb.weight, carn.weight
     herb.lose_weight(), carn.lose_weight()
     # New weight of animal must be less than before
     assert herb.weight < herb_initial_weight
     assert carn.weight < carn_initial_weight
Exemple #10
0
    def set_animal_parameters(species, params):
        """Set parameters for animal species.

        :param species: String, name of animal species
        :param params: Dict with valid parameter specification for species
        """
        if species == "Herbivore":
            Herbivore.set_params(params)
        elif species == "Carnivore":
            Carnivore.set_params(params)
        else:
            raise ValueError(
                "species needs to be either Herbivore or Carnivore!")
    def test_sorted_herbivores_and_carnivores(self, highland_cell):
        """
        :method: LandscapeCell.add_animals
        :method: LandscapeCell.sorted_herbivores
        :method: LandscapeCell.sorted_carnivores
        Check that sorting algorithms sort the lists by fitness
        """
        highland_cell.add_animals([Herbivore(weight=50), Herbivore(weight=20)])
        highland_cell.add_animals([Carnivore(weight=25), Carnivore(weight=40)])
        sorted_herbivores = list(
            [herb[0] for herb in highland_cell.sorted_herbivores])
        sorted_carnivores = highland_cell.sorted_carnivores

        assert sorted_herbivores == highland_cell.herbivores[::-1]
        assert sorted_carnivores == highland_cell.carnivores[::-1]
    def place_animals(self, listof):
        """
        Places animal objects in cell. Information of animal type is provided by the input.
        Raises value error if carnivore species is not familias

        Parameters
        ----------
        listof: list of dictionaries
            each dictionary has a structure like: (example)
            {'species': 'Carnivore', 'age': 5, 'weight': 20}

        """
        for dct in listof:
            get = dct.get("species")
            if get == 'Herbivore':
                age = dct.get("age")
                weight = dct.get("weight")
                animal = Herbivore(age=age, weight=weight)
                self.herbivores_list.append(animal)

            elif get == 'Carnivore':
                age = dct.get("age")
                weight = dct.get("weight")
                animal = Carnivore(age=age, weight=weight)
                self.carnivores_list.append(animal)
            else:
                if get is not None:
                    raise ValueError('Cant place animals rather than herbivore or carnivore')
 def test_carn_eat(self, mocker):
     """
     Firstly: To test if the carnivore has the right to eat (first should be able to prey)
     Secondly: To test for the low weight herbivores it takes longer prey list to fulfill their
     appetite
     """
     mocker.patch('numpy.random.random',
                  return_value=0)  # It will definitely prey
     assert len(self.animal[1].eat(self.herb_list)) is not 0
     herb_list_low = []
     herb_list_high = []
     for _ in range(20):
         herb_list_low.append(Herbivore(weight=5))
         herb_list_high.append(Herbivore(weight=10))
     carn = Carnivore(weight=20)
     assert len(carn.eat(herb_list_low)) > len(carn.eat(herb_list_high))
 def test_constructor(self):
     """
     Animals can be created
     """
     herb = Herbivore(weight=10, age=0)
     carn = Carnivore()
     assert isinstance(herb, Herbivore), isinstance(carn, Carnivore)
 def create_animal(self):
     """
     Create animal object
     """
     self.animal = [Herbivore(), Carnivore()]
     self.herb_list = [self.animal[0]]
     self.init_weight = []
Exemple #16
0
    def add_population(self, population):
        """Add a population to specific `island` cells by providing a list of dictionaries.

        :param population: List of dictionaries specifying population

        :Example:
            .. code-block:: python

                 example_pop = {
                    'loc': (4,4),
                    'pop': [
                        {'species': 'Herbivore', 'age': 2, 'weight': 60},
                        {'species': 'Herbivore', 'age': 9, 'weight': 30},
                        {'species': 'Herbivore', 'age': 16, 'weight': 14}
                    ]
                 }
        """
        if type(population) == list:
            for loc_dict in population:  # This loop will be replaced with a more elegant iteration
                new_animals = [
                    Herbivore.from_dict(animal_dict) if animal_dict["species"]
                    == "Herbivore" else Carnivore.from_dict(animal_dict)
                    for animal_dict in loc_dict["pop"]
                ]
                self._island.landscape[loc_dict["loc"]].add_animals(
                    new_animals)
                self._island.count_animals(animal_list=new_animals)
        else:
            raise ValueError(
                f"Pop list needs to be a list of dicts! Was of type "
                f"{type(population)}.")
Exemple #17
0
    def procreation(self, cell):
        """Iterates through each animal in the cell and procreates.

        :param cell: Current cell object
        :type cell: object
        """
        new_herbs = []
        new_carns = []
        n_herbs, n_carns = cell.herb_count, cell.carn_count

        for herb in cell.herbivores:  # Herbivores give birth)
            give_birth, birth_weight = herb.give_birth(n_herbs)

            if give_birth:
                new_herbs.append(Herbivore(weight=birth_weight, age=0))

        for carn in cell.carnivores:  # Carnivores give birth
            give_birth, birth_weight = carn.give_birth(n_carns)

            if give_birth:
                new_carns.append(Carnivore(weight=birth_weight, age=0))

        cell.add_animals(new_herbs + new_carns)  # Add new animals to cell

        self._island.count_animals(num_herbs=len(new_herbs),
                                   num_carns=len(new_carns))
 def test_set_invalid_params(self, reset_herbivore_params):
     """
     Test errors with illegal keys and values
     """
     with pytest.raises(KeyError):
         assert Herbivore.p["w_death"]
     with pytest.raises(ValueError):
         assert Herbivore.set_params({"sigma_birth": -5})
 def place_animals_in_list(self, list_of_diction):
     for animal in list_of_diction:
         if animal['species'] == "Herbivore":
             self._herb_list.append(
                 Herbivore(age=animal['age'], weight=animal['weight']))
         if animal['species'] == "Carnivore":
             self._carn_list.append(
                 Carnivore(age=animal['age'], weight=animal['weight']))
    def animals(self):
        """
        create animals of different type, age and weight to use in test of fitness
        """

        animals = [
            Herbivore(age=0, weight=5),
            Herbivore(age=0, weight=1000),
            Herbivore(age=100, weight=5),
            Herbivore(age=100, weight=1000),
            Herbivore(age=0, weight=5),
            Carnivore(age=0, weight=5),
            Carnivore(age=0, weight=1000),
            Carnivore(age=100, weight=5),
            Carnivore(age=100, weight=1000)
        ]
        return animals
    def test_mean_birth_weight(self, birth_dict, reset_herbivore_params):
        """ Test that the birth weight of animals are normal distributed using the normaltest
        from scipy.
        https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.normaltest.html

        Null hypothesis: The birth weight of the animal is normally distributed
        Alternative hypothesis: The birth weight are not normally distributed.

        We keep the null hypothesis if the p-value is larger than the significance level alpha
        """
        random.seed(123)
        N = 1000
        Herbivore.set_params(birth_dict)
        herb_birth_weights = [
            Herbivore(age=5, weight=20).birth_weight for _ in range(N)
        ]
        k2, phi = stats.normaltest(herb_birth_weights)
        assert phi > TestAnimal.alpha
 def test_animal_fitness(self, biosim):
     """
     :property: Island.animal_fitness
     Test that animal fitness property is of correct shape and value
     """
     fixed_herb_fitness = Herbivore(weight=20, age=5).fitness
     fixed_carn_fitness = Carnivore(weight=25, age=4).fitness
     assert biosim._island.animal_fitness == [[
         fixed_herb_fitness, fixed_herb_fitness, fixed_herb_fitness
     ], [fixed_carn_fitness, fixed_carn_fitness]]
 def test_shuffle_herbs(self, highland_cell):
     """
     :method: LandscapeCell.add_animals
     :method: LandscapeCell.randomize_herbs
     Test that shuffle method shuffles herbivores list
     """
     highland_cell.add_animals([Herbivore() for _ in range(1000)])
     original_herbs = [animal for animal in highland_cell.herbivores]
     highland_cell.randomize_herbs()
     assert highland_cell.herbivores != original_herbs
 def test_count_del_animals(self, island):
     """
     :method: Island.count_animals
     :method: Island.del_animals
     Test counting and removing animals with lists passed and arguments only
     """
     island.count_animals(num_herbs=10, num_carns=10)
     island.del_animals(animal_list=[Herbivore()])
     island.del_animals(num_herbs=5, num_carns=5)
     assert island.num_animals == 9
     assert island.num_herbs == 4
     assert island.num_carns == 5
 def test_kill_prey(self):
     """
     Test kill prey. With a high fitness diff the carnivore will always kill the herbivore.
     """
     carn = Carnivore(age=5, weight=30)
     herb_list = [Herbivore(age=100, weight=50) for _ in range(100)]
     mock_sorted_list = [(herb, herb.fitness) for herb in herb_list]
     kill_count = 0
     for _ in mock_sorted_list:
         if carn.kill_prey(mock_sorted_list):
             kill_count += 1
     assert kill_count == 100
 def test_reset_animals(self, highland_cell):
     """
     :method: LandscapeCell.add_animal
     :method: LandscapeCell.reset_animals
     :property: LandscapeCell.carnivores
     :property: LandscapeCell.has_moved
     Test that has_moved property is correctly set and reset
     """
     highland_cell.add_animals([Carnivore(), Herbivore()])
     highland_cell.carnivores[0].has_moved = True
     highland_cell.reset_animals()
     assert highland_cell.carnivores[0].has_moved is False
 def test_mother_weight_condition(self, mocker):
     """
     To test if the mother gives birth to the child and its weight decreases by a certain
     amount, the child should not be born and the mother's weight must remain unchanged
     """
     animal_low_weight = [Herbivore(weight=0.5), Carnivore(weight=0.5)]
     # herbivore and carnivore with enough low weight
     for animal in animal_low_weight:
         mocker.patch('numpy.random.random',
                      return_value=0)  # To be sure the create_newborn
         # is None due to the weight of mother not the probability
         assert animal.create_newborn(2) is None
 def test_single_procreation(self):
     """
     test that the initial herbivore population will not reproduce a newborn population of
     greater numbers during a year cycle. Each mother can at most give birth to one animal.
     A high fitness and gamma parameter ensures highly fertile animals.
     """
     num_newborns = 0
     adult_herbs = [Herbivore(age=5, weight=40) for _ in range(100)]
     num_adults = len(adult_herbs)
     for herb in adult_herbs:
         herb.set_params(({"gamma": 0.99}))
         if herb.give_birth(num_adults):
             num_newborns += 1
     assert num_newborns <= num_adults
    def test_give_birth(self, gamma_dict, reset_herbivore_params):
        """Test that for animals with fitness close to one, and two animals of same type one specie
        in a cell. The give_birth function should be well approximated by the parameter gamma.
        An we test this against our function under the significance level alpha.

        Null hypothesis: The give_birth function returns correct with fixed gamma
        Alternative hypothesis: The give_birth function does not return correct. We reject our
        null hypothesis.
        """

        random.seed(123)
        N = 1000
        Herbivore.set_params(gamma_dict)
        num_herbs = 2
        p = gamma_dict["gamma"]
        list_birth = [
            Herbivore(weight=200, age=5).give_birth(num_herbs)
            for _ in range(N)
        ]
        # number when births return True
        n = sum([item[0] for item in list_birth])
        mean = N * p
        assert phi_z_test(N, p, n) > TestAnimal.alpha
 def test_weight_gain(self, reset_carnivore_params, reset_herbivore_params,
                      params):
     """
     Testing weight gain of carnivores. Assuming they have access to more fodder than they
     will eat. Making old heavy herbivores with low fitness. Carnivores should add beta * F
     weight
     Assuming fitness diff is larger than DeltaPhiMax such that the carnivore always kills
     the herbivore.
     """
     carn = Carnivore(age=5, weight=40)
     # number of herbivores
     N = 1000
     herb_list = [Herbivore(age=100, weight=200) for _ in range(N)]
     mock_sorted_list = [(herb, herb.fitness) for herb in herb_list]
     initial_weight = carn.weight
     _ = carn.kill_prey(mock_sorted_list)
     new_weight = carn.weight
     assert new_weight == initial_weight + carn.p["beta"] * carn.p["F"]