from otree.api import * import random doc = """ Control_Uncertainty1_PSet 1_TA """ class Constants(BaseConstants): name_in_url = 'U1AH_Fi' history_template = 'U1AH_Fi/history.html' players_per_group = None num_rounds = 30 endowment = 30 exit = 40 A = 12 B = -8 D = -49.9 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): decision = models.StringField( choices=[['Continue', 'Continue'], ['Exit', 'Exit']], label='Do you want to keep running this firm?', widget=widgets.RadioSelect, ) probInd = models.IntegerField() outcome = models.IntegerField() exit = models.IntegerField() bank = models.IntegerField() value = models.IntegerField() treatment = models.IntegerField() game = models.IntegerField(initial=0) cost = models.IntegerField() # Function def set_payoffs(player: Player): subsession = player.subsession session = player.session if player.round_number == 3: player.probInd = 1 # +12 elif player.round_number == 13: player.probInd = 1 # +12 else: player.probInd = 2 # -8 # outcome if subsession.round_number == 1: if player.probInd == 1: player.outcome = Constants.endowment + Constants.A else: player.outcome = Constants.endowment + Constants.B if subsession.round_number > 1: prev_player = player.in_round(player.round_number - 1) if player.probInd == 1: player.outcome = prev_player.outcome + Constants.A else: player.outcome = prev_player.outcome + Constants.B # Round 1_Payoff if subsession.round_number == 1: if player.decision == 'Continue': player.value = Constants.endowment + player.outcome player.exit = player.value - Constants.exit else: player.value = Constants.endowment - Constants.exit # Remaining rounds if subsession.round_number > 1: prev_player = player.in_round(player.round_number - 1) if player.decision == 'Continue': player.value = prev_player.value + player.outcome player.exit = player.value - Constants.exit else: player.value = prev_player.value - Constants.exit # Bankruptcy payoff if subsession.round_number > 1: if player.decision == 'Continue' and player.outcome < Constants.D: player.value = player.value - Constants.exit # Function def game_order(player: Player): subsession = player.subsession session = player.session if subsession.round_number >= 1: player.participant.game = player.game + 1 # PAGES class Intro(Page): @staticmethod def is_displayed(player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): game_order(player) # Call the game_order function here return dict( participant_game=player.participant.game, ) class Choice(Page): form_model = 'player' form_fields = ['decision'] @staticmethod def is_displayed(player): return player.round_number == 1 @staticmethod def vars_for_template(player: Player): return dict( participant_game=player.participant.game, ) @staticmethod def before_next_page(player: Player, timeout_happened): set_payoffs(player) class Choice_2(Page): form_model = 'player' form_fields = ['decision'] @staticmethod def is_displayed(player): if player.round_number > 1: prev_player = player.in_round(player.round_number - 1) return player.round_number > 1 and prev_player.decision == 'Continue' and prev_player.outcome > Constants.D @staticmethod def vars_for_template(player: Player): if player.round_number > 1: prev_player = player.in_round(player.round_number - 1) else: prev_player = None prev_2_player = None if player.round_number > 2: prev_2_player = player.in_round(player.round_number - 2) return dict( past_players=player.in_previous_rounds(), prev_player_decision=prev_player.decision if prev_player else None, prev_player_outcome=prev_player.outcome if prev_player else None, prev_player_outcome_abs=abs(prev_player.outcome) if prev_player else None, prev_player_value=prev_player.value if prev_player else None, prev_player_probInd=prev_player.probInd if prev_player else None, prev_player_exit=prev_player.exit if prev_player else None, prev_player_round=prev_player.round_number if prev_player else None, prev2_player_value=prev_2_player.value if prev_2_player else None, participant_game=player.participant.game, ) @staticmethod def before_next_page(player: Player, timeout_happened): set_payoffs(player) class Exit(Page): @staticmethod def is_displayed(player): return player.round_number == 1 and player.decision == 'Exit' @staticmethod def vars_for_template(player: Player): return dict(past_players=player.in_previous_rounds(), participant_game=player.participant.game, ) @staticmethod def before_next_page(player: Player, timeout_happened): player.participant.cost = Constants.exit @staticmethod def app_after_this_page(player, upcoming_apps): if player.decision == 'Exit': return upcoming_apps[0] class Exit_2(Page): @staticmethod def is_displayed(player): if player.round_number > 1: prev_player = player.in_round(player.round_number - 1) return player.round_number > 1 and prev_player.decision == 'Exit' @staticmethod def vars_for_template(player: Player): if player.round_number > 1: prev_player = player.in_round(player.round_number - 1) return dict( past_players=player.in_previous_rounds(), prev_player_value=prev_player.value, participant_game=player.participant.game, ) @staticmethod def before_next_page(player: Player, timeout_happened): player.participant.cost = Constants.exit @staticmethod def app_after_this_page(player, upcoming_apps): prev_player = player.in_round(player.round_number - 1) if prev_player.decision == 'Exit': return upcoming_apps[0] class Bankruptcy(Page): @staticmethod def is_displayed(player): if player.round_number > 1: prev_player = player.in_round(player.round_number - 1) return player.round_number > 1 and prev_player.decision == 'Continue' and prev_player.outcome <= Constants.D @staticmethod def vars_for_template(player: Player): if player.round_number > 1: prev_player = player.in_round(player.round_number - 1) return dict( past_players=player.in_previous_rounds(), prev_player_bank=prev_player.value, prev_player_round=prev_player.round_number, prev_player_outcome=prev_player.outcome, participant_game=player.participant.game, ) @staticmethod def before_next_page(player: Player, timeout_happened): player.participant.cost = Constants.exit @staticmethod def app_after_this_page(player, upcoming_apps): prev_player = player.in_round(player.round_number - 1) if prev_player.outcome < Constants.D: return upcoming_apps[0] page_sequence = [Intro, Choice, Choice_2, Exit, Exit_2, Bankruptcy]