import random import string from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'experiment2' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 payoffShowup = cu(1.5) payoffW = cu(0.7) payoffL = cu(0.1) class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): for p in subsession.get_players(): p.is_dropout = False p.is_dropout_intro = False class Group(BaseGroup): lotteryOutcome = models.StringField() firstreport = models.IntegerField(choices=[[1, "WON"],[2, "LOST"]], label="Did you win or lose the lottery?", widget=widgets.RadioSelect) secondreport = models.IntegerField(choices=[[1, "WON"],[2, "LOST"]], label="Did you win or lose the lottery?", widget=widgets.RadioSelect) position = models.IntegerField(choices=[[0, "First"],[1, "Second"]], label="Do you want to report the outcome first or second?", widget=widgets.RadioSelect) coinflip = models.IntegerField(initial=0) coinflip2 = models.IntegerField(initial=0) class Player(BasePlayer): code = models.StringField() comprehension1 = models.IntegerField(choices=[[1, C.payoffW],[2, C.payoffL]], label="Suppose the other participant reports \"WON\" and you report \"LOST\". What is the bonus that each of you get?", widget=widgets.RadioSelect) comprehension2 = models.IntegerField(choices=[[1, C.payoffW],[2, C.payoffL]], label="Suppose both of you report \"WON\". What is the bonus that each of you get?", widget=widgets.RadioSelect) comprehension1Fail = models.IntegerField(initial=0) comprehension2Fail = models.IntegerField(initial=0) pos = models.IntegerField() posText = models.StringField() demoAge = models.IntegerField(label="How old are you?") demoGender = models.IntegerField(choices=[[1, 'Male'],[2, 'Female'],[3, 'Other'],[4, 'Prefer not to answer']],widget=widgets.RadioSelect, label="What is your gender?") demoEducation = models.IntegerField(choices=[[1, 'No degree'],[2, 'Some school degree lower than high school'],[3, 'High school degree'],[4, 'Bachelor\'s degree'],[5, 'Master\'s degree or higher']], label="What is your highest level of education?") demoRisk = models.IntegerField(choices=[[0,0],[1,1],[2,2],[3,3],[4,4],[5,5],[6,6],[7,7],[8,8],[9,9],[10,10]], label="How willing are you in general to take risks on a scale from 0 (not willing to take risks at all) to 10 (highly willing to take risks)?") moral1 = models.IntegerField(choices=[[0,0],[1,1],[2,2],[3,3],[4,4]], label="Situation 1: Imagine the unlikely case occurs that you flip 4 tails. How many tails will you report to the host") moral2 = models.IntegerField(choices=[[0,0],[1,1],[2,2],[3,3],[4,4]], label="Situation 2: Imagine the unlikely case occurs that you flip 0 tails. How many tails will you report to the host") timeout_report = models.BooleanField() timeout_position = models.BooleanField() is_dropout = models.BooleanField() is_dropout_intro = models.BooleanField() def lottery(group): if group.coinflip==0: group.coinflip = random.randint(1,4) if group.coinflip==1: group.lotteryOutcome = "WON" else: group.lotteryOutcome = "LOST" def posdecision(group): if group.coinflip2==0: group.coinflip2 = random.randint(1,2) players = group.get_players() for player in players: if group.coinflip2 == 1: player.pos = players.index(player) else: player.pos = 1 - players.index(player) if player.pos==0: player.posText="first" else: player.posText="second" # PAGES class MyWaitPage(WaitPage): title_text = "Please wait" body_text = "Waiting for another participant to accept this HIT." after_all_players_arrive = 'posdecision' class intro1(Page): @staticmethod def vars_for_template(player: Player): player.code = ''.join(random.choices(string.ascii_uppercase + string.digits, k=6)) return dict(code=player.code) timeout_seconds=60 @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.is_dropout_intro = True class part1(Page): pass timeout_seconds = 5 class part2(Page): pass @staticmethod def get_timeout_seconds(player): if player.is_dropout: return 0.01 else: return 5 class intro2(Page): @staticmethod def get_timeout_seconds(player): if player.is_dropout_intro: return 30 else: return 90 @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.is_dropout = True class comprehension(Page): form_model = 'player' form_fields = ['comprehension1', 'comprehension2'] @staticmethod def get_timeout_seconds(player): if player.is_dropout_intro: return 30 else: return 90 @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.is_dropout = True def error_message(player, values): if values['comprehension1'] != 2 and values['comprehension2'] != 1: player.comprehension1Fail+=1 player.comprehension2Fail+=1 return 'If one of you reports LOST, you receive the low bonus. If both of you report WON, you receive the high bonus. ' \ 'Please enter the correct amounts.' elif values['comprehension1'] != 2: player.comprehension1Fail+=1 return 'If one of you reports LOST, you receive the low bonus. Please enter the correct amount.' elif values['comprehension2'] != 1: player.comprehension2Fail+=1 return 'If both of you report WON, you receive the high bonus. Please enter the correct amount.' class ChoiceWaitPage1(WaitPage): after_all_players_arrive = 'lottery' class position1(Page): @staticmethod def get_timeout_seconds(player): if player.is_dropout: return 0.01 else: return 30 @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.is_dropout = True class position2(Page): form_model = 'group' form_fields = ['position'] @staticmethod def is_displayed(player): return player.pos == 0 @staticmethod def get_timeout_seconds(player): if player.is_dropout: return 0.01 else: return 30 @staticmethod def before_next_page(player: Player, timeout_happened): if timeout_happened: player.is_dropout = True player.timeout_position = True player.group.position = 1 class result(Page): @staticmethod def get_timeout_seconds(player): if player.is_dropout: return 0.01 else: return 60 @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.is_dropout = True class report1(Page): form_model = 'group' form_fields = ['firstreport'] @staticmethod def is_displayed(player): return player.pos==player.group.position @staticmethod def get_timeout_seconds(player): if player.is_dropout: return 0.01 else: return 60 @staticmethod def before_next_page(player: Player, timeout_happened): if timeout_happened: player.is_dropout = True player.timeout_report = True if player.group.lotteryOutcome == "WON": player.group.firstreport = 1 else: player.group.firstreport = random.randint(1, 2) @staticmethod def error_message(player, values): if player.group.lotteryOutcome == "WON" and values['firstreport'] == 2: return 'You have WON the lottery!' class WaitForP1(WaitPage): @staticmethod def is_displayed(player): return player.pos!=player.group.position class report2(Page): form_model = 'group' form_fields = ['secondreport'] @staticmethod def is_displayed(player): return player.pos!=player.group.position @staticmethod def vars_for_template(player): group = player.group if group.firstreport == 1: text = "WON" else: text = "LOST" return dict( otherreport = text ) @staticmethod def get_timeout_seconds(player): if player.is_dropout: return 0.01 else: return 60 @staticmethod def before_next_page(player: Player, timeout_happened): if timeout_happened: player.is_dropout = True player.timeout_report = True if player.group.lotteryOutcome == "WON": player.group.secondreport = 1 else: player.group.secondreport = random.randint(1, 2) @staticmethod def error_message(player, values): if player.group.lotteryOutcome == "WON" and values['secondreport'] == 2: return 'You have WON the lottery!' class demo(Page): form_model = 'player' form_fields = ['demoAge', 'demoGender', 'demoEducation', 'demoRisk'] @staticmethod def get_timeout_seconds(player): if player.is_dropout: return 0.01 else: return 240 class moral(Page): form_model = 'player' form_fields = ['moral1', 'moral2'] @staticmethod def get_timeout_seconds(player): if player.is_dropout: return 0.01 else: return 120 class outro(Page): @staticmethod def is_displayed(player): return player.is_dropout == False page_sequence = [MyWaitPage, intro1, part1, intro2, comprehension, position1, position2, ChoiceWaitPage1, result, report1, WaitForP1, report2, part2, demo, moral, outro]