from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random import numpy as np author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'EXLEY_ASSO' players_per_group = None num_rounds = 1 associations = [ ("World Wide Fund for Nature - UK (WWF)", "This charity’s goal is to preserve the wilderness and reduce human impact on the environment."), ("GreenPeace - UK (GP)", "This charity aims to ensure the ability of the earth to nurture life in all its diversity"), ("Sea Shepherd (SP)", "This charity’s values are to protect defenseless marine wildlife and end the destruction of habitat in the world's oceans."), ("The Nature Conservancy (NC)", "This charity intends to conserve the lands and waters on which all life depends."), ("Surfers Against Sewage (SAS)", "This charity’s focus is to protect and restore the ocean and all it makes possible."), ] pas_x1 = 2 pas_x_filler = 2 max_x1_MPL = 30 x1_values_vec = np.arange(0, max_x1_MPL+pas_x1 , pas_x1) x1_values = x1_values_vec.tolist() max_x_filler_MPL = 30 x_filler_values_vec = np.arange(0, max_x_filler_MPL+pas_x_filler , pas_x_filler) x_filler_values = x_filler_values_vec.tolist() C_x1_me = 10 C_x2_me = 0 C_x_filler = 5 class Subsession(BaseSubsession): def creating_session(self): for p in self.get_players(): randomised_associations = random.sample(Constants.associations, len(Constants.associations)) p.participant.vars['associations'] = randomised_associations for p in self.get_players(): randomised_associations = random.sample(Constants.associations, len(Constants.associations)) p.participant.vars['associations'] = randomised_associations # variables de thunes pour soi p.participant.vars['x1_me'] = Constants.C_x1_me p.x1_me = p.participant.vars['x1_me'] p.participant.vars['x2_me'] = Constants.C_x2_me p.x2_me = p.participant.vars['x2_me'] p.participant.vars['x_filler'] = Constants.C_x_filler p.x_filler = p.participant.vars['x_filler'] for s in range(1, Constants.num_rounds + 1): p.in_round(s).x1_me = p.participant.vars['x1_me'] p.in_round(s).x2_me = p.participant.vars['x2_me'] p.in_round(s).x_filler = p.participant.vars['x_filler'] class Group(BaseGroup): pass class Player(BasePlayer): # VARIABLE CHOIX POUR CALIBRATION for i, x in enumerate(Constants.x1_values, start=1): locals()[f'choice_x_{i}'] = models.StringField( choices=['A', 'B'], label=f"{x}€" ) del i, x for i, x in enumerate(Constants.x_filler_values, start=1): locals()[f'choice_y_{i}'] = models.StringField( choices=['A', 'B'], label=f"{x}€" ) del i, x # VARIABLE A METTRE DANS TOUTES LES APPLIS ENDOWMENT = models.IntegerField() association_choice = models.StringField(blank=False) # outcome (arbitrary and calibrated) x1_me = models.FloatField() # 10€ x2_me = models.FloatField() # 0€ pas de calibration x_filler = models.FloatField() # 5€ x1_norm = models.FloatField() # calbration de 10€ x_filler_norm = models.FloatField() # calibration de 5€ x1_norm_after_correction = models.FloatField() # vraie valeur de x1_norm x2_norm = models.FloatField() # 0€ pas de calibration # VARIABLES FOR CALIBRATION (min et max de la MPL de la calibration) max_y_value = models.IntegerField() min_y_value = models.IntegerField() max_x_value = models.IntegerField() min_x_value = models.IntegerField() # POUR REPERER LES NOISY PLAYERS (par contre j'ai pas codé pour chercher les multiple switchers) censored = models.IntegerField() # permet de spotter les individus qui n'ont pas shifté dans la liste corrected = models.IntegerField() # pour savoir si la valeur calibré a été changé par l'expérimentateur (notamment si le x_norm = 0, dans ce cas il faudra une valeur calibré > 0) consistant = models.IntegerField() def chosen_asso(self): self.participant.vars['association_choice'] = self.association_choice # X NORMALIZATION def get_choice_values_x1(self): choice_values_x1 = [] for i, x in enumerate(Constants.x1_values, start=1): choice_field_name = f'choice_x_{i}' player_choice = getattr(self, choice_field_name) if player_choice == 'A': choice_values_x1.append(1000) elif player_choice == 'B': choice_values_x1.append(x) return choice_values_x1 # Méthode pour trouver la valeur minimale de choix pour x_me def min_choice_value_x1(self): self.participant.vars['value_x1_norm'] = min(self.get_choice_values_x1()) if self.participant.vars['value_x1_norm'] == 1000: self.x1_norm = max(Constants.x1_values) self.participant.vars['x1_norm'] = max(Constants.x1_values) else: self.x1_norm = self.participant.vars['value_x1_norm'] #- (Constants.pas_x/2) self.participant.vars['x1_norm'] = self.x1_norm # Y NORMALISATION def get_choice_values_x_filler(self): choice_values_x_filler = [] for i, x in enumerate(Constants.x_filler_values, start=1): choice_field_name = f'choice_y_{i}' player_choice = getattr(self, choice_field_name) if player_choice == 'A': choice_values_x_filler.append(1000) elif player_choice == 'B': choice_values_x_filler.append(x) return choice_values_x_filler def min_choice_value_x_filler(self): self.participant.vars['value_x_filler_norm'] = min(self.get_choice_values_x_filler()) if self.participant.vars['value_x_filler_norm'] == 1000: self.x_filler_norm = max(Constants.x_filler_values) self.participant.vars['x_filler_norm'] = max(Constants.x_filler_values) else: self.x_filler_norm = self.participant.vars['value_x_filler_norm'] #- (Constants.pas_y/2) self.participant.vars['x_filler_norm'] = self.x_filler_norm # ECRIRE LE CODE POUR DETERMINER LES NOISY INDIVIDUALS def corrector_def(self): if int(self.x1_norm) == max(Constants.x1_values): self.censored = 1 self.corrected = 0 self.participant.vars['x1_norm_after_correction'] = self.x1_norm # ligne à changer en fonction des corrections elif int(self.x1_norm) == 0: self.censored = 0 self.corrected = 1 self.participant.vars['x1_norm_after_correction'] = self.x1_norm + 2 # si x_norm = 0€, alors on change pour le mettre à 2€ else: self.censored = 0 self.corrected = 0 self.participant.vars['x1_norm_after_correction'] = self.x1_norm # si x_norm = 0€, alors on change pour le mettre à 2€ if int(self.x1_norm) < int(self.x_filler_norm): self.consistant = 0 else: self.consistant = 1 self.participant.vars['censored'] = self.censored self.participant.vars['corrected'] = self.corrected self.x2_norm = 0 self.participant.vars['x2_norm'] = self.x2_norm self.x1_norm_after_correction = self.participant.vars['x1_norm_after_correction'] self.participant.vars['consistant'] = self.consistant