from otree.api import * import random import numpy as np import time doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'experiment_two' players_per_group = None num_rounds = 6 end = 100 cows = 10 fixed = 10 q = 12 Pmilk = 4 Psone = 170 Pstwo = 150 Psthree = 225 Psfour = 205 sale_vacc = 225 sale_nvacc = 205 exp = 40 Mt = 9 Sickness = 20 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/stratified_revised1.csv') as f: rows = list(csv.DictReader(f)) # Extract mother_names from the CSV and store in session.vars mother_names = [row['mother_name'] for row in rows] subsession.session.vars['mother_names'] = mother_names players = subsession.get_players() for i in range(len(players)): row = rows[i] player = players[i] print(row) player.treat_A = bool(int(row['treat_A'])) player.treat_B = bool(int(row['treat_B'])) player.treat_C = bool(int(row['treat_C'])) class Player(BasePlayer): treat_A = models.BooleanField(label="complete ownership of assets and complete control over flow of income") treat_B = models.BooleanField(label="no ownership of assets and complete control over flow of income ") treat_C = models.BooleanField(label="ownership of assets and no complete control over flow of income") mother_name = models.StringField(label= "Name of the participant.") household_id = models.StringField() hhead_gndr = models.BooleanField(label="Who is the head of the family.", choices=[ "Male", "Female" ], widget=widgets.RadioSelect ) asset_owner = models.BooleanField(label="Who has complete ownership of the assets?", choices=[ "Male", "Female" ], widget=widgets.RadioSelect ) income_controller = models.BooleanField(label="Who has complete control over the flow of income?", choices=[ "Male", "Female" ], widget=widgets.RadioSelect ) 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) 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 ) why = models.StringField(label= 'If the answer to the above question is 0, record why otherwise write NA') rp = models.FloatField() a_vacc = models.FloatField(min=0) a_nvacc = models.FloatField() remaining_nvacc = models.FloatField() animal_lost = models.IntegerField() sick_real = models.FloatField() vacc_mv_fwd = models.FloatField() nvacc_post_sell = models.FloatField() nvacc_mv_fwd = models.FloatField() time_spent_mypage = models.IntegerField() time_spent_results = models.IntegerField() time_spent_resultsnew = models.IntegerField() time_spent_sellpage = models.IntegerField() 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 remain_nvacc(self): return self.remaining_nvacc def sick_realisation(self): self.rp = Constants.rp[self.round_number - 1] n_post_sell = self.nonvaccinated_post_sell() if self.treat_A == 1 or self.treat_C == 1: self.sick_real = np.random.binomial(n = n_post_sell, p = self.rp) else: self.sick_real = np.random.binomial(n = n_post_sell , p = self.rp) return self.sick_real def lost(self): self.rp = Constants.rp[self.round_number - 1] sick_real = self.sick_realisation() animal_dies = np.random.binomial(n=sick_real, p=self.rp) # self.animal_lost = np.random.binomial(n = sick_real, p = self.rp) if self.sick_real < animal_dies: self.animal_lost = 0 else: self.animal_lost = animal_dies return self.animal_lost def vaccinated_mv_fwd(self): if self.treat_A == 1 or self.treat_C ==1: self.vacc_mv_fwd = self.a_vacc - self.Cows_sold_vacc else: self.vacc_mv_fwd = self.a_vacc return self.vacc_mv_fwd def nonvaccinated_post_sell(self): prev_round = self.round_number - 1 if self.treat_A == 1 or self.treat_C ==1: self.nvacc_post_sell = self.a_nvacc - self.Cows_sold_nvacc elif self.treat_B == 1 and self.round_number == 1: self.nvacc_post_sell = 10 - self.in_round(1).Cows_vacc elif self.treat_B and self.round_number > 1: self.nvacc_post_sell = self.in_round(prev_round).a_nvacc - self.in_round(prev_round).animal_lost else: self.nvacc_post_sell = self.a_nvacc return self.nvacc_post_sell def set_payoff(self): self.rp = Constants.rp[self.round_number -1] 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)) player.participant.vars['start_time'] = int(time.time()) return{ 'rp_nvacc': rp_nvacc, 'calves': calves, 'rp':rp } @staticmethod def before_next_page(player, timeout_happened): end_time = int(time.time()) start_time = player.participant.vars['start_time'] player.time_spent_mypage = end_time - start_time class SellPage(Page): form_model = 'player' form_fields = ['Cows_sold_vacc', 'Cows_sold_nvacc'] @staticmethod def is_displayed(player: Player): return (player.treat_A == 1) or (player.treat_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)) player.available_herd_nvacc() if player.round_number == 1: avail_nvacc = 10 - player.Cows_vacc #sick_real = player.sick_realisation() #died = np.random.binomial(n = sick_real, p = rp) # remaining_nvacc = avail_nvacc - player.in_round(1).Cows_vacc - player.in_round(player.round_number).Cows_sold_nvacc - died else: avail_nvacc = player.in_round(prev_round).a_nvacc -player.in_round(prev_round).Cows_sold_nvacc - player.in_round(prev_round).animal_lost #sick_real = player.sick_realisation() #died = np.random.binomial(n=sick_real, p=rp) # remaining_nvacc = player.in_round(player.round_number).a_nvacc - player.in_round(player.round_number).Cows_sold_nvacc - died if player.round_number > 1 and player.in_round(prev_round).a_nvacc == 0: avail_nvacc = 0 player.in_round(player.round_number).a_nvacc = avail_nvacc #player.in_round(player.round_number).remaining_nvacc = remaining_nvacc #player.in_round(player.round_number).animal_lost = died image_range_2 = list(np.arange(0, avail_nvacc, 1)) chance = rp * 10 rp_nvacc = np.floor(rp * avail_nvacc) player.participant.vars['start_time'] = int(time.time()) return { 'rp': rp, 'avail_vacc': avail_vacc, 'avail_nvacc': avail_nvacc, #'sick_real': sick_real, # 'animal_lost': died, 'image_range': image_range, 'image_range_2': image_range_2, 'chance': chance, 'rp_nvacc': rp_nvacc, } @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) @staticmethod def before_next_page(player, timeout_happened): end_time = int(time.time()) start_time = player.participant.vars['start_time'] player.time_spent_sellpage = end_time - start_time class Resultsnew(Page): @staticmethod def is_displayed(player: Player): return player.treat_B == 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() avail_vacc = player.in_round(1).Cows_vacc player.in_round(player.round_number).a_vacc = avail_vacc image_range_3 = list(np.arange(0, avail_vacc, 1)) player.available_herd_nvacc() if player.round_number == 1: avail_nvacc = 10 - player.in_round(1).Cows_vacc else: avail_nvacc = player.in_round(prev_round).a_nvacc - player.in_round(prev_round).animal_lost if player.round_number > 1 and player.in_round(prev_round).a_nvacc == 0: avail_nvacc = 0 player.in_round(player.round_number).a_nvacc = avail_nvacc image_range_4 = list(np.arange(0, avail_nvacc, 1)) chance = rp * 10 rp_nvacc = np.floor(rp * avail_nvacc) player.participant.vars['start_time'] = int(time.time()) return { 'rp': rp, 'avail_vacc': avail_vacc, 'avail_nvacc': avail_nvacc, 'image_range_3': image_range_3, 'image_range_4': image_range_4, 'chance': chance, 'rp_nvacc': rp_nvacc, } @staticmethod def before_next_page(player, timeout_happened): end_time = int(time.time()) start_time = player.participant.vars['start_time'] player.time_spent_resultsnew = end_time - start_time 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() if player.treat_A == 1 or player.treat_C == 1: remaining_vacc = player.a_vacc - player.Cows_sold_vacc elif player.treat_B == 1: remaining_vacc = player.a_vacc else: remaining_vacc = player.a_vacc if player.treat_A == 1 or player.treat_C == 1: remaining_nvacc = player.a_nvacc - player.Cows_sold_nvacc - player.in_round(player.round_number).lost() elif player.treat_B == 1: remaining_nvacc = player.a_nvacc - player.lost() else: remaining_nvacc = player.a_nvacc - player.in_round(player.round_number).lost() if player.round_number == 1 and player.treat_A == 1: sale_revenue = Constants.Psone * player.Cows_sold_nvacc + Constants.Pstwo * player.Cows_sold_vacc elif player.round_number == 1 and player.treat_C == 1: sale_revenue = Constants.Psone * player.Cows_sold_nvacc + Constants.Pstwo * player.Cows_sold_vacc elif player.round_number > 1 and player.treat_A == 1: sale_revenue = Constants.Psthree * player.Cows_sold_nvacc + Constants.Psfour * player.Cows_sold_vacc elif player.round_number > 1 and player.treat_C == 1: sale_revenue = Constants.Psthree * player.Cows_sold_nvacc + Constants.Psfour * player.Cows_sold_vacc else: sale_revenue = 10 sick_realised = player.sick_real milk_revenue = np.round( Constants.Pmilk * (remaining_vacc * Constants.q + (remaining_nvacc - sick_realised) * Constants.q + sick_realised * Constants.q/1.33),1) image_range_3 = list(np.arange(0, remaining_vacc, 1)) image_range_4 = list(np.arange(0, remaining_nvacc, 1)) image_range_5 = list(np.arange(0, sick_realised, 1)) image_range_6 = list(np.arange(0, player.lost(), 1)) sickness_exp = player.sick_real * Constants.Sickness maintainance_cost = (Constants.Mt/3)* player.a_vacc + Constants.Mt * player.a_nvacc if player.round_number == 1 and player.treat_A == 1: earning = player.payoff + sale_revenue - maintainance_cost - sickness_exp elif player.round_number > 1 and player.treat_A == 1: earning = player.payoff + milk_revenue - maintainance_cost - sickness_exp + sale_revenue elif player.round_number == 1 and player.treat_C == 1: earning = player.payoff + sale_revenue - maintainance_cost - sickness_exp elif player.round_number > 1 and player.treat_C == 1: earning = player.payoff - maintainance_cost - sickness_exp + sale_revenue elif player.round_number == 1 and player.treat_B == 1: earning = player.payoff - maintainance_cost - sickness_exp elif player.round_number > 1 and player.treat_B == 1: earning = player.payoff - maintainance_cost - sickness_exp + milk_revenue 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.animal_lost vacc_mov_fwd = player.vaccinated_mv_fwd() nvacc_post_sell = player.nonvaccinated_post_sell() player.participant.vars['start_time'] = int(time.time()) 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_3': image_range_3, 'image_range_4': image_range_4, 'image_range_5': image_range_5, 'image_range_6': image_range_6, 'vacc_mov_fwd': vacc_mov_fwd, 'nvacc_post_sell':nvacc_post_sell, } @staticmethod def before_next_page(player, timeout_happened): end_time = int(time.time()) start_time = player.participant.vars['start_time'] player.time_spent_results = end_time - start_time page_sequence = [MyPage, SellPage, Resultsnew, Results]