from otree.api import * import random doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'HMMS' players_per_group = 2 num_rounds = 7 cost = random.randint(1, 200) class Subsession(BaseSubsession): pass class Group(BaseGroup): actual_cost = models.IntegerField() budget = models.IntegerField(max=200) accepted = models.IntegerField( choices=( [1, "Accept"], [2, "Reject"]), widget=widgets.RadioSelect, label=" " ) superior = models.StringField() subordinate = models.StringField() has_dropout = models.BooleanField(inital=0) # pair = models.StringField() class Player(BasePlayer): payoff_round = models.IntegerField() is_dropout = models.BooleanField(initial=0) pronoun = models.IntegerField( choices=( [1, "He"], [2, "She"], [3, "They"]), widget=widgets.RadioSelect, label="Preferred Pronoun:" ) initial = models.StringField( label="First Initial:", max_length=1) limit = models.IntegerField(min=0, max=200, label=" ") accept_limit = models.IntegerField(min=0, max=200, label="At what reported budget would you have accepted " "the budget?") cost_q = models.IntegerField(max=200, label="What do you think the actual cost was?") lira = models.IntegerField() def make_field(label): return models.IntegerField( choices=[ [1, "True"], [2, "False"], ], label=label, widget=widgets.RadioSelect, ) q1e = make_field('You will perform the task in this study for 7 rounds.') q2e = make_field('The Manager will learn your actual project cost for each round.') q3e = make_field('If the Manager rejects your reported budget, you will receive 0 Lira and the Manager will ' 'receive 0 Lira for that round.') q4e = make_field('If the Manager accepts your reported budget, then you will get to keep any difference ' 'between your reported budget and the actual project cost.') q5e = make_field('You will be matched to the same Manager in every round, who will review your reported budget for ' '7 rounds. ') q1m = make_field('You will perform the task in this study for 7 rounds.') q2m = make_field('You will learn the Employee’s actual project cost for each round.') q3m = make_field('For each round, after learning the Employee’s reported budget, you will need to decide whether ' 'to approve or reject the reported budget. ') q4m = make_field('If you approve the Employee’s reported budget, you will receive earnings from any difference ' 'between 250 Lira and the Employee’s reported budget.') q5m = make_field('If you reject the Employee’s reported budget, you will receive 0 Lira and the Employee ' 'will receive 0 Lira for that round. ') q6m = make_field('You will be matched to the same Employee in every round and review their reported budget ' 'for 7 rounds.') peq1e = models.IntegerField(min=0, max=200, label=" ") peq2e = models.IntegerField( choices=( [1, "1 - Not Intimidating"], [2, "2 "], [3, "3 "], [4, "4 - Somewhat Intimidating"], [5, "5 "], [6, "6 "], [7, "7 - Very Intimidating"] ), widget=widgets.RadioSelectHorizontal, label="How intimidating did you find your manager to be?" ) peq1m = models.IntegerField(min=0, max=200, label=" ") peq2m = models.IntegerField( choices=( [1, "1 - Not Intimidating"], [2, "2 "], [3, "3 "], [4, "4 - Somewhat Intimidating"], [5, "5 "], [6, "6 "], [7, "7 - Very Intimidating"] ), widget=widgets.RadioSelectHorizontal, label="How intimidating do you believe your employee found you to be?" ) peq3 = models.IntegerField( choices=( [1, "Employee"], [2, "Manager"]), widgets=widgets.RadioSelect, label="If you were to complete this study again, would you prefer the role of the employee or the manager?" ) peq4 = models.IntegerField( choices=( [1, "Female"], [2, "Male"]), widgets=widgets.RadioSelect, label="In general, do you prefer a male or female supervisor?" ) peq5 = models.IntegerField( label="What is your age?" ) peq6 = models.IntegerField( choices=( [1, "1 - Not Honest"], [2, "2 "], [3, "3 "], [4, "4 - Somewhat Honest"], [5, "5 "], [6, "6 "], [7, "7 - Very Honest"] ), widget=widgets.RadioSelectHorizontal, label="In general, how honest of a person do you consider yourself?" ) peq7 = models.IntegerField( choices=( [1, "1 - Completely Unwilling"], [2, "2 "], [3, "3 "], [4, "4 "], [5, "5 "], [6, "6 "], [7, "7 - Completely Willing"] ), widget=widgets.RadioSelectHorizontal, label="In general, how willing are you to take risks?" ) # FUNCTIONS def creating_session(subsession): for player in subsession.get_players(): import random player.payoff_round = random.randint(1, Constants.num_rounds) def budget_min(group): return group.actual_cost def cost_q_max(player): return player.group.budget def set_payoffs(group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) if group.accepted == 1: p1.lira = 100 + (group.budget - group.actual_cost) p2.lira = 250 - group.budget else: p1.lira = 0 p2.lira = 0 def set_pairs(group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) if p2.pronoun == 1: group.superior = "M" if p2.pronoun == 2: group.superior = "F" if p2.pronoun == 3: group.superior = "T" if p1.pronoun == 1: group.subordinate = "M" if p1.pronoun == 2: group.subordinate = "F" if p1.pronoun == 3: group.subordinate = "T" print("Superior:", group.superior, "Subordinate:", group.subordinate) # PAGES class Gender(Page): timeout_seconds = 60 form_model = 'player' form_fields = ["initial", "pronoun"] @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def before_next_page(player: Player, timeout_happened): player.participant.vars['pronoun'] = player.pronoun player.participant.vars['initial'] = player.initial class General_Instructions(Page): timeout_seconds = 120 @staticmethod def is_displayed(player: Player): return player.round_number == 1 class GroupWaitPage(WaitPage): title_text = "Please wait briefly for your partner." @staticmethod def is_displayed(player: Player): return player.round_number == 1 group_by_arrival_time = True class Instructions(Page): timeout_seconds = 120 @staticmethod def is_displayed(player: Player): return player.round_number == 1 class QuizEmployee(Page): timeout_seconds = 120 @staticmethod def is_displayed(player: Player): return player.round_number == 1 and player.id_in_group == 1 form_model = 'player' form_fields = ["q1e", "q2e", "q3e", "q4e", "q5e"] @staticmethod def error_message(player, values): solutions = dict( q1e=1, q2e=2, q3e=1, q4e=1, q5e=1, ) error_messages = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_messages[field_name] = 'Your answer is incorrect. Please try again.' return error_messages class QuizManager(Page): timeout_seconds = 120 @staticmethod def is_displayed(player: Player): return player.round_number == 1 and player.id_in_group == 2 form_model = 'player' form_fields = ["q1m", "q2m", "q3m", "q4m", "q5m", "q6m"] @staticmethod def error_message(player, values): solutions = dict( q1m=1, q2m=2, q3m=1, q4m=1, q5m=1, q6m=1, ) error_messages = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_messages[field_name] = 'Your answer is incorrect. Please try again.' return error_messages class DropoutTest(Page): timeout_seconds = 10 @staticmethod def before_next_page(player: Player, timeout_happened): group = player.group if timeout_happened: group.has_dropout = 1 player.is_dropout = 1 else: group.has_dropout = 0 player.is_dropout = 0 class WaitForCosts(WaitPage): @staticmethod def after_all_players_arrive(group: Group): group.actual_cost = random.randint(1, 200) print(group.actual_cost) if group.round_number == 1: set_pairs(group) class MeetWaitPage(WaitPage): timeout_seconds = 60 @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Budget(Page): timeout_seconds = 60 form_model = 'group' form_fields = ['budget'] @staticmethod def is_displayed(player: Player): return player.id_in_group == 1 @staticmethod def vars_for_template(player: Player): cost = player.group.actual_cost pronoun = player.group.get_player_by_id(2).participant.vars['pronoun'] initial = player.group.get_player_by_id(2).participant.vars['initial'] if pronoun == 1: pn = "he" pn2 = "his" image = 'global/HMMS/male.jpg' elif pronoun == 2: pn = "she" pn2 = "her" image = 'global/HMMS/female.jpg' elif pronoun == 3: pn = "they" pn2 = "their" image = 'global/HMMS/nb.jpg' return dict( cost=cost, pn=pn, pn2=pn2, image=image, initial=initial) class WaitForP1(WaitPage): @staticmethod def is_displayed(player: Player): return player.id_in_group == 2 class Approve(Page): timeout_seconds = 60 form_model = 'group' form_fields = ['accepted'] @staticmethod def is_displayed(player: Player): return player.id_in_group == 2 @staticmethod def vars_for_template(player: Player): pronoun = player.group.get_player_by_id(1).participant.vars['pronoun'] if pronoun == 1: pn = "He" pn2 = "his" image = 'global/HMMS/male.jpg' elif pronoun == 2: pn = "She" pn2 = "her" image = 'global/HMMS/female.jpg' elif pronoun == 3: pn = "They" pn2 = "their" image = 'global/HMMS/nb.jpg' return dict( pn=pn, pn2=pn2, image=image) class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs class Limit(Page): timeout_seconds = 60 form_model = 'player' form_fields = ['cost_q'] @staticmethod def is_displayed(player: Player): return player.id_in_group == 2 @staticmethod def vars_for_template(player: Player): pronoun = player.group.get_player_by_id(1).participant.vars['pronoun'] if pronoun == 1: pn = "he" pn2 = "his" image = 'global/HMMS/male.jpg' elif pronoun == 2: pn = "she" pn2 = "her" image = 'global/HMMS/female.jpg' elif pronoun == 3: pn = "they" pn2 = "their" image = 'global/HMMS/nb.jpg' if player.group.accepted == 2: limit = '{{ formfield "accept_limit" }}' else: limit = '{{ formfield "reject_limit" }}' return dict( limit=limit, pn=pn, pn2=pn2, image=image ) class ResultsManager(Page): def is_displayed(player: Player): return player.id_in_group == 2 @staticmethod def vars_for_template(player: Player): pronoun = player.group.get_player_by_id(1).participant.vars['pronoun'] if player.group.accepted == 1: approval = "approved" else: approval = "rejected" if pronoun == 1: pn = "He" pn2 = 'his' image = 'global/HMMS/male.jpg' elif pronoun == 2: pn = "She" pn2 = 'her' image = 'global/HMMS/female.jpg' elif pronoun == 3: pn = "They" pn2 = 'their' image = 'global/HMMS/nb.jpg' return dict( approval=approval, pn=pn, pn2=pn2, image=image ) class ResultsEmployee(Page): def is_displayed(player: Player): return player.id_in_group == 1 @staticmethod def vars_for_template(player: Player): pronoun = player.group.get_player_by_id(2).participant.vars['pronoun'] initial = player.group.get_player_by_id(2).participant.vars['initial'] if player.group.accepted == 1: approval = "approved" else: approval = "rejected" if pronoun == 1: pn = "He" pn2 = 'his' image = 'global/HMMS/male.jpg' elif pronoun == 2: pn = "She" pn2 = 'her' image = 'global/HMMS/female.jpg' elif pronoun == 3: pn = "They" pn2 = 'their' image = 'global/HMMS/nb.jpg' return dict( approval=approval, pn=pn, pn2=pn2, image=image, initial=initial ) class ThankYou(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds @staticmethod def vars_for_template(player: Player): final_lira = player.in_round(player.payoff_round).lira player.payoff = final_lira/50 total = player.payoff + 1 return dict( payoff=player.payoff, lira=final_lira, total=total, ) class MeetManager(Page): timeout_seconds = 60 def is_displayed(player: Player): return player.round_number == 1 and player.id_in_group == 1 @staticmethod def vars_for_template(player: Player): pronoun = player.group.get_player_by_id(2).participant.vars['pronoun'] initial = player.group.get_player_by_id(2).participant.vars['initial'] if pronoun == 1: pn = "He" image = 'global/HMMS/male.jpg' elif pronoun == 2: pn = "She" image = 'global/HMMS/female.jpg' elif pronoun == 3: pn = "They" image = 'global/HMMS/nb.jpg' return dict( pn=pn, initial=initial, image=image) class MeetEmployee(Page): timeout_seconds = 60 def is_displayed(player: Player): return player.round_number == 1 and player.id_in_group == 2 @staticmethod def vars_for_template(player: Player): pronoun = player.group.get_player_by_id(1).participant.vars['pronoun'] initial = player.group.get_player_by_id(1).participant.vars['initial'] if pronoun == 1: pn = "He" pn2 = 'his' image = 'global/HMMS/male.jpg' elif pronoun == 2: pn = "She" pn2 = 'her' image = 'global/HMMS/female.jpg' elif pronoun == 3: pn = "They" pn2 = 'their' image = 'global/HMMS/nb.jpg' return dict( pn=pn, pn2=pn2, initial=initial, image=image) class PEQManager(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds and player.id_in_group == 2 form_model = 'player' form_fields = ["peq2m", "peq3", "peq4", "peq5", "peq6", "peq7"] class PEQManager1(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds and player.id_in_group == 2 def vars_for_template(player: Player): initial = player.group.get_player_by_id(1).participant.vars['initial'] return dict( initial=initial) form_model = 'player' form_fields = ["peq1m"] class PEQEmployee(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds and player.id_in_group == 1 form_model = 'player' form_fields = ["peq2e", "peq3", "peq4", "peq5", "peq6", "peq7"] class PEQEmployee1(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds and player.id_in_group == 1 def vars_for_template(player: Player): initial = player.group.get_player_by_id(2).participant.vars['initial'] return dict( initial=initial) form_model = 'player' form_fields = ["peq1e"] class WaitPageGender(WaitPage): def is_displayed(player: Player): return player.round_number == 1 class WaitForOthers(WaitPage): @staticmethod def before_next_page(player: Player): if player.is_dropout: player.payoff = 0 else: player.payoff = 6.80 class DropoutHappened(Page): @staticmethod def is_displayed(player: Player): return player.group.has_dropout == True page_sequence = [GroupWaitPage, General_Instructions, Instructions, QuizEmployee, QuizManager, WaitPageGender, Gender, MeetWaitPage, MeetManager, MeetEmployee, DropoutTest, WaitForOthers, DropoutHappened, WaitForCosts, Budget, WaitForP1, Approve, ResultsWaitPage, Limit, ResultsEmployee, ResultsManager, PEQManager1, PEQEmployee1, PEQManager, PEQEmployee, ThankYou]