from otree.api import * import random import numpy as np import math doc = """ """ # Description: Same as Frame 9 but with all the signals and states preselected class C(BaseConstants): NAME_IN_URL = 'Frame19' PLAYERS_PER_GROUP = 100 NUM_ROUNDS = 5 ag = "Agreement" dag = "Disagreement" Initials = 6 NUMBERS = [1, 2, 3, 4, 5] N = 5 TREATMENTS = ['agreement', 'disagreement'] class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): session = subsession.session session.completions_by_treatment = {color: 0 for color in C.TREATMENTS} print(session.completions_by_treatment) for player in subsession.get_players(): if player.id_in_group % 2 == 0: player.evenodd = 1 else: player.evenodd = 0 N = 100 states = random.sample(range(0, 100), C.NUM_ROUNDS) signal_type1 = [] signal_type2 = [] for i in range(C.NUM_ROUNDS): urn = np.zeros(N, dtype=int) urn[:states[i]] = 1 print("urn:", urn) #draws = random.sample(urn.tolist(), 10) #print("draws: ", draws) #signal_type1.extend([sum(draws)]) draws2 = random.sample(urn.tolist(), 10) signal_type2.extend([sum(draws2)]) print(states, "+", signal_type1) #pistas1 = [] for player in subsession.get_players(): for r in range(1, C.NUM_ROUNDS + 1): if subsession.round_number == r: player.n = states[r - 1] urn = np.zeros(N, dtype=int) urn[:player.n] = 1 draws = random.sample(urn.tolist(), 10) player.pista1 = sum(draws) #pista1_values[r-1] = player.pista1 # Append player.pista1 to the list for player in subsession.get_players(): pistas1 = [] prev_rounds = [p for p in player.in_rounds(2, 3)] for prev in prev_rounds: pistas1.append(prev.pista1) player.participant.pista1 = pistas1 pistas2 = [] prev_rounds2 = [p for p in player.in_rounds(4, 5)] for prev in prev_rounds2: pistas2.append(prev.pista1) player.participant.pista2 = pistas2 print(player.participant.pista2) if subsession.round_number < 2: #Define payment rounds for each player before the session starts (at round 1). for i, player in enumerate(subsession.get_players()): player.participant.payment_round = random.choice([2,3,4,5]) player.payment_round = player.participant.payment_round urnp = np.zeros(100, dtype=int) urnp[:30] = 1 # print(urn) draws = random.sample(urnp.tolist(), 10) player.blue = sum(draws) else: #Once defined, these parameters will be carried over the other rounds. for j in (1, 2): for i, player in enumerate(subsession.get_players()): player.payment_round = player.participant.payment_round for player in subsession.get_players(): if player.subsession.round_number == 5: k = round(random.uniform(0, 100), 2) player.k = k class Group(BaseGroup): pass class Player(BasePlayer): participantID = models.StringField(label="") finished = models.BooleanField(initial=False) #Variable defined to flag the players who finished the session initial = models.IntegerField(initial=0) color = models.StringField() other = models.IntegerField() other2 = models.IntegerField() num_failed_attempts2 = models.IntegerField(initial=0) failed_too_many2 = models.BooleanField(initial=False) test_sgl0 = models.IntegerField(blank=True, label=' Question: Is the following statement true or false? The other participant is another person who already completed this study.', choices=[ [0, "True"], [1, "False"], ], widget=widgets.RadioSelectHorizontal ) test_sgl1 = models.IntegerField(blank=True, label=' Question: Consider the hypothetical scenario in which the computer chooses 40 blue balls for the urn. How many red balls are in the urn in this case?
Note: For each round, you will not know the number of blue balls chosen by the computer. ') test_sgl2 = models.IntegerField(blank=True, label=' Question: Does the other participant know the proportion of blue balls in the urn?', choices=[ [0, "Yes"], [1, "No"], ], widget=widgets.RadioSelectHorizontal ) test_sgl3 = models.IntegerField(blank=True, label=' Question: Suppose the other participant gets a sample with 3 blue balls out of 10. Which of the following is true?', choices=[ [0, "The proportion of blue balls in the urn is certainly 30%."], [1, "Since the observed balls are only 10 out of 100, it is not possible to determine with certainty the proportion of blue balls in the urn."], ], widget=widgets.RadioSelectHorizontal ) test_sgl3_1 = models.IntegerField(blank=True, label=' Question: Suppose you get a sample with 3 blue balls out of 10. Which of the following is true?', choices=[ [0, "The proportion of blue balls in the urn is certainly 30%."], [1, "Since the observed balls are only 10 out of 100, it is not possible to determine with certainty the proportion of blue balls in the urn."], ], widget=widgets.RadioSelectHorizontal ) test_sgl4 = models.IntegerField(blank=True, label=' Question: Is the following statement true or false? The 10 balls that the other participant observed were returned to the urn before the computer ' 'randomly selects my 10-ball sample. ', choices=[ [0, "True"], [1, "False"], ], widget=widgets.RadioSelectHorizontal ) test_sgl5 = models.IntegerField(blank=True, label=' Question: Is the following statement true or false? I will have the opportunity to revise my estimation of B% ' 'after observing the guess of the other participant.', choices=[ [0, "True"], [1, "False"], ], widget=widgets.RadioSelectHorizontal ) pista1 = models.IntegerField() pista2 = models.FloatField() blue = models.FloatField() guess = models.FloatField(label=" Task: Introduce your guess about the proportion of blue balls in the urn. " "
If you think that b% of the balls in the urn are blue, then enter the number \"b\". Do not type the % sign. ") guess_practice = models.FloatField(label=" Task: Introduce your guess about the proportion of blue balls in the urn. " "
If you think that b% of the balls in the urn are blue, then enter the number \"b\". Do not type the % sign. ", max=100) upd_guess = models.FloatField(label=" Task: Introduce your final guess about the proportion of blue balls in the urn. " "
If you think that b% of the balls in the urn are blue, then enter the number \"b\". Do not type the % sign.") chosen_guess = models.FloatField() n = models.IntegerField() score = models.FloatField() score2 = models.FloatField(initial=0) payment_round = models.IntegerField() square_diff = models.FloatField() k = models.FloatField() payment_guess = models.CurrencyField() diff = models.FloatField() evenodd = models.IntegerField() qmoral1 = models.IntegerField( label='
1. Abortion deadlines.
', choices=[ [0, "There should be a definitive time limit during pregnancy within which abortions are permissible (if allowed at all). " "Abortions performed near the birth due date are tantamount to murder."], [1, "Abortion should be legally permitted from the moment of conception until just before birth. " "No individual should have the power to impose arbitrary deadlines restricting a woman's autonomy over her own body."], ], widget=widgets.RadioSelect, ) qmoral2 = models.IntegerField( label='
2. Gender-transition medical treatments for minors.
', choices=[ [0, "Minors, due to their lack of maturity and susceptibility to confusion, should never be permitted to " "undergo gender-transition medical treatment, regardless of parental consent. Altering their body is a decision " "that must be reserved for adulthood."], [1, "Minors have an inherent right to live in alignment with their gender identity, and facilitating gender-transition medical treatment " "at an early age is crucial for a successful transition. Any opposition to this goal should be unequivocally denounced as flagrant discrimination."], ], widget=widgets.RadioSelect, ) qmoral3 = models.IntegerField( label='
3. Animal testing in medical research.
', choices=[ [0, "Stringent regulations must be enforced to govern animal testing, with the utmost priority placed on minimizing " "animal suffering and actively fostering the advancement of alternative methods. " "The well-being and dignity of animals must never be sacrificed for the sake of human benefits."], [1, "Imposing regulations on animal testing often leads to detrimental delays in life-saving research, " "impeding timely access to potential cures for countless individuals. Human welfare should unequivocally be the " "paramount concern in the field of medical research."], ], widget=widgets.RadioSelect, ) qmoral4 = models.IntegerField( label='
4. Body Positivity versus Fitness promotion.
', choices=[ [0, "All bodies, regardless of their shape and size, must be embraced, celebrated, and fairly represented in the media. " "Any diets, programs, or representations that aim to mold bodies into specific standards have profoundly detrimental effects and perpetuate an insidious culture of discrimination."], [1, "It is crucial to advocate for healthy eating habits and active lifestyles to combat the prevalence of certain diseases. " "Obesity, excessive fat, and high cholesterol pose genuine health concerns that require attention and action."], ], widget=widgets.RadioSelect, ) qmoral5 = models.IntegerField( label='
5. Transgender woman in female sports.
', choices=[ [0, "Transgender women must be strictly prohibited from participating in female sports, particularly at the high school and " "college levels. The biological differences between cisgender women and transgender women create an inherently " "unfair competition for the former group, compromising the integrity of the sport. "], [1, "Transgender women are unequivocally women and, therefore, possess the absolute right to participate in any " "and all female-designated competitions. Any opposition to this policy is discriminatory and transphobic, " "perpetuating harmful biases. "], ], widget=widgets.RadioSelect, ) morality1 = models.IntegerField( label="You perceive this issue as:", choices=[ [1, "Very important"], [0, "Not very important"], ], widget=widgets.RadioSelectHorizontal, ) morality2 = models.IntegerField( label="You perceive this issue as:", choices=[ [1, "Very important"], [0, "Not very important"], ], widget=widgets.RadioSelectHorizontal, ) morality3 = models.IntegerField( label='You perceive this issue as:', choices=[ [1, "Very important"], [0, "Not very important"], ], widget=widgets.RadioSelectHorizontal, ) morality4 = models.IntegerField( label='You perceive this issue as:', choices=[ [1, "Very important"], [0, "Not very important"], ], widget=widgets.RadioSelectHorizontal, ) morality5 = models.IntegerField( label='You perceive this issue as:', choices=[ [1, "Very important"], [0, "Not very important"], ], widget=widgets.RadioSelectHorizontal, ) consent = models.IntegerField( label="By clicking \'Accept\', I hereby acknowledge that I have read and understood the content on this page and agree to participate in this study. If you " "do not want to continue with this study, please choose \'Reject\'.", choices=[ [1, "Accept"], [0, "Reject"], ], widget=widgets.RadioSelect ) check = models.IntegerField( label="", choices=[ [1, "Agrees"], [0, "Disagrees"], ], widget=widgets.RadioSelect ) feedback = models.LongStringField(label="", blank=True) #FUNCTIONS #### Get the other players in the group. def other_players(player: Player): return player.get_others_in_group() def get_high_score(player: Player): if player.round_number == 1: print("start", player.id_in_group) participant = player.participant participant.scores = [] subsession = player.subsession vector = [] # get all the players who have finished the session finished_players = [p for p in subsession.get_players() if p.finished] print('number of finished players', len(finished_players)) for other_player in finished_players: score = 0 for n in C.NUMBERS: # the score variables gives the number of questions in common with a given player if getattr(player, 'qmoral{}'.format(n)) == getattr(other_player, 'qmoral{}'.format(n)): #new score += 1 # append the score to the list of participant.scores (to have the number of common answers with each other participant) participant.scores.append(score) print(score) imax = participant.scores.index(max(participant.scores)) #index of maximum element of the scores list: This will give the "number" of the participant with the maximum agreement print('imax', imax) imin = participant.scores.index(min(participant.scores)) print('imin', imin) other_ag = finished_players[imax] #other_ag is a participant object, in particular, the participant with index imax in the list of finished participants other_dag = finished_players[imin] vector_ag = [0] * C.N vector_dag = [0] * C.N print('othere ag', other_ag, 'other dag', other_dag) for n in C.NUMBERS: if getattr(player, 'qmoral{}'.format(n)) == getattr(other_ag, 'qmoral{}'.format(n)): # new vector_ag[n-1] = 1 # Make a vector with five elements (one per question) that makes 1 the questions of agreement with other_ag if getattr(player, 'qmoral{}'.format(n)) != getattr(other_dag, 'qmoral{}'.format(n)): # new vector_dag[n-1] = 1 print('vector ag', vector_ag) vector_ag = np.array(vector_ag) vector_dag = np.array(vector_dag) # Identify indexes of 1 values (questions in common with other_ag indexes_ag = np.where(vector_ag == 1)[0] indexes_dag = np.where(vector_dag == 1)[0] print("print1", indexes_ag) print("print2", indexes_dag) vector_relev_ag = [0] * C.N vector_relev_dag = [0] * C.N # Randomly select two indexes if len(indexes_ag) >= 2: random_indexes_ag = [100, 100] indexes = [i for i, value in enumerate(participant.scores) if value >= 2] others = [finished_players[i] for i in indexes] minimuns = [] maximuns = [] for other_player in others: subs = np.abs(np.subtract(other_player.participant.pista1, player.participant.pista1)) mins = min(subs) maxs = max(subs) minimuns.append(mins) maximuns.append(maxs) print('minimums', minimuns) if sum(minimuns) == 0: relevant_ag_other = others[np.argmax(maximuns)] print('Not players with full non-zero vector, pick the maximum then ') else: relevant_idxs = [i for i, value in enumerate(minimuns) if value > 0] print('relevant indexes', relevant_idxs) relevant_others = [others[i] for i in relevant_idxs] print('relevant_others', relevant_others) relevant_ag_other = relevant_others[0] for n in C.NUMBERS: if getattr(player, 'qmoral{}'.format(n)) == getattr(relevant_ag_other, 'qmoral{}'.format(n)): # new vector_relev_ag[n - 1] = 1 # Make a vector with five elements (one per question) that makes 1 the questions of agreement with other_ag print('vector relev ag', vector_relev_ag) vector_relev_ag = np.array(vector_relev_ag) # Identify indexes of 1 values (questions in common with other_ag indexes_relev_ag = np.where(vector_relev_ag == 1)[0] print('indexes relev ag', indexes_relev_ag) if player.id_in_group % 2 == 0: relevant_indexes_ag = [x + 1 for x in indexes_relev_ag[:2]] else: relevant_indexes_ag = [x + 1 for x in indexes_relev_ag[-2:]] else: random_indexes_ag = [-1, -1] relevant_indexes_ag = [-1, -1] relevant_ag_other = finished_players[imax] if len(indexes_dag) >= 2: random_indexes_dag = [100, 100] indexes_d = [i for i, value in enumerate(participant.scores) if value <= 3] print(indexes_d, 'indexes_d') others_d = [finished_players[i] for i in indexes_d] print(others_d, 'others_d', others_d[0].qmoral4, others_d[0].qmoral3) minimuns_d = [] maximuns_d = [] for other_player in others_d: subs_d = np.abs(np.subtract(other_player.participant.pista1, player.participant.pista1)) mins_d = min(subs_d) maxs_d = max(subs) minimuns_d.append(mins_d) maximuns_d.append(maxs_d) if sum(minimuns_d) == 0: relevant_dag_other = others_d[np.argmax(maximuns_d)] print('Not players with full non-zero vector, pick the maximum then ') else: relevant_idxs_d = [i for i, value in enumerate(minimuns_d) if value > 0] relevant_others_d = [others_d[i] for i in relevant_idxs_d] relevant_dag_other = relevant_others_d[0] for n in C.NUMBERS: print(getattr(player, 'qmoral{}'.format(n)), 'player', getattr(relevant_dag_other, 'qmoral{}'.format(n)), 'other') if getattr(player, 'qmoral{}'.format(n)) != getattr(relevant_dag_other, 'qmoral{}'.format(n)): # new vector_relev_dag[n - 1] = 1 # Make a vector with five elements (one per question) that makes 1 the questions of agreement with other_ag print('vector relev dag', vector_relev_dag) vector_relev_dag = np.array(vector_relev_dag) # Identify indexes of 1 values (questions in common with other_ag indexes_relev_dag = np.where(vector_relev_dag == 1)[0] if player.id_in_group % 2 == 0: relevant_indexes_dag = [x + 1 for x in indexes_relev_dag[:2]] else: relevant_indexes_dag = [x + 1 for x in indexes_relev_dag[-2:]] else: print('failed to find a disagreement player') random_indexes_dag = [-1, -1] relevant_indexes_dag = [-1, -1] relevant_dag_other = finished_players[imin] #random_indexes_dag = [1, 2] #participant.q1 = random_indexes_ag #participant.q2 = random_indexes_dag #define the part objects questions1 = random_indexes_ag questions2 = random_indexes_dag q1 = relevant_indexes_ag q2 = relevant_indexes_dag agreement_player = finished_players.index(relevant_ag_other) disagreement_player = finished_players.index(relevant_dag_other) print("Indexes of 1 values:", indexes_ag) print("Randomly selected indexes:", random_indexes_ag) return[questions1, questions2, imax, imin, q1, q2, agreement_player, disagreement_player] def get_other_partII(player: Player): print('second part for player', player.id_in_group) participant = player.participant participant.scores = [] subsession = player.subsession vector = [] # get all the players who have finished the session print('other', player.other) finished_players = [p for p in subsession.get_players() if p.finished and p.id_in_group != player.other] minimuns = [] maximuns = [] print('number of finished players get other partII', len(finished_players)) prev_rounds = [p for p in player.in_rounds(2, 3)] diff1 = abs(10*prev_rounds[0].pista1 - prev_rounds[0].pista2) print('diff1=', diff1) diff2 = abs(10*prev_rounds[1].pista1 - prev_rounds[1].pista2) print('diff2=', diff2) for other_player in finished_players: subs = 10*np.abs(np.subtract(other_player.participant.pista2, player.participant.pista2)) print('subs', subs) q1 = 1 if diff1 in subs else 0 q2 = 1 if diff2 in subs else 0 minimuns.append(q1) maximuns.append(q2) if sum(minimuns) > 0: index = minimuns.index(1) print(minimuns, index, 'round2' ) elif sum(maximuns) > 0: index = maximuns.index(1) print(maximuns, index, 'round3') else: index = 0 print('Not Found') print('index=', index) return[index] def get_vector(player: Player): print("This function is being used") if player.color == 'agreement': vector = get_high_score(player)[0] if sum(vector) < 0: vector = get_high_score(player)[1] player.color = 'disagreement' else: vector = get_high_score(player)[1] print('treatment is', vector) if sum(vector) < 0: vector = get_high_score(player)[0] player.color = 'agreement' print(player.color) return [vector] #PAGES ############################################################################################################# ############################################################################################################# class StartingPage(Page): form_model = 'player' form_fields = ['participantID'] def is_displayed(player: Player): return player.round_number == 1 def before_next_page(player: Player, timeout_happened): subsession = player.subsession participant = player.participant # get all the players who have finished the session finished_players = [p for p in subsession.get_players() if p.finished] if len(finished_players) < 2: player.initial = 1 participant.init = player.initial print("participant init: ", participant.init) class Consent(Page): form_model = 'player' form_fields = ['consent'] #timeout_seconds = 0.5 def is_displayed(player: Player): return player.round_number == 1 class Reject(Page): @staticmethod def is_displayed(player: Player): return player.field_maybe_none('consent') == 0 and player.round_number == 1 class Instructions(Page): #timeout_seconds = 0.5 def is_displayed(player: Player): return player.round_number == 1 class test0(Page): form_model = 'player' form_fields = ['test_sgl0'] @staticmethod def error_message(player: Player, values): solutions = dict(test_sgl0=0) errors = {name: 'Wrong' for name in solutions if values[name] != solutions[name]} print('errors is', errors) if errors: player.num_failed_attempts2 += 1 if player.num_failed_attempts2 >= 4: player.failed_too_many2 = True else: return errors def vars_for_template(player: Player): return { 'attempts': 3-player.num_failed_attempts2 } def is_displayed(player: Player): return player.round_number == 1 and player.initial==0 class test1(Page): form_model = 'player' form_fields = ['test_sgl1'] @staticmethod def error_message(player: Player, values): solutions = dict(test_sgl1=60) errors = {name: 'Wrong' for name in solutions if values[name] != solutions[name]} print('errors is', errors) if errors: player.num_failed_attempts2 += 1 if player.num_failed_attempts2 >= 4: player.failed_too_many2 = True else: return errors def vars_for_template(player: Player): return { 'attempts': 3-player.num_failed_attempts2 } def is_displayed(player: Player): return player.round_number == 1 and player.num_failed_attempts2 < 4 class test2(Page): form_model = 'player' form_fields = ['test_sgl2'] @staticmethod def error_message(player: Player, values): solutions = dict(test_sgl2=1) errors = {name: 'Wrong' for name in solutions if values[name] != solutions[name]} print('errors is', errors) if errors: player.num_failed_attempts2 += 1 if player.num_failed_attempts2 >= 4: player.failed_too_many2 = True else: return errors def vars_for_template(player: Player): return { 'attempts': 3-player.num_failed_attempts2 } def is_displayed(player: Player): return player.round_number == 1 and player.num_failed_attempts2 < 4 and player.initial==0 class test3(Page): form_model = 'player' form_fields = ['test_sgl3'] @staticmethod def error_message(player: Player, values): solutions = dict(test_sgl3=1) errors = {name: 'Wrong' for name in solutions if values[name] != solutions[name]} print('errors is', errors) if errors: player.num_failed_attempts2 += 1 if player.num_failed_attempts2 >= 4: player.failed_too_many2 = True else: return errors def vars_for_template(player: Player): return { 'attempts': 3-player.num_failed_attempts2 } def is_displayed(player: Player): return player.round_number == 1 and player.num_failed_attempts2 < 4 and player.initial==0 class test3_1(Page): form_model = 'player' form_fields = ['test_sgl3_1'] @staticmethod def error_message(player: Player, values): solutions = dict(test_sgl3_1=1) errors = {name: 'Wrong' for name in solutions if values[name] != solutions[name]} print('errors is', errors) if errors: player.num_failed_attempts2 += 1 if player.num_failed_attempts2 >= 4: player.failed_too_many2 = True else: return errors def vars_for_template(player: Player): return { 'attempts': 3 - player.num_failed_attempts2 } def is_displayed(player: Player): return player.round_number == 1 and player.num_failed_attempts2 < 4 and player.initial==1 class test4(Page): form_model = 'player' form_fields = ['test_sgl4'] @staticmethod def error_message(player: Player, values): solutions = dict(test_sgl4=0) errors = {name: 'Wrong' for name in solutions if values[name] != solutions[name]} print('errors is', errors) if errors: player.num_failed_attempts2 += 1 if player.num_failed_attempts2 >= 4: player.failed_too_many2 = True else: return errors def vars_for_template(player: Player): return { 'attempts': 3-player.num_failed_attempts2 } def is_displayed(player: Player): return player.round_number == 1 and player.num_failed_attempts2 < 4 and player.initial==0 class test5(Page): form_model = 'player' form_fields = ['test_sgl5'] @staticmethod def error_message(player: Player, values): solutions = dict(test_sgl5=0) errors = {name: 'Wrong' for name in solutions if values[name] != solutions[name]} print('errors is', errors) if errors: player.num_failed_attempts2 += 1 if player.num_failed_attempts2 >= 4: player.failed_too_many2 = True else: return errors def vars_for_template(player: Player): return { 'attempts': 3-player.num_failed_attempts2 } def is_displayed(player: Player): return player.round_number == 1 and player.num_failed_attempts2 < 4 and player.initial == 0 class Failed2(Page): @staticmethod def is_displayed(player: Player): return player.failed_too_many2 class Payoffs(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 ############################################################################################################# ############################################################################################################# ####################################### GUESSING BLOCK ###################################################### ############################################################################################################# ############################################################################################################# class Practice(Page): form_model = 'player' form_fields = ['guess_practice'] def vars_for_template(player: Player): #urn = np.zeros(100, dtype=int) #urn[:30] = 1 #print(urn) #draws = random.sample(urn.tolist(), 10) #player.blue = sum(draws) frac = player.blue / 10 * 100 return { 'frac': frac, 'blue': player.blue, } def is_displayed(player: Player): return player.round_number == 1 def before_next_page(player: Player, timeout_happened): participant = player.participant participant.guess_practice = player.guess_practice class GuessForRestX(Page): #Guess page for the 6th round for player after P6. Note the use of the player random advisor 'adv' defined on the disagreement page. #timeout_seconds = 6 form_model = 'player' form_fields = ['guess'] def vars_for_template(player: Player): # urn = player.participant.urn # draws = random.sample(urn.tolist(), 10) # print(draws) # player.pista1 = sum(draws) if player.initial == 0: prev_player = player.in_round(1) other = prev_player.other player.other = other if player.round_number in [2, 3]: finished_player = [p for p in player.subsession.get_players() if p.id_in_group == other] player.pista2 = finished_player[0].guess elif player.round_number in [4, 5]: finished_player = [p for p in player.subsession.get_players() if p.id_in_group == player.other2] print('other 2', player.other2) print('finished players', len(finished_player)) player.pista2 = finished_player[0].guess frac1 = player.pista1 / 10 * 100 if player.initial == 0: frac2 = player.pista2 / 10 * 100 return { 'frac1': frac1, 'frac2': frac2, } else: return { 'frac1': frac1, } def is_displayed(player: Player): return player.round_number != 1 def before_next_page(player: Player, timeout_happened): if player.initial == 1: player.score = (player.guess - player.n) ** 2 if player.round_number == player.payment_round: player.square_diff = player.score else: player.square_diff = 0 class Guess_updatedX(Page): #Updated guess for everyone once they receive the second hint (either private or from the other player) #timeout_seconds = 2 form_model = 'player' form_fields = ['upd_guess'] @staticmethod def vars_for_template(player: Player): frac1 = player.pista1 / 10 * 100 frac2 = player.pista2 / 10 * 100 return { 'frac1': frac1, 'frac2': frac2, } def is_displayed(player: Player): return player.round_number in [2, 3] and player.initial == 0 def before_next_page(player: Player, timeout_happened): player.chosen_guess = random.choice([player.upd_guess, player.guess]) player.score = (player.chosen_guess - player.n) ** 2 if player.round_number == player.payment_round: player.square_diff = player.score else: player.square_diff = 0 class Guess_updated2(Page): #timeout_seconds = 2 form_model = 'player' form_fields = ['upd_guess'] def vars_for_template(player: Player): frac1 = player.pista1 / 10 * 100 frac2 = player.pista2 / 10 * 100 return { 'frac1': frac1, 'frac2': frac2, 'other': 1 + 2 * (player.id_in_group-2) } def is_displayed(player: Player): return player.round_number in [4, 5] and player.initial == 0 def before_next_page(player: Player, timeout_happened): player.chosen_guess = random.choice([player.upd_guess, player.guess]) player.score = (player.chosen_guess - player.n) ** 2 if player.round_number == player.payment_round: player.square_diff = player.score else: player.square_diff = 0 ############################################################################################################# ############################################################################################################# ########################################## ############################################### ########################################## DISAGREEMENT BLOCK ############################################### ########################################## ############################################### ############################################################################################################# ############################################################################################################# class Survey(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 def vars_for_template(player: Player): player.square_diff = 0 if player.round_number == 1: return{ 'other': 1 + 2 * (player.id_in_group - 2) } def before_next_page(player: Player, timeout_happened): session = player.session player.color = min( C.TREATMENTS, key=lambda color: session.completions_by_treatment[color], ) print("the assigment treatment on the survey page is", player.color) print(session.completions_by_treatment) class Disagreement_moral(Page): form_model = 'player' form_fields = ['qmoral1', 'qmoral2', 'qmoral3', 'qmoral4', 'qmoral5'] @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Disagreement_result(Page): form_model = 'player' form_fields = ['check'] @staticmethod def vars_for_template(player: Player): print('Disagreement_Result page') finished_players = [p for p in player.subsession.get_players() if p.finished] imin = get_high_score(player)[7] imax = get_high_score(player)[6] if player.color == 'agreement': other = finished_players[imax] vector = get_high_score(player)[4] else: other = finished_players[imin] vector = get_high_score(player)[5] player.other = other.id_in_group return{ # 'other_answer': player.field_display('question_other'), 'q1': other.field_display('qmoral{}'.format(vector[0])), 'q2': other.field_display('qmoral{}'.format(vector[1])), 'other': 1 + 2 * (player.id_in_group - 2) } def is_displayed(player: Player): return player.round_number == 1 and player.initial == 0 def before_next_page(player: Player, timeout_happened): if player.color == 'agreement': if player.check == 1: player.score2 = 50 else: if player.check == 0: player.score2 = 50 class Survey2(Page): #timeout_seconds = 6 form_model = 'player' form_fields = ['morality{}'.format(n) for n in C.NUMBERS] @staticmethod def get_form_fields(player: Player): print("Get form fields Survey 2") if player.initial == 1: return ['morality{}'.format(n) for n in C.NUMBERS] else: # print('new player') if player.color == 'agreement': check = get_high_score(player)[0] vector = get_high_score(player)[4] print('initial: agreement') if sum(check) < 0: print('failed to find an agreement player') vector = get_high_score(player)[5] player.color = 'disagreement' print("treatment change") else: check = get_high_score(player)[1] vector = get_high_score(player)[5] print('initial: disagreement', vector) if sum(check) < 0: print('failed to find a disagreement player') vector = get_high_score(player)[4] player.color = 'agreement' print(player.color) #return ['morality{}'.format(n) for n in vector] print('vector', vector) return ['morality{}'.format(vector[0]), 'morality{}'.format(vector[1])] def vars_for_template(player: Player): print("vars for template Survey 2") if player.initial == 0: # print('new player') if player.color == 'agreement': check = get_high_score(player)[0] vector = get_high_score(player)[4] if sum(check) < 0: vector = get_high_score(player)[5] player.color = 'disagreement' else: check = get_high_score(player)[1] vector = get_high_score(player)[5] print('treatment stable again', vector) if sum(check) < 0: vector = get_high_score(player)[4] player.color = 'agreement' print(player.color) return { 'resp1': player.field_display('qmoral{}'.format(vector[0])), 'resp2': player.field_display('qmoral{}'.format(vector[1])), 'vector0': vector[0], 'vector1': vector[1], } def is_displayed(player: Player): #This is only relevant for those after P6 on the 6th round. return player.round_number == 1 and player.initial == 0 ############################################################################################################ ############################################################################################################ ########################################## PAYOFFS BLOCK ################################################### ############################################################################################################ ############################################################################################################ class Results(Page): form_model = 'player' form_fields = ['feedback'] @staticmethod def get_form_fields(player: Player): if player.round_number == 5: return ['feedback'] def vars_for_template(player: Player): if player.round_number == 5: diff = sum([player.square_diff for player in player.in_all_rounds()]) player.diff = diff if player.initial == 0: survey = sum([player.score2 for player in player.in_all_rounds()]) else: survey = 50 if diff <= player.k: player.payment_guess = 200 bonus = 200 player.payoff = 2 + 1 + survey/100 score = 200+100 + survey else: player.payment_guess = 0 bonus = 0 player.payoff = 1 + survey/100 score = 100 + survey other = player.in_round(player.payment_round) print('other', other.round_number) if player.initial == 0: guess = other.chosen_guess else: guess = other.guess if player.payoff == 3.5: code = 'C12R00Y5' elif player.payoff == 3: code = 'CXC376KG' elif player.payoff == 1.5: code = 'CZLLFG6D' else: code = 'C1BEEBE2' return{ 'score': score, 'survey': survey + 50, 'guess': guess, 'bonus': bonus, 'k': player.k, 'n': other.n, 'code': code } def before_next_page(player: Player, timeout_happened): # set the finished flag to True if player.round_number == 5: player.finished = True # Here is where the "initial players" are flagged as finished. #prev_player = player.in_previous_rounds() #prev_player.finished = True #this is how you UPDATE a player field of a previous round prev_rounds = [p for p in player.in_previous_rounds()] for prev in prev_rounds: # new prev.finished = True if player.round_number == 1: session = player.session session.completions_by_treatment[player.color] += 1 def is_displayed(player: Player): #This is only relevant for those after P6 on the 6th round. return player.round_number in [1, 5] class Other_player(Page): #timeout_seconds = 0.05 @staticmethod def vars_for_template(player: Player): if player.round_number == 3: return{ 'other': 1 + 2 * (player.id_in_group - 2) } def is_displayed(player: Player): return player.round_number in [1, 4] and player.initial == 0 class SessionNumber(Page): def is_displayed(player: Player): #This is only relevant for those after P6 on the 6th round. player.initial = player.participant.init return player.round_number in [1, 4] # def before_next_page(player: Player, timeout_happened): # if player.round_number >= 4 and player.initial == 0: # prev_player = player.in_round(1) # other = prev_player.other # player.other = other class Round1(Page): def vars_for_template(player: Player): if player.round_number >= 4 and player.initial == 0: prev_player = player.in_round(1) other = prev_player.other player.other = other print(get_other_partII(player)[0]) finished_players = [p for p in player.subsession.get_players() if p.finished and p.id_in_group != player.other] other2_idx = get_other_partII(player)[0] ###what is happening is that get_other part III needs the player.other but that is only defined after the round page. Fix this other2 = finished_players[other2_idx] player.other2 = other2.id_in_group if player.round_number > 1: participant = player.participant player.initial = participant.init if player.round_number >= 3: return{ 'other': 1 + 2 * (player.id_in_group - 2) } def is_displayed(player: Player): return player.round_number in [1, 3, 4, 5] page_sequence = [StartingPage, Consent, Reject, Instructions, test0, test1, test2, test3, test3_1, test4, test5, Failed2, Payoffs, Practice, SessionNumber, Other_player, Round1, Survey, Disagreement_moral, Survey2, Disagreement_result, GuessForRestX, Guess_updatedX, Guess_updated2, Results] #StartingPage, Consent, Reject, Instructions, test0, test1, test2, test3, test3_1, test4, test5, Failed2, Payoffs, Practice,