from otree.api import * import json from random import randint c = Currency doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'part1' players_per_group = None num_rounds = 3 timer_text = 'Time left:' max_seconds_on_page = dict(p1=90, p2=30, p3=120, dice_page=20, results_intro=30, results=60) exchange_rate_ex_1 = c(6) exchange_rate_ex_2 = c(24) dice = [1, 12] vars_for_templates = dict( part_n=1, use_summary=False, is_example=False, role='', ) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): dropout = models.BooleanField(initial=False, doc="""Only if timed out on P1 page""") timeout = models.BooleanField(initial=False) rolled = models.BooleanField(initial=False) num = models.IntegerField(initial=0) report = models.IntegerField( label="Please report the result of the die roll here:", min=Constants.dice[0], max=Constants.dice[1] ) round_to_pay = models.IntegerField() # FUNCTIONS def live_roll(player: Player, data, rolled_field='rolled'): player.rolled = True player.num = data def set_automatic_report(player: Player, timeout_happened, set_mode='manualset'): if 'manual' not in set_mode: player.report = player.num elif timeout_happened: player.timeout = True num = randint(Constants.dice[0], Constants.dice[1]) player.num = num player.report = num def set_payoff_for_this_part(player: Player, part_num: int): num_rounds = Constants.num_rounds if player.round_number == num_rounds: round_to_pay = randint(1, num_rounds) player.round_to_pay = round_to_pay player.participant.vars[f'payoff_part_{part_num}'] = player.in_round(round_to_pay).report # PAGES class FirstRoundPage(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class WaitingSessionStart(WaitPage): wait_for_all_groups = True body_text = """
Thank you for participating in this experiment. The experiment will start as soon as the minimum number of participant enter this stage.
The experiment can start any second. The maximum waiting time is 5 minutes. The time for this study and the payment are calculated to include this waiting time.
Once the experiment starts you are expected to coninue right away. If you do not make inputs in a timely manner, you will be excluded from the study and you will not receive payment.
Please do not get distracted and pay attention to this page.
""" @staticmethod def is_displayed(player: Player): return player.round_number == 1 class P1(FirstRoundPage): timeout_seconds = Constants.max_seconds_on_page['p1'] timer_text = Constants.timer_text @staticmethod def vars_for_template(player: Player): const = Constants earnings_ex_2 = const.exchange_rate_ex_2.to_real_world_currency(player.session) return dict( earnings_ex_1=const.exchange_rate_ex_1.to_real_world_currency(player.session), earnings_ex_2=earnings_ex_2, earnings_ex_2_total=earnings_ex_2 + player.session.config['participation_fee'] ) @staticmethod def before_next_page(player: Player, timeout_happened): if timeout_happened: player.dropout = True player.participant.vars['dropout'] = True @staticmethod def app_after_this_page(player: Player, upcoming_apps): if player.participant.vars.get('dropout'): return upcoming_apps[-1] class P2(FirstRoundPage): timeout_seconds = Constants.max_seconds_on_page['p2'] timer_text = Constants.timer_text class FirstPartWaitingPage(WaitPage): wait_for_all_groups = True class P3(FirstRoundPage): timeout_seconds = Constants.max_seconds_on_page['p3'] timer_text = Constants.timer_text @staticmethod def vars_for_template(player: Player): const = Constants _vars = const.vars_for_templates _vars.update(earnings_ex_1=const.exchange_rate_ex_1.to_real_world_currency(player.session)) return _vars class P4(Page): timeout_seconds = Constants.max_seconds_on_page['dice_page'] timer_text = Constants.timer_text form_model = 'player' form_fields = ['report'] @staticmethod def live_method(player: Player, data): live_roll(player, data) @staticmethod def vars_for_template(player: Player): const = Constants _vars = const.vars_for_templates _vars.update(earnings_ex_1=const.exchange_rate_ex_1.to_real_world_currency(player.session)) return _vars @staticmethod def before_next_page(player: Player, timeout_happened): set_automatic_report(player, timeout_happened) set_payoff_for_this_part(player, 1) class ResultsIntro(Page): timeout_seconds = Constants.max_seconds_on_page['results_intro'] timer_text = Constants.timer_text @staticmethod def vars_for_template(player: Player): const = Constants _vars = const.vars_for_templates _vars.update(earnings_ex_1=const.exchange_rate_ex_1.to_real_world_currency(player.session)) return _vars @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds class Results(Page): timeout_seconds = Constants.max_seconds_on_page['results'] timer_text = Constants.timer_text @staticmethod def vars_for_template(player: Player): const = Constants _vars = const.vars_for_templates _vars.update( earnings_ex_1=const.exchange_rate_ex_1.to_real_world_currency(player.session), report=player.participant.vars['payoff_part_1'] ) return _vars @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds page_sequence = [WaitingSessionStart, P1, P2, P3, P4, ResultsIntro, Results]