from otree.api import * import random doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'misfortune' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 1 # oTree will then automatically assign each role to a different player # has to end up with _ROLE # (sequentially according to id_in_group). PRINCIPAL_ROLE = 'allocator' AGENT1_ROLE = 'recipient_1' AGENT2_ROLE = 'recipient_2' class Subsession(BaseSubsession): pass # creating_session should not be inside any class # to check if shuffles correctly, open your browser to the Results tab def creating_session(subsession: Subsession): subsession.group_randomly() # shuffles players randomly, which will randomly decide their roles print(subsession.get_group_matrix()) # subsession.random_number = random.randint(1, 3) # print('random_number:', subsession.random_number) class Group(BaseGroup): pass class Player(BasePlayer): total_payoff = models.FloatField() ExNo = models.IntegerField(label="Enter your experimental number as shown on your desk:") dis3_1 = models.FloatField() dis3_2 = models.FloatField() dis0_1 = models.FloatField() dis0_2 = models.FloatField() dis03_1 = models.FloatField() dis03_2 = models.FloatField() payoff_1 = models.IntegerField() payoff_2 = models.FloatField() CQ_1 = models.StringField( label="How will you be paid by the whole study?", choices=[ ['A', 'Fixed payment and the payment for one randomly selected task.'], ['B', 'Fixed payment and the payments for two tasks.'], ], widget=widgets.RadioSelect ) CQ_2 = models.StringField( label="How will you be paid for Part 1?", choices=[ ['A', 'The majority will earn $3, and the minority will earn $0 after finishing the task.'], ['B', 'Half will earn $3, and half will earn $0 after finishing the task.'], ['C', 'The majority will earn $0 and the minority will earn $3 after finishing the task.'], ], widget=widgets.RadioSelect ) CQ_3 = models.StringField( label="If you are selected as the allocator, how much will you be paid for Part 2?", choices=[ ['A', '$X, which is fixed.'], ['B', '$X, which depends on your allocation decisions.'], ], widget=widgets.RadioSelect ) CQ_4 = models.StringField( label="If you are selected to be a recipient, how much will you be paid for Part 2?", choices=[ ['A', 'The allocator\'s choice for a random scenario.'], ['B', 'The allocator\'s choice based on the actual scenario you and the other recipient experienced in Part 1.'], ], widget=widgets.RadioSelect ) # PAGES class MyPage(Page): form_model = 'player' form_fields = ['ExNo'] # A Page can have any of the 4 functions, is_displayed(), vars_for_template(), # before_next_page(), timeout_seconds class Part1(Page): pass class CQ1(Page): form_model = 'player' form_fields = ['CQ_1', 'CQ_2'] def error_message(player, value): if value['CQ_1'] != "B": return "Try again." if value['CQ_2'] != 'A': return "Try again." class count1(Page): pass class count2(Page): pass class count3(Page): pass class count4(Page): pass class count5(Page): pass class count6(Page): pass class count7(Page): pass class count8(Page): pass class count9(Page): pass class count10(Page): pass class Result1(Page): form_model = 'player' form_fields = ['payoff_1'] class Part2(Page): pass class CQ2(Page): form_model = 'player' form_fields = ['CQ_3', 'CQ_4'] def error_message(player, value): if value['CQ_3'] != "A": return "Try again." if value['CQ_4'] != 'B': return "Try again." class Allocation(Page): form_model = 'player' form_fields = ['dis3_1', 'dis3_2', 'dis0_1', 'dis0_2', 'dis03_1', 'dis03_2'] class Result2WaitPage(WaitPage): @staticmethod #set payoffs in stage 2 # A WaitPage can have any of the 4 functions, is_displayed(), after_all_players_arrive(), # group_by_arrival_time(),group_by_arrival_time_method(), def after_all_players_arrive(group: Group): principal = group.get_player_by_role(C.PRINCIPAL_ROLE) recipient1 = group.get_player_by_role(C.AGENT1_ROLE) recipient2 = group.get_player_by_role(C.AGENT2_ROLE) # check if we set the roles correctly, and yes, it's correct # print(principal,recipient1,recipient2) # set recipients payoff_2 based on real situation principal.payoff_2 = 2 # set distributor's payoff as X=2 principal.total_payoff = principal.payoff_1 + principal.payoff_2+5 if recipient1.payoff_1 == 3 and recipient2.payoff_1 == 3: # has to use "and", "&" doesn't work recipient1.payoff_2 = principal.dis3_1 recipient2.payoff_2 = principal.dis3_2 print(recipient1.payoff_2, recipient2.payoff_2) recipient1.total_payoff = recipient1.payoff_1 + recipient1.payoff_2+5 recipient2.total_payoff = recipient2.payoff_1 + recipient2.payoff_2+5 elif recipient1.payoff_1 == 0 and recipient2.payoff_1 == 0: recipient1.payoff_2 = principal.dis0_1 recipient2.payoff_2 = principal.dis0_2 print(recipient1.payoff_2, recipient2.payoff_2) recipient1.total_payoff = recipient1.payoff_1 + recipient1.payoff_2+5 recipient2.total_payoff = recipient2.payoff_1 + recipient2.payoff_2+5 elif recipient1.payoff_1 == 0 and recipient2.payoff_1 == 3: recipient1.payoff_2 = principal.dis03_1 recipient2.payoff_2 = principal.dis03_2 print(recipient1.payoff_2, recipient2.payoff_2) recipient1.total_payoff = recipient1.payoff_1 + recipient1.payoff_2+5 recipient2.total_payoff = recipient2.payoff_1 + recipient2.payoff_2+5 else: recipient1.payoff_2 = principal.dis03_2 recipient2.payoff_2 = principal.dis03_1 print(recipient1.payoff_2, recipient2.payoff_2) recipient1.total_payoff = recipient1.payoff_1 + recipient1.payoff_2+5 recipient2.total_payoff = recipient2.payoff_1 + recipient2.payoff_2+5 class Result2(Page): pass # @staticmethod # def js_vars(player): # return dict( # payoff2=player.payoff_2, # totalpayoff = player.total_payoff, # ) page_sequence = [MyPage, Part1, CQ1, count1, count2, count3, count4, count5, count6, count7, count8, count9, count10, Result1, Part2, CQ2, Allocation, Result2WaitPage, Result2]