from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random import json author = 'Vincent Lenglin' doc = """ """ class Constants(BaseConstants): name_in_url = 'MAIF_PREV_YCPC' players_per_group = None # CONDITIONS EXPERIMENTALES # --------------------------------- epsilon = 10 num_rounds = 5 # nombre de tableaux par condition num_choices = 15 # nombre de ligne par tableau class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): page_sequence = models.StringField() TREATMENT = models.StringField() num_rounds = models.IntegerField(initial=Constants.num_rounds) num_choices = models.IntegerField(initial=Constants.num_choices) epsilon = models.IntegerField(initial=Constants.epsilon) # ASSOCIATIONS association_choice = models.StringField() WTP_VEC = models.StringField() y_me = models.IntegerField() x_me = models.IntegerField() y_outcome = models.IntegerField() x_outcome = models.IntegerField() D_me = models.IntegerField() D_norm = models.FloatField() y_norm = models.FloatField() x_norm = models.FloatField() y_norm_computed = models.FloatField() y_outcome_vec_order = models.StringField() x_outcome_vec_order = models.StringField() interval = models.FloatField() # BOULES boule_verte = models.IntegerField() boule_rouge = models.IntegerField() boule_verte_option_prev = models.IntegerField() boule_rouge_option_prev = models.IntegerField() boule_order = models.LongStringField() # ADDITIONAL VARIABLES error = models.BooleanField(initial=False) epsilon = models.IntegerField(initial=Constants.epsilon) boule_rouge_entrainement = models.IntegerField() boule_rouge_option_prev_entrainement = models.IntegerField() boule_verte_entrainement = models.IntegerField() boule_verte_option_prev_entrainement = models.IntegerField() is_list_ascending = models.IntegerField() # PAIEMENT trial_drawn = models.IntegerField() row_drawn = models.IntegerField() chosen_option = models.StringField() # CHOIX for j in range(1, Constants.num_choices + 1): locals()['choix' + str(j)] = models.StringField(choices=['A', 'B']) del j correction = models.IntegerField() y_B_charity_selected = models.FloatField() x_B_charity_selected = models.FloatField() py_B_charity_selected = models.FloatField() px_B_charity_selected = models.FloatField() y_A_charity_selected = models.FloatField() x_A_charity_selected = models.FloatField() py_A_charity_selected = models.FloatField() px_A_charity_selected = models.FloatField() y_B_self_selected = models.FloatField() x_B_self_selected = models.FloatField() py_B_self_selected = models.FloatField() px_B_self_selected = models.FloatField() y_A_self_selected = models.FloatField() x_A_self_selected = models.FloatField() py_A_self_selected = models.FloatField() px_A_self_selected = models.FloatField() y_B_self_selected = models.FloatField() x_B_self_selected = models.FloatField() py_B_self_selected = models.FloatField() px_B_self_selected = models.FloatField() random_round = models.IntegerField() random_row = models.IntegerField() charity_selected = models.StringField() choice_selected = models.StringField() paiement_self_exley = models.FloatField() paiement_charity_exley = models.FloatField() # BODY def ascending_or_descending_def(self): # Calculer l'intervalle pour avoir exactement 21 nombres interval = self.participant.vars['x_norm'] / (Constants.num_choices - 1) # 20 intervalles pour 21 nombres self.interval = interval self.participant.vars['interval'] = self.interval self.participant.vars['WTP_values'] = [i * interval for i in range(Constants.num_choices)] self.participant.vars['WTP_values'] = self.participant.vars['WTP_values'][::-1] self.WTP_VEC = str(self.participant.vars['WTP_values']) def chosen_asso(self): self.association_choice = self.participant.vars['association_choice'] def create_loteries(self): self.participant.vars['y_outcome_vec'] = [self.participant.vars['y_outcome'] for _ in range(len(self.participant.vars['boule_verte_option']))] self.participant.vars['x_outcome_vec'] = [self.participant.vars['x_outcome'] for _ in range(len(self.participant.vars['boule_verte_option']))] pairs = list(zip(self.participant.vars['boule_verte_option'], self.participant.vars['y_outcome_vec'], self.participant.vars['x_outcome_vec'])) # Mélangez les paires random.shuffle(pairs) # Divisez les paires mélangées en deux listes séparées order, y_outcome_vec_order, x_outcome_vec_order = zip(*pairs) # On record l'ordre des conditions dans la database self.boule_order = str(order) self.y_outcome_vec_order = str(y_outcome_vec_order) self.x_outcome_vec_order = str(x_outcome_vec_order) # On répand le résultat de l'aléatoirisation des conditions aux rounds for s in range(1, Constants.num_rounds + 1): self.in_round(s).boule_verte = order[s - 1] self.in_round(s).y_outcome_vec_order = str(y_outcome_vec_order) self.in_round(s).x_outcome_vec_order = str(x_outcome_vec_order) self.in_round(s).boule_verte_option_prev = self.in_round(s).boule_verte + Constants.epsilon self.in_round(s).y_outcome = self.participant.vars['y_outcome'] self.in_round(s).x_outcome = self.participant.vars['x_outcome'] self.in_round(s).y_me = self.participant.vars['y_me'] self.in_round(s).x_me = self.participant.vars['x_me'] self.in_round(s).D_me = self.participant.vars['D_me'] self.in_round(s).D_norm = self.participant.vars['D_norm'] self.in_round(s).y_norm = self.participant.vars['y_norm'] self.in_round(s).x_norm = self.participant.vars['x_norm'] self.in_round(s).y_norm_computed = self.participant.vars['y_norm_computed'] self.in_round(s).TREATMENT = "MAIF_PREV_YCPC" self.in_round(s).correction = self.participant.vars['correction'] self.in_round(s).WTP_VEC = str(self.participant.vars['WTP_values']) self.in_round(s).interval = self.participant.vars['interval'] ############################################################### # REAL - task ################################################################ # crée le nombre de boules vertes de l'option A def create_boule(self): self.boule_rouge = self.participant.vars['num_boule'] - self.boule_verte boule = [] for i in range(1, self.participant.vars['num_boule'] + 1): couleur = 'verte' if i <= self.boule_verte else 'noire' boule.append({'numero': i, 'couleur': couleur}) return boule # crée le nombre de boules vertes de l'option B def create_boule_prev(self): self.boule_rouge_option_prev = self.participant.vars['num_boule'] - self.boule_verte_option_prev boule = [] for i in range(1, self.participant.vars['num_boule'] + 1): couleur = 'verte' if i <= self.boule_verte_option_prev else 'noire' boule.append({'numero': i, 'couleur': couleur}) return boule ############################################################### # ENTRAINEMENT - consigne ################################################################ # crée le nombre de boules vertes de l'option A def create_boule_entrainement(self): self.boule_rouge_entrainement = self.participant.vars['num_boule'] - 50 self.boule_verte_entrainement = self.participant.vars['num_boule'] - 50 boule = [] for i in range(1, self.participant.vars['num_boule'] + 1): couleur = 'verte' if i <= self.boule_verte_entrainement else 'noire' boule.append({'numero': i, 'couleur': couleur}) return boule # crée le nombre de boules vertes de l'option B def create_boule_prev_entrainement(self): self.boule_rouge_option_prev_entrainement = self.participant.vars['num_boule'] - 60 self.boule_verte_option_prev_entrainement = self.participant.vars['num_boule'] - 40 boule = [] for i in range(1, self.participant.vars['num_boule'] + 1): couleur = 'verte' if i <= self.boule_verte_option_prev_entrainement else 'noire' boule.append({'numero': i, 'couleur': couleur}) return boule ######################################################################## # PAIEMENT ######################################################################## def paiement_def(self): # TRAITEMENT YCYC SI SELECTIONNE POUR PAIEMENT : # ------------------------------------------------------------- if self.participant.vars['paiement_treatment'] == "YCPC": # tirage aléatoire du round self.random_round = random.randint(1, Constants.num_rounds) self.participant.vars['random_round'] = self.random_round self.random_row = random.randint(1, Constants.num_choices) self.participant.vars['random_row'] = self.random_row # SELF : # ----------------------- # outcome self self.y_A_self_selected = 0 # sous ycpc, les outcomes pour self sont nulles self.x_A_self_selected = 0 self.participant.vars['y_A_self_selected'] = 0 self.participant.vars['x_A_self_selected'] = 0 self.y_B_self_selected = 0 # sous ycpc, les outcomes pour self sont nulles self.x_B_self_selected = 0 self.participant.vars['y_B_self_selected'] = 0 self.participant.vars['x_B_self_selected'] = 0 # probability self # Loterie A self.py_A_self_selected = 0 # sous ycpc les proba ne portent pas sur la richesse du self, donc p = 0 self.px_A_self_selected = 0 self.participant.vars['py_A_self_selected'] = 0 self.participant.vars['px_A_self_selected'] = 0 # Loterie B - preventive self.py_B_self_selected = 0 self.px_B_self_selected = 0 self.participant.vars['py_B_self_selected'] = 0 self.participant.vars['px_B_self_selected'] = 0 # CHARITY : # ----------------------- # outcome charity and name charity self.charity_selected = self.association_choice self.participant.vars['charity_selected'] = self.association_choice self.y_A_charity_selected = self.in_round(self.participant.vars['random_round']).y_norm_computed + self.in_round(self.participant.vars['random_round']).x_norm self.x_A_charity_selected = 0 + self.in_round(self.participant.vars['random_round']).x_norm self.participant.vars['y_A_charity_selected'] = self.y_A_charity_selected self.participant.vars['x_A_charity_selected'] = self.x_A_charity_selected self.y_B_charity_selected = self.in_round(self.participant.vars['random_round']).y_norm_computed + self.participant.vars['WTP_values'][self.participant.vars['random_row']-1] self.x_B_charity_selected = 0 + self.participant.vars['WTP_values'][self.participant.vars['random_row']-1] self.participant.vars['y_B_charity_selected'] = self.y_B_charity_selected self.participant.vars['x_B_charity_selected'] = self.x_B_charity_selected # probability charity # Loterie A self.py_A_charity_selected = self.in_round(self.participant.vars['random_round']).boule_verte self.px_A_charity_selected = self.in_round(self.participant.vars['random_round']).boule_rouge self.participant.vars['py_A_charity_selected'] = self.py_A_charity_selected self.participant.vars['px_A_charity_selected'] = self.px_A_charity_selected # Loterie B - preventive self.py_B_charity_selected = self.in_round(self.participant.vars['random_round']).boule_verte_option_prev self.px_B_charity_selected = self.in_round(self.participant.vars['random_round']).boule_rouge_option_prev self.participant.vars['py_B_charity_selected'] = self.py_B_charity_selected self.participant.vars['px_B_charity_selected'] = self.px_B_charity_selected # RECUPERATION DES CHOIX POUR CE TABLEAU (ce round) et paiement de la partie Exley # -------------------------------------------------------------------------------------------- def get_choice_x_round_x(self): if self.participant.vars['paiement_treatment'] == "YCPC": # Utilisez in_round pour obtenir l'instance du joueur pour le round spécifique player_round_2 = self.in_round(self.participant.vars['random_round'] ) # créer la liste des choix choix_vec = ['choix' + str(i) for i in range(1, Constants.num_choices + 1)] # Sélectionner aléatoirement un nom de choix choix_selected = choix_vec[self.participant.vars['random_row']-1] # Utiliser getattr pour obtenir la valeur du choix sur l'objet player_round_2 self.choice_selected = getattr(player_round_2, choix_selected, None) self.participant.vars['choice_selected'] = self.choice_selected if self.participant.vars['choice_selected'] == 'A': outcomes = [self.participant.vars['y_A_charity_selected'], self.participant.vars['x_A_charity_selected']] weights = [self.participant.vars['py_A_charity_selected'], self.participant.vars['px_A_charity_selected']] self.paiement_self_exley = 0 self.paiement_charity_exley = random.choices(outcomes, weights, k=1)[0] elif self.participant.vars['choice_selected'] == 'B': outcomes = [self.participant.vars['y_B_charity_selected'], self.participant.vars['x_B_charity_selected']] weights = [self.participant.vars['py_B_charity_selected'], self.participant.vars['px_B_charity_selected']] self.paiement_self_exley = 0 self.paiement_charity_exley = random.choices(outcomes, weights, k=1)[0] self.participant.vars['paiement_self_exley'] = 0 self.participant.vars['paiement_charity_exley'] = self.paiement_charity_exley