from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, ) import random import numpy as np doc = """ Traitement 1 """ class Constants(BaseConstants): name_in_url = 'IPDARM_EQUAL_ANTE' players_per_session = 4 players_per_group = 2 #Changer avec session num_rounds = 50 #instructions_template = '' instructions_template_G = 'IPDARM_EQUAL_ANTE/instruction_G.html' # Population A # payoff if 1 player defects and the other cooperates""", betray_payoff_A = c(36) betrayed_payoff_A = c(16) # payoff if both players cooperate or both defect both_cooperate_payoff_A = c(32) both_defect_payoff_A = c(20) # Population B # payoff if 1 player defects and the other cooperates""", betray_payoff_B = c(18) betrayed_payoff_B = c(8) # payoff if both players cooperate or both defect both_cooperate_payoff_B = c(16) both_defect_payoff_B = c(10) gain_elicitation = c(3) acceptation = 10 alea_intra = 80 alea_inter = 97 class Subsession(BaseSubsession): ADGA = models.IntegerField(initial=0,) ADGB = models.IntegerField(initial=0,) ANGAA = models.IntegerField(initial=0,) ANGAB = models.IntegerField(initial=0,) ANGBA = models.IntegerField(initial=0,) ANGBB = models.IntegerField(initial=0,) def creating_session(self): for p in self.get_players(): p.participant.vars['Gain_elicitation'] = 0 p.participant.vars['cumulative_payoff'] = 0 def do_my_shuffle(self): if self.round_number == 1: players = self.get_players() #print(players) Pop_A = [p for p in players if p.participant.vars['role'] == 'A'] Pop_B = [p for p in players if p.participant.vars['role'] == 'B'] random.shuffle(Pop_A) random.shuffle(Pop_B) #print(Pop_A) #print(Pop_B) group_matrix = [] def is_possible(type_groupe, Pop_A, Pop_B): if type_groupe == 1: return len(Pop_A) >= 2 elif type_groupe == 2: return len(Pop_B) >= 2 return False for p in range(1,3): if p == 1: while is_possible(p, Pop_A, Pop_B): group_matrix.append([Pop_A.pop() for _ in range(2)]) elif p == 2: while is_possible(p, Pop_A, Pop_B): group_matrix.append([Pop_B.pop() for _ in range(2)]) self.set_group_matrix(group_matrix) print("Round 1") else: #if np.random.choice(100, 1, replace=True) <= 20: #modifier par Constants.alea_intra # self.group_like_round(self.round_number - 1) # print("Round intra") if np.random.choice(100, 1, replace=True) <= Constants.alea_inter: #modifier par Constants.alea_inter players = self.get_players() # print(players) AbsA = [p for p in players if (p.participant.vars['role'] == 'A' and p.in_round(p.round_number - 1).disconnected == True)] AbsB = [p for p in players if (p.participant.vars['role'] == 'B' and p.in_round(p.round_number - 1).disconnected == True)] Pop_A = [p for p in players if (p.participant.vars['role'] == 'A' and p.in_round(p.round_number - 1).disconnected == False)] Pop_B = [p for p in players if (p.participant.vars['role'] == 'B' and p.in_round(p.round_number - 1).disconnected == False)] random.shuffle(Pop_A) random.shuffle(Pop_B) print(Pop_A) print(Pop_B) print(AbsA) print(AbsB) group_matrix = [] def is_possible(type_groupe, AbsA, AbsB, Pop_A, Pop_B): if type_groupe == 1: return len(AbsA) >= 2 if type_groupe == 2: return len(AbsB) >= 2 elif type_groupe == 3: return len(Pop_A) >= 2 elif type_groupe == 4: return len(Pop_B) >= 2 return False for p in range(1, 5): if p == 1: while is_possible(p, AbsA, AbsB, Pop_A, Pop_B): group_matrix.append([AbsA.pop() for _ in range(2)]) if len(AbsA) == 1: group_matrix.append([AbsA.pop(), Pop_A.pop()]) elif p == 2: while is_possible(p, AbsA, AbsB, Pop_A, Pop_B): group_matrix.append([AbsB.pop() for _ in range(2)]) if len(AbsB) == 1: group_matrix.append([AbsB.pop(), Pop_B.pop()]) elif p == 3: while is_possible(p, AbsA, AbsB, Pop_A, Pop_B): group_matrix.append([Pop_A.pop() for _ in range(2)]) elif p == 4: while is_possible(p, AbsA, AbsB, Pop_A, Pop_B): group_matrix.append([Pop_B.pop() for _ in range(2)]) self.set_group_matrix(group_matrix) print("Round inter") else: print("STOP") Group.STOP = "STOP" def elicitation(self): ADLA = [] ADLB = [] ANLAA = [] #ANLBA = [] #ANLAB = [] ANLBB = [] DiscoA = [] DiscoB = [] for p in self.get_players(): if self.round_number == 1: if p.in_round(1).rolee == "A" and p.disconnected == False: ADLA.append(p.decision) ANLAA.append(p.AN1A) elif p.in_round(1).rolee == "A" and p.disconnected == True: DiscoA.append(1) if p.in_round(1).rolee == "B" and p.disconnected == False: ADLB.append(p.decision) ANLBB.append(p.AN1B) elif p.in_round(1).rolee == "B" and p.disconnected == True: DiscoB.append(1) else: if p.in_round(1).rolee == "A" and p.Attente == False and p.disconnected == False: ADLA.append(p.decision) ANLAA.append(p.AN1A) elif (p.in_round(1).rolee == "A" and p.Attente == True) or (p.in_round(1).rolee == "A" and p.Attente == False and p.disconnected == True) : DiscoA.append(1) if p.in_round(1).rolee == "B" and p.Attente == False and p.disconnected == False: ADLB.append(p.decision) ANLBB.append(p.AN1B) elif (p.in_round(1).rolee == "B" and p.Attente == True) or (p.in_round(1).rolee == "B" and p.Attente == False and p.disconnected == True): DiscoB.append(1) DiscoAF = sum(DiscoA) DiscoBF = sum(DiscoB) self.ADGA = int((sum(ADLA)/(Constants.players_per_session - DiscoAF)) * 100) self.ADGB = int((sum(ADLB)/(Constants.players_per_session - DiscoBF)) * 100) self.ANGAA = int((sum(ANLAA)/(Constants.players_per_session - DiscoAF)) * 100) #self.ANGAB = int((sum(ANLAB)/(Constants.players_per_session)) * 100) #self.ANGBA = int((sum(ANLBA)/(Constants.players_per_session)) * 100) self.ANGBB = int((sum(ANLBB)/(Constants.players_per_session - DiscoBF)) * 100) #print(DiscoAF) #print(ADLA) #print(self.ADGA) #print(self.ANGAA) #print(DiscoBF) #print(ADLB) #print(self.ADGB) #print(self.ANGBB) class Group(BaseGroup): STOP = models.CharField(initial='') def Message(self): for p in self.get_players(): if p.get_partner().Message != '': p.Reception = p.get_partner().Message def STOP(self): return self.STOP def AorB(self): for p in self.get_players(): if p.round_number != 1: if p.in_round(1).rolee == "A": p.ADA_old = p.in_round(p.round_number - 1).ADA p.ANA_old = p.in_round(p.round_number - 1).ANA if p.in_round(1).rolee == "B": p.ADB_old = p.in_round(p.round_number - 1).ADB p.ANB_old = p.in_round(p.round_number - 1).ANB if p.in_round(1).rolee == "A" and p.in_round(1).get_partner().rolee == "A": p.instructions_template = 'IPDARM_EQUAL_ANTE/instruction_A.html' p.tableau_template = 'IPDARM_EQUAL_ANTE/tableau_A.html' p.tableau_bis_template = 'IPDARM_EQUAL_ANTE/tableau_A_bis.html' elif p.in_round(1).rolee == "B" and p.in_round(1).get_partner().rolee == "B": p.instructions_template = 'IPDARM_EQUAL_ANTE/instruction_B.html' p.tableau_template = 'IPDARM_EQUAL_ANTE/tableau_B.html' p.tableau_bis_template = 'IPDARM_EQUAL_ANTE/tableau_B_bis.html' else: p.instructions_template = "erreur" def Disco(self): for p in self.get_players(): if p.round_number != 1: p.disconnected = p.in_round(p.round_number - 1).disconnected if p.disconnected == True or p.get_partner().disconnected == True: p.Attente = True def set_payoffs(self): for p in self.get_players(): if p.in_round(1).rolee == "A" and p.in_round(1).get_partner().rolee =="A": if p.decision == 1 and p.get_partner().decision == 1: p.payoff = Constants.both_cooperate_payoff_A elif p.decision == 1 and p.get_partner().decision == 0: p.payoff = Constants.betrayed_payoff_A elif p.decision == 0 and p.get_partner().decision == 1: p.payoff = Constants.betray_payoff_A elif p.decision == 0 and p.get_partner().decision == 0: p.payoff = Constants.both_defect_payoff_A if p.in_round(1).rolee == "B" and p.in_round(1).get_partner().rolee =="B": if p.decision == 1 and p.get_partner().decision == 1: p.payoff = Constants.both_cooperate_payoff_B elif p.decision == 1 and p.get_partner().decision == 0: p.payoff = Constants.betrayed_payoff_B elif p.decision == 0 and p.get_partner().decision == 1: p.payoff = Constants.betray_payoff_B elif p.decision == 0 and p.get_partner().decision == 0: p.payoff = Constants.both_defect_payoff_B if p.get_partner().disconnected == True or p.disconnected == True: p.payoff = 0 if p.in_round(1).rolee == "A": if abs(p.ADA - self.subsession.ADGA) <= Constants.acceptation: p.Gain_ADA = Constants.gain_elicitation if abs(p.ANA - self.subsession.ANGAA) <= Constants.acceptation: p.Gain_ANA = Constants.gain_elicitation if p.in_round(1).rolee == "B": if abs(p.ADB - self.subsession.ADGB) <= Constants.acceptation: p.Gain_ADB = Constants.gain_elicitation if abs(p.ANB - self.subsession.ANGBB) <= Constants.acceptation: p.Gain_ANB = Constants.gain_elicitation if p.AD1 == p.get_partner().decision: p.Gain_AD1 = Constants.gain_elicitation if p.round_number == 1: p.Total_payoff = p.payoff p.Gain_Total_Attente = p.Gain_ADA + p.Gain_ADB + p.Gain_ANA + p.Gain_ANB + p.Gain_AD1 else: p.Total_payoff = p.payoff + p.in_round(p.round_number - 1).Total_payoff p.Gain_Total_Attente = p.Gain_ADA + p.Gain_ADB + p.Gain_ANA + p.Gain_ANB + p.Gain_AD1 + p.in_round(p.round_number - 1).Gain_Total_Attente p.participant.vars['cumulative_payoff'] = p.Total_payoff p.participant.vars['Gain_elicitation'] = p.Gain_Total_Attente class Player(BasePlayer): Attente = models.BooleanField(initial=False) disconnected = models.BooleanField(initial=False) ADA_old = models.IntegerField(initial=0,) ANA_old = models.IntegerField(initial=0,) ADB_old = models.IntegerField(initial=0,) ANB_old = models.IntegerField(initial=0,) rolee = models.CharField(initial='') Message = models.CharField(blank=True,) Reception = models.CharField(initial='Your partner has not written a text') instructions_template = models.CharField(initial='') tableau_template = models.CharField(initial='') tableau_bis_template = models.CharField(initial='') decision = models.IntegerField( choices=[1, 0], doc="""This player's decision""", widget=widgets.RadioSelect, ) ADA = models.IntegerField( min=0, max=100, doc="""Attente descriptive des A""", ) ANA = models.IntegerField( min=0, max=100, doc="""Attente normative des A""", ) ADB = models.IntegerField( min=0, max=100, doc="""Attente descriptive des B""", ) ANB = models.IntegerField( min=0, max=100, doc="""Attente normative des B""", ) AD1 = models.IntegerField( choices=[[1, 'option X'], [0, 'option Y']], doc="""Attente descriptive du premier ordre""", widget=widgets.RadioSelect, ) AN1A = models.IntegerField( choices=[[1, 'option X'], [0, 'option Y']], doc="""Attente normative du premier ordre des A""", widget=widgets.RadioSelect, ) AN1B = models.IntegerField( choices=[[1, 'option X'], [0, 'option Y']], doc="""Attente normative du premier ordre des B""", widget=widgets.RadioSelect, ) Gain_ADA = models.CurrencyField(initial=0,) Gain_ANA = models.CurrencyField(initial=0,) Gain_ADB = models.CurrencyField(initial=0,) Gain_ANB = models.CurrencyField(initial=0,) Gain_AD1 = models.CurrencyField(initial=0,) Gain_Total_Attente = models.CurrencyField(initial=0,) Total_payoff = models.CurrencyField(initial=0,) def role(self): if self.participant.vars['role'] == "A": self.rolee = self.participant.vars['role'] elif self.participant.vars['role'] == "B": self.rolee = self.participant.vars['role'] def get_partner(self): return self.get_others_in_group()[0] def disconnect(self): self.decision = 0 self.AD1 = 0 self.disconnected = True if self.participant.vars['role'] == "A": self.ADA =0 self.ANA =0 self.AN1A =0 if self.participant.vars['role'] == "B": self.ADB =0 self.ANB =0 self.AN1B =0 def attentevalue(self): #self.decision = 0 if self.participant.vars['role'] == "A": self.ADA = self.in_round(self.round_number - 1).ADA self.ANA = self.in_round(self.round_number - 1).ANA if self.participant.vars['role'] == "B": self.ADB = self.in_round(self.round_number - 1).ADB self.ANB = self.in_round(self.round_number - 1).ANB