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 = 'Frame18' PLAYERS_PER_GROUP = 150 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) 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) 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 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() 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 ) #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) # Randomly select two indexes if len(indexes_ag) >= 2: #random_indexes_ag = np.random.choice(indexes_ag + 1, size=2, replace=False) if player.id_in_group % 2 == 0: random_indexes_ag = [x + 1 for x in indexes_ag[:2]] else: random_indexes_ag = [x + 1 for x in indexes_ag[-2:]] else: random_indexes_ag = [-1, -1] #random_indexes_ag = [1, 2] if len(indexes_dag) >= 2: if player.id_in_group % 2 == 0: random_indexes_dag = [x + 1 for x in indexes_dag[:2]] else: random_indexes_dag = [x + 1 for x in indexes_dag[-2:]] else: random_indexes_dag = [-1, -1] #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 print("Indexes of 1 values:", indexes_ag) print("Randomly selected indexes:", random_indexes_ag) return[questions1, questions2, imax, imin] 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: if player.round_number in [2, 3]: prev_player = player.in_round(1) other = prev_player.other player.other = other 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.finished] player.pista2 = finished_player[1].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)[3] imax = get_high_score(player)[2] if player.color == 'agreement': other = finished_players[imax] vector = get_high_score(player)[0] else: other = finished_players[imin] vector = get_high_score(player)[1] 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 = 75 else: if player.check == 0: player.score2 = 75 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': vector = get_high_score(player)[0] if sum(vector) < 0: print('failed to find an agreement player') vector = get_high_score(player)[1] player.color = 'disagreement' print("treatment change") else: vector = get_high_score(player)[1] print('treatment stable', vector) if sum(vector) < 0: print('failed to find a disagreement player') vector = get_high_score(player)[0] player.color = 'agreement' print(player.color) #return ['morality{}'.format(n) for n in 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': 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 stable again', vector) if sum(vector) < 0: vector = get_high_score(player)[0] 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): #timeout_seconds = 0.05 @staticmethod def vars_for_template(player: Player): if player.round_number == 5: k = round(random.uniform(0, 200), 2) player.k = k 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 = 75 if diff <= k: player.payment_guess = 200 player.payoff = 2 + 0.75 + survey/100 score = 200+75 + survey else: player.payment_guess = 0 player.payoff = 0.75 + survey/100 score = 75 + survey return{ 'score': score } 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] class Round1(Page): def vars_for_template(player: Player): 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, 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,