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 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 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 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 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 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)}.")
def create_animal(self): """ Create animal object """ self.animal = [Herbivore(), Carnivore()] self.herb_list = [self.animal[0]] self.init_weight = []
def test_constructor(self): """ Animals can be created """ herb = Herbivore(weight=10, age=0) carn = Carnivore() assert isinstance(herb, Herbivore), isinstance(carn, Carnivore)
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 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 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 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"]
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_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_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_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_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
def test_death(self, mocker): """ Firstly: To test if the animal dies when its weight is less / equal to zero Secondly: Since there's a reverse relationship between death and fitness, animals with higher fitness should have lower probability to die. Existence of this relationship is being tested here """ animal_zero_weight = [Herbivore(weight=0), Carnivore(weight=0)] die_low_weight = [] die_high_weight = [] sum_die_low_weight = [] sum_die_high_weight = [] self.animal[1].eat( self.herb_list) # Feeding the carnivore for one time self.animal[0].eat() # Feeding the herbivore for one time for species in range(2): assert animal_zero_weight[species].is_dying() is True for _ in range(500): for _ in range(100): die_low_weight.append(self.animal[species].is_dying()) sum_die_low_weight.append(sum(die_low_weight)) for _ in range( 50 ): # Feeding animals for 50 times leading to fitness increment self.animal[1].eat(self.herb_list) self.animal[0].eat() for _ in range(500): for _ in range(100): die_high_weight.append(self.animal[species].is_dying()) sum_die_high_weight.append(sum(die_high_weight)) contingency_table = np.array([sum_die_high_weight, sum_die_low_weight]) chi2_stat, p_val, dof, ex = stats.chi2_contingency(contingency_table) assert p_val < ALPHA
def test_calculate_fitness(self): """ Firstly: To test if the weight is 0 the fitness would be also zero Secondly: To see if the fitness is a number between 0 and 1 Thirdly: To see if the fitness increases by increment in weight Lastly: If the fitness decreases by aging """ animal_zero_weight = [Herbivore(weight=0), Carnivore(weight=0)] for species in range(2): assert animal_zero_weight[species].calculate_fitness() == 0 for species in range(2): assert 0 < self.animal[species].calculate_fitness() < 1 fitness_before_weighting = self.animal[species].calculate_fitness() self.animal[1].eat(self.herb_list) # Feeding the carnivore self.animal[0].eat() # Feeding the herbivore fitness_after_weighting_but_before_aging = self.animal[ species].calculate_fitness() if self.animal[1].check_carn_prey( self.animal[0].calculate_fitness(), self.animal[1].calculate_fitness()): assert fitness_after_weighting_but_before_aging - fitness_before_weighting > 0 self.animal[species].grow_older() # aging the animals fitness_after_aging = self.animal[species].calculate_fitness() assert fitness_after_aging - fitness_after_weighting_but_before_aging < 0
def carnivore(self): return Carnivore()
def test_constructor(self): """ Test carnivores can be constructed """ carn = Carnivore() assert isinstance(carn, Carnivore)
def test_parameters(self, reset_herbivore_params, reset_carnivore_params): """ Test parameters of herbs and carns """ herb, carn = Herbivore(), Carnivore() assert herb.p != carn.p
def reset_carnivore_params(): """ Set parameters of carnivores back to defaults """ yield Carnivore.set_params(Carnivore.p)
def set_animal_parameters(self, species, params): if species == "Herbivore": Herbivore.set_parameters(params) elif species == "Carnivore": Carnivore.set_parameters(params)