from otree.api import * from part2 import ( Constants as Part2Constants, default_vars_for_template, TaskPage, TaskDice, TaskAutoset, TaskTrading, TaskTradingResultsWaitingPage, TaskTradingResults, set_random_price, set_group, set_task_payoff ) from random import sample c = Currency doc = """ Your app description """ class Constants(Part2Constants): name_in_url = 'part3' num_rounds = 20 max_seconds_on_page = dict( role_page=15, rule_page=15, task=20, price_page=20, task_trading_results=20, next_part_intro=90 ) num_rounds_to_pay = 2 class Subsession(BaseSubsession): pass class Group(BaseGroup): treatment = models.StringField() has_unmatched = models.BooleanField(initial=False) has_dropout = models.BooleanField(initial=False) class Player(BasePlayer): dropout = models.BooleanField(initial=False) timeout = models.BooleanField(initial=False) pair_id = models.IntegerField() game_role = models.StringField(initial='') 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] ) price = models.IntegerField( label='Please set the price for the fictional object:', min=Constants.dice[0], max=Constants.dice[1] ) traded = models.BooleanField(initial=False) round_to_pay_first = models.IntegerField() round_to_pay_second = models.IntegerField() # FUNCTIONS def set_groups_for_all_rounds(subsession: Subsession): group_matrix = subsession.session.group_matrix subsessions = subsession.in_rounds(1, Constants.num_rounds) for s in subsessions: s.set_group_matrix(group_matrix) def set_rounds_to_pay(player: Player): const = Constants rounds_to_pay = sample(list(range(1, Constants.num_rounds+1)), const.num_rounds_to_pay) player.round_to_pay_first, player.round_to_pay_second = rounds_to_pay player.participant.vars['part3_payoff'] = sum(player.in_round(r).payoff for r in rounds_to_pay) def set_vars_for_template_part3(player: Player): return dict( part_n=3, is_example=False, role=player.participant.vars['game_role'], ) # PAGES class GroupingPage(WaitPage): wait_for_all_groups = True after_all_players_arrive = 'set_groups_for_all_rounds' @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def app_after_this_page(player, upcoming_apps): if player.participant.unmatched: return upcoming_apps[-3] class TaskRoundWaitingPage(WaitPage): after_all_players_arrive = set_group class TaskRole(TaskPage): timeout_seconds = Constants.max_seconds_on_page['role_page'] @staticmethod @default_vars_for_template def vars_for_template(player: Player): _vars = set_vars_for_template_part3(player) _vars.update(rule='', display_round_number=True) return _vars @staticmethod def before_next_page(player: Player, timeout_happened): set_random_price(player) class TaskRule(TaskPage): timeout_seconds = Constants.max_seconds_on_page['rule_page'] @staticmethod @default_vars_for_template def vars_for_template(player: Player): rules = Constants.rules _vars = set_vars_for_template_part3(player) _vars.update( rule=rules[0] if player.participant.vars['treatment'] == 'autoset' else rules[1], display_round_number=True ) return _vars class TaskDicePart3(TaskDice): template_name = 'part2/templates/part2/TaskDice.html' @staticmethod @default_vars_for_template def vars_for_template(player: Player): rules = Constants.rules _vars = set_vars_for_template_part3(player) _vars.update( rule=rules[0] if player.participant.vars['treatment'] == 'autoset' else rules[1], display_round_number=True ) return _vars class TaskAutosetPart3(TaskAutoset): template_name = 'part2/templates/part2/TaskAutoset.html' @staticmethod @default_vars_for_template def vars_for_template(player: Player): rules = Constants.rules _vars = set_vars_for_template_part3(player) _vars.update( rule=rules[0] if player.participant.vars['treatment'] == 'autoset' else rules[1], display_round_number=True ) return _vars class TaskTradingPart3(TaskTrading): template_name = 'part2/templates/part2/TaskTrading.html' @staticmethod @default_vars_for_template def vars_for_template(player: Player): rules = Constants.rules _vars = set_vars_for_template_part3(player) _vars.update( rule=rules[0] if player.participant.vars['treatment'] == 'autoset' else rules[1], price=player.price if player.participant.vars['treatment'] == 'manualrand' else 0, display_round_number=True ) return _vars class TaskTradingResultsPart3(TaskTradingResults): template_name = 'part2/templates/part2/TaskTradingResults.html' timeout_seconds = Constants.max_seconds_on_page['task_trading_results'] @staticmethod @default_vars_for_template def vars_for_template(player: Player): rules = Constants.rules _vars = set_vars_for_template_part3(player) _vars.update( rule=rules[0] if player.participant.vars['treatment'] == 'autoset' else rules[1], earnings=int(player.payoff), display_round_number=True ) return _vars class TaskResultsIntro(TaskPage): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod @default_vars_for_template def vars_for_template(player: Player): _vars = set_vars_for_template_part3(player) _vars.update( role='', rule='' ) return _vars @staticmethod def before_next_page(player: Player, timeout_happened): set_rounds_to_pay(player) class TaskResults(TaskPage): @staticmethod def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod @default_vars_for_template def vars_for_template(player: Player): _vars = set_vars_for_template_part3(player) _vars.update( role='', rule='', earnings_first_round=player.in_round(player.round_to_pay_first).payoff, earnings_second_round=player.in_round(player.round_to_pay_second).payoff, earnings=player.participant.vars['part3_payoff'] ) return _vars page_sequence = [ GroupingPage, TaskRoundWaitingPage, TaskRole, TaskRule, TaskDicePart3, TaskAutosetPart3, TaskTradingPart3, TaskTradingResultsWaitingPage, TaskTradingResultsPart3, TaskResultsIntro, TaskResults ]