def test_find_correct_coordinates(self): """ Implements seeding to assert that find_new_coordinates returns correct location for the animal to move to. """ numpy.random.seed(1) test_population_for_coords = [{ "species": "Herbivore", "age": 1, "weight": 10.0 }] test_properties_for_coords = { "species": "Herbivore", "age": 1, "weight": 10 } neighbours_for_coords = { (1, 2): Jungle(test_population_for_coords), (2, 1): Jungle(test_population_for_coords), (2, 3): Jungle(test_population_for_coords), (3, 2): Jungle(test_population_for_coords) } for jungle in neighbours_for_coords.values(): jungle.regrowth() herbivore = Herbivore(test_properties_for_coords) assert herbivore.find_new_coordinates(neighbours_for_coords) == (2, 1)
def test_coordinates_returned_when_animal_will_move_true( self, mocker, example_properties): """ Asserts that a tuple of coordinates is returned from return_new_coordinates if the animal will move because the random number is less than the probability of moving. """ test_population_true = [{ "species": "Herbivore", "age": 1, "weight": 10.0 }] dict_of_neighbours = { (1, 2): Jungle(test_population_true), (2, 1): Jungle(test_population_true), (2, 3): Jungle(test_population_true), (3, 2): Jungle(test_population_true) } for jungle in dict_of_neighbours.values(): jungle.regrowth() herbivore = Herbivore(example_properties) herbivore.fitness = 1 mocker.patch('numpy.random.random', return_value=0.1) new_coordinates = herbivore.return_new_coordinates(dict_of_neighbours) assert type(new_coordinates) == tuple
def create_map_dict(self): """ Iterates through geography dictionary and creates a new dictionary of the entire map. This dict has coordinates as keys and instances of landscape classes as values. Each landscape instance has the population list of it's coordinate as input. :raise ValueError: if invalid landscape type is given in geography string """ self.create_geography_dict() self.create_population_dict() for location, landscape_type in self.geography.items(): if landscape_type is "J": if location in self.population.keys(): self.map[location] = Jungle(self.population[location]) else: self.map[location] = Jungle([]) elif landscape_type is "S": if location in self.population.keys(): self.map[location] = Savannah(self.population[location]) else: self.map[location] = Savannah([]) elif landscape_type is "D": if location in self.population.keys(): self.map[location] = Desert(self.population[location]) else: self.map[location] = Desert([]) elif landscape_type is "O": self.map[location] = Ocean([]) elif landscape_type is "M": self.map[location] = Mountain([]) else: raise ValueError(f"Invalid landscape type {landscape_type}")
def test_meat_for_carnivores(self): jungle = Jungle() jungle.add_animals([{ 'species': 'Herbivore', 'age': 10, 'weight': 100 }]) assert type(jungle.meat_for_carnivores) is float or \ type(jungle.meat_for_carnivores) is int assert jungle.meat_for_carnivores == 100
def test_set_parameters_only_changes_one_class(self, parameters_savanna, default_parameters_savanna): jungle = Jungle() savanna = Savanna() savanna.set_parameters(**parameters_savanna) jungle.set_parameters(f_max=800) assert savanna.f_max == parameters_savanna['f_max'] assert savanna.alpha == parameters_savanna['alpha'] assert jungle.f_max == 800 savanna.set_parameters(**default_parameters_savanna)
def test_correct_rel_abund_fodder_herb(self, example_population, example_properties): """ Checks that find_rel_abund_of_fodder returns correct amount of fodder for herb in Jungle cell. """ jungle = Jungle(example_population) jungle.regrowth() herbivore = Herbivore(example_properties) rel_abund_fodder = herbivore.find_rel_abund_of_fodder(jungle) assert rel_abund_fodder == 20.0
def test_feeding_plenty(self): """ Test for herbivore feeding method with plenty of fodder. Returns ------- """ h1 = Herbivore(age=5, weight=20) j1 = Jungle() h1.feeding(j1) assert h1.weight == 29 assert j1.get_fodder() == 790
def test_migrate_all_animals_all_move(self, jungle, herb_list_big, carn_list_big, tear_down_params): """Test to see that all animals migrate if they deside to migrate. """ j = jungle j.herb_list = herb_list_big j.carn_list = carn_list_big neighbors = (Jungle(), Jungle(), Jungle(), Jungle()) Herb.set_parameters({"mu": 100, "F": 0}) Carn.set_parameters({"mu": 100, "F": 0}) j.migrate_all_animals(neighbors) assert len(j.herb_move_from_list) == 1000 assert len(j.carn_move_from_list) == 1000
def test_add_animals(self, animal_list): jungle = Jungle() jungle.add_animals(animal_list) assert jungle.num_herbivores == 2 assert jungle.num_carnivores == 1 assert jungle.num_animals == len(animal_list) herbivore0 = jungle.herbivores[0] herbivore1 = jungle.herbivores[1] carnivore0 = jungle.carnivores[0] assert herbivore0.age == animal_list[0]['age'] assert herbivore0.weight == animal_list[0]['weight'] assert herbivore1.age == animal_list[1]['age'] assert herbivore1.weight == animal_list[1]['weight'] assert carnivore0.age == animal_list[2]['age'] assert carnivore0.weight == animal_list[2]['weight'] animal_list_with_wrong_parameter = [{ 'species': 'Carnivore', 'age': 0.5, 'weight': 100 }] with pytest.raises(ValueError): jungle.add_animals(animal_list_with_wrong_parameter) animal_list_with_wrong_parameter = [{ 'species': 'Carnivore', 'age': 3, 'weight': -10 }] with pytest.raises(ValueError): jungle.add_animals(animal_list_with_wrong_parameter)
def test_feeding_none(self): """ Test for herbivore feeding method with no fodder. Returns ------- """ h1 = Herbivore(age=5, weight=20) j1 = Jungle() j1.fodder = 0 h1.feeding(j1) assert h1.weight == 20 assert j1.get_fodder() == 0
def build_map(self): """ Builds island based on input string. Island biomes are placed in a two dimensional array """ geography = [ list(row) for row in self.island_map.replace(" ", "").split("\n") ] for row in geography: temp = [] for cell in row: if cell == "J": temp.append(Jungle()) elif cell == "S": temp.append(Savannah()) elif cell == "D": temp.append(Desert()) elif cell == "M": temp.append(Mountain()) elif cell == "O": temp.append(Ocean()) else: raise ValueError('"{}" is not properly defined! ' 'Use capital letters.') self.island_temp.append(temp) self.island = np.array(self.island_temp)
def tear_down_params(self): """ Creates a tear_down fixture that resets the parameters to default for the jungle class instances. """ yield None Jungle().set_default_parameters_for_jungle()
def test_animal_will_move_to_tuple_coordinates(self, example_population, example_properties): """ Asserts that the where_will_animal_move method returns a tuple. """ neighbours_for_tuple = { (1, 2): Jungle(example_population), (2, 1): Jungle(example_population), (2, 3): Jungle(example_population), (3, 2): Jungle(example_population) } for jungle in neighbours_for_tuple.values(): jungle.regrowth() herbivore = Herbivore(example_properties) assert type( herbivore.find_new_coordinates(neighbours_for_tuple)) is tuple
def test_dict_converted_correctly_to_list_and_array( self, example_properties, example_population): """ Asserts that the output from convert_dict_to_list_and_array method are of the correct types. """ herbivore = Herbivore(example_properties) dict_of_neighbours = { (1, 2): Jungle(example_population), (2, 1): Jungle(example_population), (2, 3): Jungle(example_population), (3, 2): Jungle(example_population) } for jungle in dict_of_neighbours.values(): jungle.regrowth() prob_dict = herbivore.prob_move_to_each_neighbour(dict_of_neighbours) locs, probs = herbivore.convert_dict_to_list_and_array(prob_dict) assert type(locs) is list assert type(probs) is numpy.ndarray
def test_correct_rel_abund_fodder_carn(self, example_population_carn, example_properties): """ Checks that find_rel_abund_of_fodder returns correct value for carnivores. """ jungle = Jungle(example_population_carn) carnivore = Carnivore(example_properties) rel_abund_fodder = carnivore.find_rel_abund_of_fodder(jungle) assert rel_abund_fodder == 0.15
def test_feeding_carnivore_fit(self): """ Test for carnivore feeding method, with fit carnivore. Returns ------- """ c1 = Carnivore(1, 3000) # fitness ~= 1 c1.set_parameters({'DeltaPhiMax': 1.00001}) j1 = Jungle() j1.add_herbivore(5,10) j1.herbivores[0].fitness = 0 boolean = c1.feeding(j1.herbivores) c1.set_parameters({'DeltaPhiMax': 10.0}) # default-value assert c1.weight == 3007.5 assert boolean == [False]
def test_correct_types_in_prob_move_dict(self, example_population, example_properties): """ Asserts that the prob_move_to_each_neighbour method returns a dictionary with tuples as keys and floats as values. """ herbivore = Herbivore(example_properties) dict_of_neighbours = { (1, 2): Jungle(example_population), (2, 1): Jungle(example_population), (2, 3): Jungle(example_population), (3, 2): Jungle(example_population) } for jungle in dict_of_neighbours.values(): jungle.regrowth() prob_dict = herbivore.prob_move_to_each_neighbour(dict_of_neighbours) assert type(prob_dict) is dict for loc, prob in prob_dict.items(): assert type(loc) is tuple assert type(prob) is float
def test_feeding_carnivore_appetite(self): """ Test for a fit carnivore's feeding method, with low appetite. Returns ------- """ c1 = Carnivore(1, 20) c1.fitness = 1 c1.set_parameters({'DeltaPhiMax': 1.00001, 'F': 10.0}) j1 = Jungle() j1.add_herbivore(5,20) j1.herbivores[0].fitness = 0 boolean = c1.feeding(j1.herbivores) c1.set_parameters({'DeltaPhiMax': 10.0, 'F': 50.0}) # default-value assert c1.weight == 27.5 assert boolean == [False]
def test_migrate_all_animals_equal_prob(self, jungle, herb_list_big, carn_list_big, tear_down_params): """ Test to see that animal is equally likely to migrate to any square if move propensity is equal for all squares. """ j = jungle j.herb_list = herb_list_big j.carn_list = carn_list_big neighbors = (Jungle(), Jungle(), Jungle(), Jungle()) Herb.set_parameters({"mu": 100, "F": 0}) Carn.set_parameters({"mu": 100, "F": 0}) j.migrate_all_animals(neighbors) num_moved = np.array(( len(neighbors[0].herb_move_to_list), len(neighbors[1].herb_move_to_list), len(neighbors[2].herb_move_to_list), len(neighbors[3].herb_move_to_list), )) num_expected = np.array((250, 250, 250, 250)) _, pvalue = chisquare(num_moved, num_expected) assert pvalue > 0.001
def landscape_data(self, animal_objects): carn1, carn2, herb1, herb2 = animal_objects animals = {'Herbivore': [herb1, herb2], 'Carnivore': [carn1, carn2]} landscapes_dict = { 'S': Savannah(), 'O': Ocean(), 'D': Desert(), 'M': Mountain(), 'J': Jungle() } for species, animals in animals.items(): for animal in animals: landscapes_dict['S'].add_animal(animal) landscapes_dict['D'].add_animal(animal) landscapes_dict['J'].add_animal(animal) return landscapes_dict
def test_chi2_pval_square_random_select(self): """Test to see that self.square_random_select chooses squares with the correct probability""" def event_frequencies(p, num_events): event_count = np.zeros_like(p) for _ in range(num_events): event = j.square_random_select(p) event_count[event] += 1 return event_count j = Jungle() p = np.array((0.1, 0.4, 0.3, 0.2)) num_events = 10000 num_expected = num_events * p num_observed = event_frequencies(p, num_events) _, p_value = chisquare(num_observed, num_expected) assert p_value > 0.001
def array_to_island(self): """ Converts the array from the method string_to_array into a island. changes the array consisting of strings into an array consisting of instances of classes depedning on the letter that was previously in the array, for example 'J' would turn into an instance of the Jungle-class. These are stored in Island.cells Returns ------- Raises ------ SyntaxError If self.map contain other letters than 'J', 'S', 'D', 'O', 'M'. """ array_map = self.string_to_array() array_shape = np.shape(array_map) # type: tuple nested = list(np.zeros(array_shape)) for i, e in enumerate(nested): nested[i] = list(e) for i in range(array_shape[0]): for j in range(array_shape[1]): if array_map[i, j] == 'J': nested[i][j] = Jungle() elif array_map[i, j] == 'S': nested[i][j] = Savannah() elif array_map[i, j] == 'D': nested[i][j] = Desert() elif array_map[i, j] == 'O': nested[i][j] = Ocean() elif array_map[i, j] == 'M': nested[i][j] = Mountain() else: raise SyntaxError("Island geography multi-line string " "must only have these letters: " "'J', 'S', 'D', 'O', 'M'") self.cells = np.array(nested)
def test_propensity(self): jungle = Jungle() jungle.add_migrated_herb(Herbivore()) jungle.add_migrated_carn(Carnivore()) lambda_herb = Herbivore.lambda_ epsilon_herb = jungle.fodder / (2 * Herbivore.F) propensity_herbivore = math.exp(lambda_herb * epsilon_herb) lambda_carn = Carnivore.lambda_ epsilon_carn = jungle.meat_for_carnivores / (2 * Carnivore.F) propensity_carnivore = math.exp(lambda_carn * epsilon_carn) propensity = jungle.propensity assert propensity['Herbivore'] == propensity_herbivore assert propensity['Carnivore'] == propensity_carnivore
def test_feed_herbivore(self, animal_list): test_jungle = Jungle() test_jungle.herbivores.append(Herbivore(5, 40)) test_jungle.herbivores.append(Herbivore(50, 4)) test_jungle.herbivores = (test_jungle.sort_by_fitness( test_jungle.herbivores)) test_jungle.fodder = 15 a_weight = test_jungle.herbivores[0].weight b_weight = test_jungle.herbivores[1].weight # herbivore F is 10 and beta is 0.9 # b will eat 10 and gain 10*0.9 weight # a will eat 5 and gain 5*0.9 weight a, b = test_jungle.herbivores test_jungle.feed_herbivores() assert test_jungle.fodder == 0 # b will be last because its fitness will be higher assert b.weight == b_weight + 10 * 0.9 assert a.weight == a_weight + 5 * 0.9
def test_constructor_jungle(self): """ Asserts that class instance has been initialized with no fodder available. """ test_pop_jungle = [{ "species": "Herbivore", "age": 1, "weight": 10.0 }, { "species": "Herbivore", "age": 3, "weight": 50.0 }, { "species": "Herbivore", "age": 5, "weight": 20.0 }] jungle = Jungle(test_pop_jungle) assert jungle.fodder_amount == 0
def test_die(self, jungle_many_animals, carnivore_list): num_animals = jungle_many_animals.num_animals jungle_many_animals.die() assert num_animals > jungle_many_animals.num_animals jungle = Jungle() jungle.add_animals(carnivore_list) carnivore0 = jungle.carnivores[0] carnivore0._fitness = 0 carnivore0._compute_fitness = False carnivore1 = jungle.carnivores[1] carnivore1._fitness = 1 carnivore1._compute_fitness = False jungle.die() assert carnivore0 not in jungle.carnivores assert carnivore1 in jungle.carnivores
'age': 5, 'weight': 20 } for _ in range(150)] }] ini_carns = [{ 'loc': (10, 10), 'pop': [{ 'species': 'Carnivore', 'age': 5, 'weight': 20 } for _ in range(40)] }] animals.Herbivore.set_parameters({'zeta': 3.2, 'xi': 1.8}) animals.Carnivore.set_parameters({ 'a_half': 70, 'phi_age': 0.5, 'omega': 0.3, 'F': 65, 'DeltaPhiMax': 9. }) Jungle.set_parameters({'f_max': 700}) sim = BioSim(island_map=geogr, ini_pop=ini_herbs, seed=123456) sim.simulate(num_steps=100, vis_steps=1, img_steps=2000) sim.add_population(population=ini_carns) sim.simulate(num_steps=100, vis_steps=1, img_steps=2000) input('Press ENTER')
def jungle(self): """Creates a fixture of a jungle class instance. """ return Jungle()
def test_grow(self): jungle = Jungle() jungle.fodder = 0 jungle.grow() assert jungle.fodder == Jungle.f_max
def test_init(self): jungle = Jungle() assert type(jungle.herbivores) is list assert type(jungle.carnivores) is list assert jungle.fodder == Jungle.f_max