from otree.api import * import random import itertools doc = """ """ class C(BaseConstants): NAME_IN_URL = 'T1' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 21 TREATMENT = 1 EXPERT_ROLE = 'E' NONEXPERTONE_ROLE = 'NE1' NONEXPERTTWO_ROLE = 'NE2' HISTORY_TEMPLATE = 'T1/DocHistory.html' MESSAGE_TEMPLATE = 'T1/DocOtherMessage.html' VOTE_TEMPLATE_HIST = 'T1/DocOtherVoteHist.html' VOTE_TEMPLATE = 'T1/DocOtherVote.html' MESSAGEDETAIL_TEMPLATE = 'T1/DocOtherMessage2.html' INFO_TEMPLATE = 'T1/DocBlock1.html' TWO_TEMPLATE = 'T1/DocBlock2.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): decision = models.IntegerField() truth = models.IntegerField() red_vote = models.IntegerField(initial=0) blue_vote = models.IntegerField(initial=0) red_message = models.IntegerField(initial=0) blue_message = models.IntegerField(initial=0) message_number = models.IntegerField(initial=0) vote_number = models.IntegerField(initial=0) class Player(BasePlayer): def round_number_minus_one(self): return self.round_number - 1 cubicle_number = models.IntegerField(label='Please enter your cubicle number') signal = models.IntegerField() vote = models.IntegerField(choices=[[1, 'vote for RED '], [-1, 'vote for BLUE '], [0, 'abstain (not vote)']], widget=widgets.RadioSelectHorizontal, label='You choose to' ) message = models.IntegerField( choices=[[1, '"My information suggests RED "'], [-1, '"My information suggests BLUE "'], [0, 'nothing (i.e., you do not send any messages)']], widget=widgets.RadioSelectHorizontal, label='You choose to send a message that says' ) other_message_number = models.IntegerField(initial=0) other_vote_number = models.IntegerField(initial=0) #quiz ####quiz quiz1 = models.IntegerField( label='', choices=[ [1, 'both 60%'], [2, 'both 90%'], [3, '60% and 90%, respectively'], [4, 'not known'], ], widget=widgets.RadioSelectHorizontal ) quiz2 = models.IntegerField( label='', choices=[ [1, 'BLUE'], [2, 'RED'], [3, 'not known'], ], widget=widgets.RadioSelectHorizontal ) # quiz2 = models.IntegerField( # label='', # choices=[ # [1, 'both suggest RED'], # [2, 'both suggest BLUE'], # [3, 'suggest RED and BLUE respectively'], # [4, 'is not known'], # ], # widget=widgets.RadioSelectHorizontal # ) quiz3 = models.BooleanField( label='', choices=[True, False], widget=widgets.RadioSelectHorizontal) quiz0 = models.BooleanField( label='', choices=[True, False], widget=widgets.RadioSelectHorizontal) quiz4 = models.IntegerField( label='', choices=[ [1, 'some members in the group'], [2, 'all members in the group'], [3, 'no one'], [3, 'not sure'], ], widget=widgets.RadioSelectHorizontal ) quiz5 = models.BooleanField( label='', choices=[True, False], widget=widgets.RadioSelectHorizontal) quiz6 = models.IntegerField( label='', choices=[ [1, 'higher than 120 points'], [2, '120 points'], [3, 'lower than 120 points but higher than 0 points'], [4, '0 points'], [5, 'It depends on other conditions.'], ], widget=widgets.RadioSelectHorizontal ) quiz7 = models.IntegerField( label='', choices=[ [1, 'higher than 120 points'], [2, '120 points'], [3, 'lower than 120 points but higher than 0 points'], [4, '0 points'], [5, 'It depends on other conditions.'], ], widget=widgets.RadioSelectHorizontal ) quiz8 = models.BooleanField( label='', choices=[True, False], widget=widgets.RadioSelectHorizontal) quiz9 = models.IntegerField( label='', choices=[ [1, 'higher than 120 points'], [2, '120 points'], [3, 'lower than 120 points but higher than 0 points'], [4, '0 points'], [5, 'It depends on other conditions.'], ], widget=widgets.RadioSelectHorizontal ) #historyadd group_message_red = models.IntegerField() group_message_blue = models.IntegerField() group_message_number = models.IntegerField() group_vote_red = models.IntegerField() group_vote_blue = models.IntegerField() group_vote_number = models.IntegerField() group_decision = models.IntegerField() group_truth = models.IntegerField() #payment final_payment = models.CurrencyField() round_picked_one = models.IntegerField() round_picked_two = models.IntegerField() # survey and so on iban_number = models.StringField(label='Please enter your IBAN number') iban_number_2 = models.StringField(label='Please enter it again to avoid mistake') age = models.IntegerField(label='Your age is') gender = models.IntegerField( label='Your gender is', choices=[ [1, 'female'], [2, 'male'], [3, 'non-binary'], [4, 'prefer not to say'], [5, 'other (please specify below)'] ], widget=widgets.RadioSelect ) other_gender = models.LongStringField(blank=True,label="") education= models.IntegerField( blank=True, label='Your current educational status is', choices=[ [1, 'Bachelor student'], [2, 'Master student'], [3, 'PhD student'], [4, 'prefer not to say'], [5, 'other (please specify below)'] ], widget=widgets.RadioSelect ) other_education = models.LongStringField(label="",blank=True) nationality = models.StringField(blank=True, label='Your nationality is') comment = models.LongStringField(blank=True, label='Any comments or feedbacks? (for example, whether and how clear/interesting/diffucult the experiment is, how you make the decisions, or any other observations you would like to share.)') hypoquestion = models.IntegerField( label='A hypothetical question (not affecting your payment). Suppose that in a group, one person has information suggesting BLUE with a 90% correctness probability, while the other two persons both have information suggesting RED with a 60% correctness probability. To maximize their chances of winning the prize, which box should this group choose? ', choices=[ [1, 'RED'], [2, 'BLUE'], [3, 'I do not know./It is hard to say.'], ], widget=widgets.RadioSelectHorizontal ) hypoquestionfollow = models.IntegerField( blank=True, label='If you choose RED or BLUE in the question above, how confident are you about your answer?(from 1-5 point, a higher number means that you are more confident)', choices=[1,2,3,4,5 ], widget=widgets.RadioSelectHorizontal ) # FUNCTIONS def creating_session(subsession): subsession.group_randomly() def round_start(group: Group): group.decision = 0 group.red_vote = 0 group.blue_vote = 0 group.red_message = 0 group.blue_message = 0 group.message_number = 0 group.vote_number = 0 group.round_number = group.round_number-1 group.truth = random.choice([1, 0]) for p in group.get_players(): if p.role == 'E': x = random.choices([group.truth, 1 - group.truth], weights=(90, 10), k=1) p.signal = x[0] if p.role != 'E': x = random.choices([group.truth, 1 - group.truth], weights=(60, 40), k=1) p.signal = x[0] def comm_reveal(group: Group): players = group.get_players() for p in players: if p.message == 1: group.red_message = group.red_message + 1 if p.message == -1: group.blue_message = group.blue_message + 1 group.message_number = group.red_message + group.blue_message # return dict(others=p.get_others_in_group()) for p in players: if p.message == 0: p.other_message_number = group.message_number if p.message != 0: p.other_message_number = group.message_number - 1 def set_payoffs(group: Group): players = group.get_players() for p in players: if p.vote == 1: group.red_vote = group.red_vote + 1 if p.vote == -1: group.blue_vote = group.blue_vote + 1 group.vote_number = group.red_vote + group.blue_vote if group.red_vote > group.blue_vote: group.decision = 1 elif group.red_vote < group.blue_vote: group.decision = 0 else: group.decision = random.choice([1, 0]) for p in players: if group.decision == group.truth: p.payoff = 3 else: p.payoff = 0 if p.round_number == C.NUM_ROUNDS: participant = p.participant x = random.sample(range(2, C.NUM_ROUNDS+1), 2) p.round_picked_one = x[0] p.round_picked_two = x[1] player_in_selected_round_one = p.in_round(p.round_picked_one) player_in_selected_round_two = p.in_round(p.round_picked_two) p.final_payment = player_in_selected_round_one.payoff + player_in_selected_round_two.payoff participant.payoff = p.final_payment #historyadd p.group_message_red = group.red_message p.group_message_blue = group.blue_message p.group_message_number = group.message_number p.group_vote_red = group.red_vote p.group_vote_blue = group.blue_vote p.group_vote_number = group.vote_number p.group_decision = group.decision p.group_truth = group.truth class Cubicle(Page): form_model = 'player' form_fields = ['cubicle_number'] def is_displayed(player: Player): return player.round_number == 1 class Instruction1(Page): def is_displayed(player: Player): return player.round_number == 1 class Instruction2(Page): def is_displayed(player: Player): return player.round_number == 1 class Quiz(Page): def is_displayed(player: Player): return player.round_number == 1 if C.TREATMENT != 1: form_model = 'player' form_fields = ['quiz0', 'quiz1', 'quiz2','quiz4', 'quiz5','quiz6','quiz7'] @staticmethod def error_message(player: Player, values): solutions = dict(quiz0=False,quiz1=3,quiz2=3,quiz4=2,quiz5=False,quiz6=2, quiz7=2) errors = {f: 'Wrong' for f in solutions if values[f] != solutions[f]} if errors: return errors if C.TREATMENT == 1: form_model = 'player' form_fields = ['quiz0', 'quiz1', 'quiz2','quiz6','quiz7'] @staticmethod def error_message(player: Player, values): solutions = dict(quiz0=False,quiz1=3,quiz2=3,quiz6=2, quiz7=2) errors = {f: 'Wrong' for f in solutions if values[f] != solutions[f]} if errors: return errors class Wait(WaitPage): after_all_players_arrive = round_start class Comm(Page): def is_displayed(player: Player): return C.TREATMENT != 1 form_model = 'player' form_fields = ['message'] @staticmethod def vars_for_template(player: Player): return dict(me_previous=player.in_previous_rounds()) class WaitComm(WaitPage): if C.TREATMENT != 1: after_all_players_arrive = comm_reveal # # class CommReveal(Page): # def is_displayed(player: Player): # return C.TREATMENT != 1 # # @staticmethod # def vars_for_template(player: Player): # return dict(me_previous=player.in_previous_rounds()) class Vote(Page): form_model = 'player' form_fields = ['vote'] @staticmethod def vars_for_template(player: Player): return dict(me_previous=player.in_previous_rounds(), others=player.get_others_in_group() ) # @staticmethod # def vars_for_template(player: Player): # return dict(others=player.get_others_in_group()) # for o in others: # o.message == 1 class Signal(Page): def vars_for_template(player: Player): return dict(me_previous=player.in_previous_rounds(), others=player.get_others_in_group() ) class ResultsWaitPage(WaitPage): body_text = "Waiting for the other group members to decide." after_all_players_arrive = set_payoffs class ResultsVote(Page): def vars_for_template(player: Player): return dict(me_previous=player.in_previous_rounds(), others=player.get_others_in_group() ) class Results(Page): def vars_for_template(player: Player): return dict(me_previous=player.in_previous_rounds(), others=player.get_others_in_group() ) # @staticmethod # def vars_for_template(player: Player): # return dict(other_player_units=other_player(player).units) class FinalResults(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['iban_number','iban_number_2'] class Survey(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['hypoquestion', 'hypoquestionfollow','comment', 'age', 'nationality','gender','other_gender', 'education','other_education'] class Ending(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS class AfterTrial(Page): def is_displayed(player: Player): return player.round_number == 1 # page_sequence = [Wait, Cubicle, Instruction1, Instruction2, Quiz, # Signal, Comm, WaitComm, Vote, ResultsWaitPage, Results, FinalResults, Survey, Ending] # page_sequence = [Wait, Cubicle,Instruction1, Instruction2, Quiz, # Signal, Comm, WaitComm, Vote, ResultsWaitPage, ResultsVote, Results, AfterTrial, FinalResults, Survey, Ending] page_sequence = [Wait, Cubicle,Instruction1, Instruction2,Quiz, Signal, Comm, WaitComm, Vote, ResultsWaitPage, ResultsVote, Results,AfterTrial, FinalResults, Survey, Ending] # # # page_sequence = [Survey, # # ] # page_sequence = [Instruction1, Instruction2, # ]