Answered step by step
Verified Expert Solution
Question
1 Approved Answer
Hi :) i need to write a test code to this class. import math import random class Animal: # These parameters are defined at the
Hi :) i need to write a test code to this class.
import math import random class Animal: # These parameters are defined at the class level w_birth = 0 sigma_birth = 0 beta = 0 eta = 0 phi_age = 0 w_half = 0 phi_weight = 0 mu = 0 gamma = 0 xi = 0 omega = 0 F = 0 DeltaPhiMax = 0 a_half = 0 zeta = 0 default_params = {'w_birth': w_birth, 'sigma_birth': sigma_birth, 'beta': beta, 'eta': eta, 'a_half': a_half, 'zeta': zeta, 'phi_age': phi_age, 'w_half': w_half, 'phi_weight': phi_weight, 'mu': mu, 'gamma': gamma, 'xi': xi, 'omega': omega, 'F': F} def __init__(self, age=None, weight=None): """Create animal with given age and weight""" self.a = 0 if age is None else age self.w = random.gauss(self.w_birth, self.sigma_birth) if weight is None else weight self.phi = None self.fitness() self.migrated = False self.given_birth_this_year = False @classmethod def set_params(cls, new_params): """ Set class parameters. Parameters ---------- new_params : dict Legal keys: ['w_birth', 'sigma_birth', 'beta', 'eta', 'a_half', 'zeta', 'phi_age', 'w_half', 'phi_weight', 'mu', 'gamma', 'xi', 'omega', 'F', 'DeltaPhiMax'] Raises ------ ValueError, KeyError """ for key in new_params: if key not in cls.default_params.keys(): raise KeyError('Invalid parameter name: ' + key) if not all(value >= 0 for value in new_params.values()): raise ValueError('All values must be positive') if 'DeltaPhiMax' in new_params: if not 0 < new_params['DeltaPhiMax']: raise ValueError('DeltaPhiMax must be strictly positive (>0).') cls.DeltaPhiMax = new_params['DeltaPhiMax'] if 'eta' in new_params: if not 0 <= new_params['eta'] <= 1: raise ValueError('eta must be in [0, 1].') cls.eta = new_params['eta'] if 'w_birth' in new_params: cls.w_birth = new_params['w_birth'] if 'sigma_birth' in new_params: cls.sigma_birth = new_params['sigma_birth'] if 'beta' in new_params: cls.beta = new_params['beta'] if 'a_half' in new_params: cls.a_half = new_params['a_half'] if 'zeta' in new_params: cls.zeta = new_params['zeta'] if 'phi_age' in new_params: cls.phi_age = new_params['phi_age'] if 'w_half' in new_params: cls.w_half = new_params['w_half'] if 'phi_weight' in new_params: cls.phi_weight = new_params['phi_weight'] if 'mu' in new_params: cls.mu = new_params['mu'] if 'gamma' in new_params: cls.a_half = new_params['gamma'] if 'xi' in new_params: cls.xi = new_params['xi'] if 'omega' in new_params: cls.omega = new_params['omega'] if 'F' in new_params: cls.F = new_params['F'] @classmethod def get_params(cls): """ Get class parameters. Returns ------- dict Dictionary with class parameters. """ return cls.default_params def fitness(self): """Calculate the fitness of the animal.""" if self.w <= 0: fitness = 0 e_plus = math.exp(self.phi_age * (self.a - self.a_half)) e_minus = math.exp(-self.phi_weight * (self.w - self.w_half)) q_plus = 1 / (1 + e_plus) q_minus = 1 / (1 + e_minus) fitness = q_plus * q_minus if not 0 <= fitness <= 1: raise ValueError('fitness must be in [0, 1].') self.phi = fitness def migrate(self): """ Decide whether an animal migrates. Returns ------- bool True if animal migrates. """ p_migrate = self.mu * self.phi migrate_bool = random.random() < p_migrate self.migrated = True if migrate_bool else False return migrate_bool def ages(self): """Animal ages by one cycle.""" self.a += 1 def dies(self): """ Decide whether an animal dies. Returns ------- bool True if animal dies. """ if self.w == 0: p_death = 0 else: p_death = self.omega * (1 - self.phi) return random.random() < p_death def gives_birth(self, num_animals): """ Decide whether an animal gives birth. Parameters ---------- num_animals : int (number of animals of same species in the cell) Returns ------- bool True if animal gives birth. """ p_birth = 0 if num_animals >= 2: if self.given_birth_this_year or \ self.w < (self.zeta * (self.w_birth + self.sigma_birth)): p_birth = 0 else: p_birth = min(1, (self.gamma * self.phi * (num_animals - 1))) return random.random() < p_birth def newborn(self): """ Newborn is born if mother does not lose certain amount of weight at birth Returns ------- newborn animal instance of Herbivore or Carnivore newborn """ child = self.__class__() weight_loss_at_birth = self.xi * child.w if self.w > weight_loss_at_birth: self.w -= weight_loss_at_birth self.given_birth_this_year = True self.fitness() return child def eat(self, fodder): """Weight gain of animal on eating fodder""" self.w += self.beta * fodder self.fitness() # reevaluate fitness def wt_loss(self): """Yearly weight loss of an animal""" self.w -= self.eta * self.w self.fitness() # reevaluate fitness class Herbivore(Animal): w_birth = 8.0 sigma_birth = 1.5 beta = 0.9 eta = 0.05 phi_age = 0.6 w_half = 10.0 phi_weight = 0.1 mu = 0.25 gamma = 0.2 xi = 1.2 omega = 0.4 F = 10.0 a_half = 40.0 zeta = 3.5 def __init__(self, age=None, weight=None): super().__init__(age, weight) def eat(self, fodder_available): """ Herbivore eats from the fodder available :param fodder_available: remaining fodder available in the cell :return: """ if fodder_available > 0: fodder_to_eat = fodder_available if fodder_available < self.F else self.F super().eat(fodder_to_eat) class Carnivore(Animal): w_birth = 6.0 sigma_birth = 1.0 beta = 0.75 eta = 0.125 phi_age = 0.3 w_half = 4.0 phi_weight = 0.4 mu = 0.4 gamma = 0.8 xi = 1.1 omega = 0.8 F = 50.0 DeltaPhiMax = 10.0 a_half = 40.0 zeta = 3.5 default_params = {'w_birth': w_birth, 'sigma_birth': sigma_birth, 'beta': beta, 'eta': eta, 'a_half': a_half, 'zeta': zeta, 'phi_age': phi_age, 'w_half': w_half, 'phi_weight': phi_weight, 'mu': mu, 'gamma': gamma, 'xi': xi, 'omega': omega, 'F': F, 'DeltaPhiMax': DeltaPhiMax} def __init__(self, age=None, weight=None): super().__init__(age, weight) def eat(self, h_pop): """ Carnivore decides if he wants to eat from the herbivore population in the cell :param h_pop: herbivore population in the cell :return: """ survivors = [] f_eaten = 0 for herb in h_pop: if f_eaten < self.F and self.kill(herb): w_sub = self.F if herb.w > self.F else 0 super().eat(herb.w - w_sub) f_eaten += herb.w else: survivors.append(herb) return survivors def kill(self, herbivore): """ Carnivore decides if he will kill herbivore :param herbivore: :return: """ if self.phi <= herbivore.phi: p_kill = 0 elif 0 < (self.phi - herbivore.phi) < self.DeltaPhiMax: p_kill = (self.phi - herbivore.phi) / self.DeltaPhiMax else: p_kill = 1 return random.random() < p_kill i have tried to do it by my self, and the test code below is the best i have could write.
import random import math import pytest import scipy.stats as stats from biosim.animal import Animal # Overall parameters for probabilistic tests SEED = 12345678 # random seed for tests ALPHA = 0.01 # significance level for statistical tests @pytest.fixture def set_params(request): Animal.set_params(request.param) yield Animal.set_params(Animal.default_params) def test_animal_create(): b = Animal(None) assert b.a == 0 def test_animal_create_weight(): b = Animal(None) assert b.w == random.gauss(self.w_birth, self.sigma_birth) def test_animal_aging(): b = Animal() for n in range(10): b.ages() assert b.a == n + 1 def test_weight_loss(): an = Animal() an.w -= an.eta * an.w assert an.w def test_eat(): an_eat = Animal() an_eat.w -= an_eat.beta * fodder assert an_eat.w @pytest.mark.parametrize('set_params', [{'phi_age': 0.6},{'phi_weight':0.1},{'w_half':10.0},{'a_half':40.0}]) def test_anim_herb_fitness(set_params): b = Animal() for _ in range(100): assert b.fitness() @pytest.mark.parametrize('set_params', [{'mu': 0.25}], indirect=True) def test_anim_herb_migrate(set_params): b = Animal() for _ in range(100): assert b.migrate()
can someone help me to complete the test code, and i also strugling with making code to deth, birth, eat and new born.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started