from otree.api import * import random import numpy as np from scipy.stats import bernoulli doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'experiment' players_per_group = None num_rounds = 6 end = 100 cows = 10 fixed = 7 q = 2 P = 7 Psone = 3 Pstwo = 8 Psthree = 5 Psfour = 9 sale_vacc = 5 sale_nvacc = 2 exp = 4 Mt = 6 Sickness = 5 rp = np.round(np.random.uniform(0, 1, 6),1) class Group(BaseGroup): pass class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): import csv with open('data/pre_assigned.csv') as f: rows = list(csv.DictReader(f)) players = subsession.get_players() for i in range(len(players)): row = rows[i] player = players[i] print(row) player.part_id = row['part_id'] player.treatment_A = bool(int(row['treatment_A'])) player.treatment_B = bool(int(row['treatment_B'])) player.treatment_C = bool(int(row['treatment_C'])) player.treatment_D = bool(int(row['treatment_D'])) class Player(BasePlayer): treatment_A = models.BooleanField(label="complete ownership of assets and complete control over flow of income") treatment_B = models.BooleanField(label="no ownership of assets and complete control over flow of income ") treatment_C = models.BooleanField(label="ownership of assets and no complete control over flow of income") treatment_D = models.BooleanField(label="no ownership of assets and no complete control over flow of income") part_id = models.StringField() Cows_vacc = models.FloatField(label="How many cows do you want to vaccinate?", min=0, max=10) herd_size_round_start = models.FloatField(label=None, initial=10) Cows_sold_vacc = models.FloatField(label="How many of the vaccinated animals do you want to sell?", min=0) Cows_sold_nvacc = models.FloatField(label="How many of the non vaccinated animals do you want to sell?", min=0, max=10) Cows_sold = Cows_sold_nvacc + Cows_sold_nvacc vacc_lost = models.FloatField(label=None, initial=0) nvacc_lost = models.FloatField(label=None, initial=0) why = models.StringField() payoff_round_start = models.CurrencyField( initial=100 ) available_round_start = models.FloatField( initial=10 ) available_vacc_round_start = models.FloatField( initial=10 ) available_nvacc_round_start = models.FloatField( initial=0 ) rp = models.FloatField() pr = models.FloatField() variable = models.IntegerField() vacc_cost = models.IntegerField() a_vacc = models.FloatField(min=0) a_nvacc = models.FloatField() animal_lost = models.IntegerField() lost = models.FloatField() sick_real = models.FloatField() def available_herd_vacc(self): self.a_vacc = self.available_vacc_round_start def available_herd_nvacc(self): self.a_nvacc = self.available_nvacc_round_start def herd_size(self): return self.herd_size_round_start def animals_lost(self): self.rp = Constants.rp[self.round_number - 1] self.lost = np.random.uniform(0, self.rp) if self.round_number > 1 and self.lost > 0.5: self.animal_lost = 1 elif self.round_number > 1 and self.lost < 0.5: self.animal_lost = 0 else: self.animal_lost = 0 return self.animal_lost def sickness_realised(self): prev_round = self.round_number - 1 if self.treatment_A == 1 or self.treatment_C == 1: remaining_nvacc = self.a_nvacc - self.Cows_sold_nvacc - self.animals_lost() else: remaining_nvacc = self.a_nvacc - self.animals_lost() self.rp = Constants.rp[self.round_number - 1] self.rp = float(self.rp) self.sick_real = np.random.binomial(n = remaining_nvacc, p = self.rp) return self.sick_real def set_payoff(self): self.pr = random.uniform(0.0, 1.0) self.rp = Constants.rp[self.round_number -1] self.variable = random.randint(1, 3) if self.round_number == 1: self.payoff = self.payoff_round_start - Constants.exp - self.Cows_vacc * Constants.fixed else: self.payoff = self.payoff_round_start - Constants.exp class MyPage(Page): form_model = 'player' form_fields = ['Cows_vacc', 'why'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): rp = Constants.rp[player.round_number -1] rp_nvacc = np.floor(rp * 10) calves = list(np.arange(0, player.herd_size_round_start,1)) return{ 'rp_nvacc': rp_nvacc, 'calves': calves, 'rp':rp } class SellPage(Page): form_model = 'player' form_fields = ['Cows_sold_vacc', 'Cows_sold_nvacc'] @staticmethod def is_displayed(player: Player): return (player.treatment_A == 1) or (player.treatment_C == 1) @staticmethod def vars_for_template(player: Player): prev_round = player.round_number - 1 rp = Constants.rp[player.round_number -1] prev_vacc = player.in_round(prev_round).a_vacc if prev_round >= 1 else 10 player.available_vacc_round_start = prev_vacc player.available_herd_vacc() if player.round_number > 2: avail_vacc = player.a_vacc - player.in_round(prev_round).Cows_sold_vacc elif player.round_number == 2: avail_vacc = player.in_round(prev_round).Cows_vacc - player.in_round(prev_round).Cows_sold_vacc elif player.round_number > 2 and player.in_round(prev_round).a_vacc == 0: avail_vacc = 0 else: avail_vacc = player.Cows_vacc player.in_round(player.round_number).a_vacc = avail_vacc image_range = list(np.arange(0,avail_vacc,1)) prev_nvacc = player.in_round(prev_round).a_nvacc if prev_round >= 1 else 0 player.available_nvacc_round_start = prev_nvacc player.available_herd_nvacc() player.animals_lost() if player.round_number > 2 and player.in_round(prev_round).a_nvacc != 0: avail_nvacc = player.a_nvacc - player.in_round(prev_round).Cows_sold_nvacc - player.in_round(prev_round).animal_lost elif player.round_number == 2 : avail_nvacc = 10 - player.in_round(prev_round).Cows_vacc - player.in_round(prev_round).Cows_sold_nvacc - player.in_round(prev_round).animal_lost elif player.round_number > 2 and player.in_round(prev_round).a_nvacc == 0: avail_nvacc = 0 else: avail_nvacc = 10 - player.in_round(1).Cows_vacc player.in_round(player.round_number).a_nvacc = avail_nvacc image_range_2 = list(np.arange(0, avail_nvacc, 1)) rp_nvacc = np.floor(rp*avail_nvacc) chance = rp * 10 sickness_cost = np.round(Constants.Sickness * avail_nvacc * rp,1) image_range_3 = list(np.arange(0+1, avail_vacc + 1, 1)) vacc_keep = [] for i in image_range_3: vacc_keep_1 = i * Constants.P - i * Constants.Mt / 3 vacc_keep.append(vacc_keep_1) vacc_sell = [] for j in image_range_3: vacc_sell_1 = j * Constants.Psfour vacc_sell.append(vacc_sell_1) zipped_vacc = zip(image_range_3, vacc_keep, vacc_sell) image_range_4 = list(np.arange(0 + 1, avail_nvacc + 1, 1)) nvacc_keep = [] for j in image_range_4: nvacc_keep_1 = np.round(j * Constants.P * (1 - rp) + j * Constants.P * rp - j * Constants.Mt + j * rp * Constants.Sickness) nvacc_keep.append(nvacc_keep_1) nvacc_sell = [] for j in image_range_4: nvacc_sell_1 = j * Constants.Psthree nvacc_sell.append(nvacc_sell_1) zipped = zip(image_range_4, nvacc_keep, nvacc_sell) return { 'avail_vacc': avail_vacc, 'avail_nvacc': avail_nvacc, 'image_range': image_range, 'image_range_2': image_range_2, 'rp':rp, 'rp_nvacc':rp_nvacc, 'sickness_cost': sickness_cost, 'chance': chance, 'vacc_keep': vacc_keep, 'vacc_sell': vacc_sell, 'nvacc_keep': nvacc_keep, 'nvacc_sell': nvacc_sell, 'image_range_3': image_range_3, 'image_range_4': image_range_4, 'zipped_vacc': zipped_vacc, 'zipped_file':zipped } @staticmethod def error_message(player: Player, values): vacc_chosen = values["Cows_sold_vacc"] nvacc_chosen = values["Cows_sold_nvacc"] if vacc_chosen > player.in_round(player.round_number).a_vacc: return "You tried to sell " + str(vacc_chosen) + " vaccinated cows which is more than " + str(player.in_round(player.round_number).a_vacc) if nvacc_chosen > player.in_round(player.round_number).a_nvacc: return "You tried to sell " + str(nvacc_chosen) + " non vaccinated cows which is more than " + str(player.in_round(player.round_number).a_nvacc) class LostBD(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return (player.treatment_B == 1) or (player.treatment_D == 1) @staticmethod def vars_for_template(player: Player): prev_round = player.round_number - 1 rp = Constants.rp[player.round_number - 1] prev_vacc = player.in_round(prev_round).a_vacc if prev_round >= 1 else 10 player.available_vacc_round_start = prev_vacc player.available_herd_vacc() if player.round_number >= 1: avail_vacc = player.in_round(1).Cows_vacc else: avail_vacc = 10 player.in_round(player.round_number).a_vacc = avail_vacc image_range = list(np.arange(0, avail_vacc, 1)) prev_nvacc = player.in_round(prev_round).a_nvacc if prev_round >= 1 else 0 player.available_nvacc_round_start = prev_nvacc player.available_herd_nvacc() if player.round_number > 2 and player.in_round(prev_round).rp > 0.5 and player.in_round( prev_round).a_nvacc != 0: avail_nvacc = player.a_nvacc - 1 elif player.round_number > 2 and player.in_round(prev_round).rp < 0.5 and player.in_round( prev_round).a_nvacc != 0: avail_nvacc = player.a_nvacc elif player.round_number == 2 and player.in_round(prev_round).rp > 0.5: avail_nvacc = 10 - player.in_round(prev_round).Cows_vacc - 1 elif player.round_number == 2 and player.in_round(prev_round).rp < 0.5: avail_nvacc = 10 - player.in_round(prev_round).Cows_vacc elif player.round_number > 2 and player.in_round(prev_round).rp > 0.5 and player.in_round( prev_round).a_nvacc == 0: avail_nvacc = 0 elif player.round_number > 2 and player.in_round(prev_round).rp < 0.5 and player.in_round( prev_round).a_nvacc == 0: avail_nvacc = 0 else: avail_nvacc = 10 - player.Cows_vacc player.in_round(player.round_number).a_nvacc = avail_nvacc image_range_2 = list(np.arange(0, avail_nvacc, 1)) if player.round_number > 1 and player.in_round(prev_round).rp > 0.5: animal_lost = 1 else: animal_lost = 0 rp_nvacc = np.floor(rp * avail_nvacc) sickness_cost = np.round(Constants.Sickness * avail_nvacc * rp, 1) if player.round_number > 1: prev_rp = player.in_round(prev_round).rp else: prev_rp = rp return { 'avail_vacc': avail_vacc, 'avail_nvacc': avail_nvacc, 'image_range': image_range, 'image_range_2': image_range_2, 'animal_lost': animal_lost, 'rp': rp, 'rp_nvacc': rp_nvacc, 'prev_rp': prev_rp, 'sickness_cost': sickness_cost, } class Results(Page): @staticmethod def vars_for_template(player: Player): total_payoff = sum([p.payoff for p in player.in_all_rounds()]) prev_round = player.round_number - 1 prev_payoff = player.in_round(prev_round).payoff if prev_round >= 1 else 100 player.payoff_round_start = prev_payoff player.set_payoff() player.animals_lost() if player.treatment_A == 1 or player.treatment_C == 1: remaining_vacc = player.a_vacc - player.Cows_sold_vacc else: remaining_vacc = player.a_vacc if player.treatment_A == 1 or player.treatment_C == 1: remaining_nvacc = player.a_nvacc - player.Cows_sold_nvacc - player.animal_lost else: remaining_nvacc = player.a_nvacc if player.round_number == 1 and player.treatment_A == 1: sale_revenue = Constants.Psone * player.Cows_sold_nvacc + Constants.Pstwo * player.Cows_sold_vacc elif player.round_number == 1 and player.treatment_C == 1: sale_revenue = Constants.Psone * player.Cows_sold_nvacc + Constants.Pstwo * player.Cows_sold_vacc elif player.round_number > 1 and player.treatment_A == 1: sale_revenue = Constants.Psthree * player.Cows_sold_nvacc + Constants.Psfour * player.Cows_sold_vacc elif player.round_number > 1 and player.treatment_C == 1: sale_revenue = Constants.Psthree * player.Cows_sold_nvacc + Constants.Psfour * player.Cows_sold_vacc else: sale_revenue = 10 milk_revenue = np.round(Constants.P * (remaining_vacc + remaining_nvacc * (player.sickness_realised()/10)),1) sick_realised = player.sickness_realised() image_range_5 = list(np.arange(0, sick_realised, 1)) sickness_exp = sick_realised * Constants.Sickness maintainance_cost = (Constants.Mt/3)* player.a_vacc + Constants.Mt * player.a_nvacc if player.round_number == 1 and player.treatment_A == 1: earning = player.payoff + sale_revenue - maintainance_cost - sickness_exp elif player.round_number > 1 and player.treatment_A == 1: earning = player.payoff + milk_revenue - maintainance_cost - sickness_exp + sale_revenue elif player.round_number == 1 and player.treatment_C == 1: earning = player.payoff + sale_revenue - maintainance_cost - sickness_exp elif player.round_number > 1 and player.treatment_C == 1: earning = player.payoff - maintainance_cost - sickness_exp + sale_revenue elif player.round_number > 1 and player.treatment_B == 1: earning = player.payoff + Constants.P * (player.a_vacc + player.a_nvacc * (1 - player.rp)) -\ (Constants.Mt / 3) * player.a_vacc - Constants.Mt * player.a_nvacc -\ Constants.Sickness * player.rp * player.a_nvacc elif player.round_number > 1 and player.treatment_D == 1: earning = player.payoff - (Constants.Mt / 3) * player.a_vacc - Constants.Mt * player.a_nvacc - \ Constants.Sickness * player.rp * player.a_nvacc else: earning = player.payoff + Constants.q * 10 player.in_round(player.round_number).payoff = earning total_vacc_cost = player.in_round(1).Cows_vacc * Constants.fixed animal_lost = player.animals_lost() return { 'earning': earning, 'total_payoff': total_payoff, 'prev_payoff': prev_payoff, 'remaining_vacc': remaining_vacc, 'remaining_nvacc':remaining_nvacc, 'sale_revenue': sale_revenue, 'milk_revenue': milk_revenue, 'sick_realised':sick_realised, 'animal_lost': animal_lost, 'sickness_exp': sickness_exp, 'maintainance_cost': maintainance_cost, 'total_vacc_cost': total_vacc_cost, 'image_range_5': image_range_5, } page_sequence = [MyPage, SellPage, LostBD, Results]