from otree.api import * import time import random import math from decimal import Decimal class C(BaseConstants): NAME_IN_URL = 'employee_choice_sp' PLAYERS_PER_GROUP = 4 NUM_ROUNDS = 1 class Group(BaseGroup): pass class Subsession(BaseSubsession): pass class OnlineWorkers(ExtraModel): worker_id = models.CharField(max_length=50) class Player(BasePlayer): worker_id = models.CharField(initial='e') mturk_dupe = models.IntegerField(initial=0) participant_number = models.IntegerField(default=0) player_label = models.StringField() condition = models.IntegerField() employee_label = models.StringField(default='A') pay_period = models.IntegerField() informed_consent = models.StringField(initial=None, choices=[('Yes', 'Yes'), ('No', 'No')], verbose_name='', widget=widgets.RadioSelect()) kc1 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc2 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc3 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc4 = models.StringField(initial=None, choices=[('a', 'A points'), ('b', 'B points')], verbose_name='', widget=widgets.RadioSelect()) kc5 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc6 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc7 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc8 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc9 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc10 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) A_points_self = models.IntegerField(verbose_name='', max=50, initial=0) A_points_self_output = models.IntegerField() A_points_Emp2 = models.IntegerField(verbose_name='', max=50, initial=0) A_points_Emp3 = models.IntegerField(verbose_name='', max=50, initial=0) A_points_Emp4 = models.IntegerField(verbose_name='', max=50, initial=0) A_points_output_Emp2 = models.CharField() A_points_output_Emp3 = models.CharField() A_points_output_Emp4 = models.CharField() B_points_self = models.IntegerField(verbose_name='', max=50) B_points_self_output = models.IntegerField() total_self_output = models.IntegerField() B_points_Emp2 = models.IntegerField(verbose_name='', max=50, initial=0) B_points_Emp3 = models.IntegerField(verbose_name='', max=50, initial=0) B_points_Emp4 = models.IntegerField(verbose_name='', max=50, initial=0) B_points_output_Emp2 = models.CharField() B_points_output_Emp3 = models.CharField() B_points_output_Emp4 = models.CharField() A_points_multiplier = models.CharField() B_points_multiplier = models.CharField() total_output_Emp2 = models.CharField() total_output_Emp3 = models.CharField() total_output_Emp4 = models.CharField() A_points_received_Emp2 = models.IntegerField() A_points_received_Emp3 = models.IntegerField() A_points_received_Emp4 = models.IntegerField() A_points_rec_output_Emp2 = models.FloatField() A_points_rec_output_Emp3 = models.FloatField() A_points_rec_output_Emp4 = models.FloatField() B_points_received_Emp2 = models.IntegerField() B_points_received_Emp3 = models.IntegerField() B_points_received_Emp4 = models.IntegerField() B_points_rec_output_Emp2 = models.FloatField() B_points_rec_output_Emp3 = models.FloatField() B_points_rec_output_Emp4 = models.FloatField() total_help_given = models.IntegerField() #Just total input points given (for mgr view) total_help_received = models.IntegerField() #Just total input points received (for mgr view) total_help_output_received = models.FloatField() #Total output points from help received; Add to total_self_output #Plus bonus points below...to get to total points for comp self_compensation = models.StringField() help_compensation = models.StringField() total_compensation = models.StringField() decision_time = models.StringField() perf_evalulation = models.IntegerField(verbose_name='') bonus_points = models.IntegerField(verbose_name='') manager_id = models.IntegerField() #PEQ decision_difficulty = models.StringField(initial=None, choices=[('1', '1 = Not at all difficult.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Somewhat difficult.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Very difficult.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_expectations_personal = models.StringField(initial=None, choices=[('1', '1 = I did not expect others to use any points in this manner.'), ('2', '2 '), ('3', '3 '), ('4', '4 = I expected others to use some points in this manner.'), ('5', '5 '), ('6', '6 '), ('7', '7 = I expected others to use most or all of their points in this manner.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_expectations_general = models.StringField(initial=None, choices=[('1', '1 = I did not expect others to use any points in this manner.'), ('2', '2 '), ('3', '3 '), ('4', '4 = I expected others to use some points in this manner.'), ('5', '5 '), ('6', '6 '), ('7', '7 = I expected others to use most or all of their points in this manner.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) difficulty_choosing_helpee = models.StringField(initial=None, choices=[('1', '1 = Not at all difficult.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Somewhat difficult.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Very difficult.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) relative_helping = models.StringField(initial=None, choices=[('1', '1 = Others used far fewer points than me in this manner.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Others used the same number of points as me in this manner.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Others used far more points than me in this manner.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) obligated_helping = models.StringField(initial=None, choices=[('1', '1 = Not at all.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Somewhat.'), ('5', '5 '), ('6', '6 '), ('7', '7 = A great deal.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_needed = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_deserved = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_synergy = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_grateful = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) manager_wants = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) others_right_thing = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) others_manager_wants = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_feels_good = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_own_reward = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_if_unobservable = models.StringField(initial=None, choices=[('1', '1 = I would have used far fewer points in this manner.'), ('2', '2 '), ('3', '3 '), ('4', '4 = I would have used the same number of points in this manner.'), ('5', '5 '), ('6', '6 '), ('7', '7 = I would have used far more points in this manner.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_if_observable = models.StringField(initial=None, choices=[('1', '1 = I would have used far fewer points in this manner.'), ('2', '2 '), ('3', '3 '), ('4', '4 = I would have used the same number of points in this manner.'), ('5', '5 '), ('6', '6 '), ('7', '7 = I would have used far more points in this manner.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) A_points_observable = models.StringField(initial=None, choices=[('1', '1 = I would have used far fewer A points in this manner.'), ('2', '2 '), ('3', '3 '), ('4', '4 = I would have used the same number of A points in this manner.'), ('5', '5 '), ('6', '6 '), ('7', '7 = I would used far more A points in this manner.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) B_points_observable = models.StringField(initial=None, choices=[('1', '1 = I would have used far fewer B points in this manner.'), ('2', '2 '), ('3', '3 '), ('4', '4 = I would have used the same number of B points in this manner.'), ('5', '5 '), ('6', '6 '), ('7', '7 = I would used far more B points in this manner.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) group_id_1 = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) group_id_2 = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) group_id_3 = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) group_id_4 = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) group_id_5 = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) group_id_6 = models.StringField(initial=None, choices=[('1', '1 = Strongly disagree.'), ('2', '2 '), ('3', '3 '), ('4', '4 = Neither agree nor disagree.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Strongly agree.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) affect_enthusiastic = models.StringField(initial=None, choices=[('1', '1 = Not at all'), ('2', '2 = A little'), ('3', '3 = Moderately'), ('4', '4 = Quite a bit'), ('5', '5 = Extremely')], verbose_name='', widget=widgets.RadioSelectHorizontal()) affect_upset = models.StringField(initial=None, choices=[('1', '1 = Not at all'), ('2', '2 = A little'), ('3', '3 = Moderately'), ('4', '4 = Quite a bit'), ('5', '5 = Extremely')], verbose_name='', widget=widgets.RadioSelectHorizontal()) affect_interested = models.StringField(initial=None, choices=[('1', '1 = Not at all'), ('2', '2 = A little'), ('3', '3 = Moderately'), ('4', '4 = Quite a bit'), ('5', '5 = Extremely')], verbose_name='', widget=widgets.RadioSelectHorizontal()) affect_distressed = models.StringField(initial=None, choices=[('1', '1 = Not at all'), ('2', '2 = A little'), ('3', '3 = Moderately'), ('4', '4 = Quite a bit'), ('5', '5 = Extremely')], verbose_name='', widget=widgets.RadioSelectHorizontal()) affect_determined = models.StringField(initial=None, choices=[('1', '1 = Not at all'), ('2', '2 = A little'), ('3', '3 = Moderately'), ('4', '4 = Quite a bit'), ('5', '5 = Extremely')], verbose_name='', widget=widgets.RadioSelectHorizontal()) affect_nervous = models.StringField(initial=None, choices=[('1', '1 = Not at all'), ('2', '2 = A little'), ('3', '3 = Moderately'), ('4', '4 = Quite a bit'), ('5', '5 = Extremely')], verbose_name='', widget=widgets.RadioSelectHorizontal()) gender = models.StringField(initial=None, choices=[('a', 'a. Male'), ('b', 'b. Female'), ('c', 'c. Non-binary'), ('d', 'd. Other'), ('e', 'e. Prefer not to answer')], verbose_name='', widget=widgets.RadioSelect()) age = models.IntegerField(verbose_name='', min=18, max=110) work_experience = models.IntegerField(verbose_name='', min=0) education = models.CharField(initial=None, choices=[('1', 'Less than high school'), ('2', 'High school graduate'), ('3', 'Some college'), ('4', '2 year degree'), ('5', '4 year degree'), ('6', 'Graduate degree')], verbose_name='') #FUNCTIONS def creating_session(subsession): session = subsession.session for player in subsession.get_players(): player.condition = session.config['condition'] player.participant.label = 'e' # PAGES class IC(Page): form_model = 'player' form_fields = ['informed_consent'] def before_next_page(player, timeout_happened): # See if that worker ID already appears in players, in which case they at least started the experiment if player.participant.label != 'e': worker_match = [w for w in OnlineWorkers.filter() if (w.worker_id == player.participant.label)] if not worker_match: OnlineWorkers.create(worker_id=player.participant.label) player.worker_id = player.participant.label else: player.mturk_dupe = 1 class IC_Decline(Page): @staticmethod def is_displayed(player: Player): return player.informed_consent == "No" class DuplicateWorker(Page): @staticmethod def is_displayed(player: Player): return player.mturk_dupe == 1 class ResultsWaitPage(WaitPage): pass class GenInstructions(Page): pass class TaskInstructions(Page): pass class TaskInstructions2(Page): pass class PerformanceEval(Page): pass class Payoffs(Page): pass class KnowledgeCheck(Page): form_model = 'player' @staticmethod def get_form_fields(player): if player.condition == 3 or player.condition == 4: return ['kc1', 'kc2', 'kc3', 'kc4', 'kc5', 'kc6', 'kc7', 'kc8', 'kc9', 'kc10'] else: return ['kc1', 'kc2', 'kc3', 'kc4', 'kc5', 'kc6', 'kc7', 'kc8', 'kc9'] class Decision(Page): form_model = 'player' form_fields = ['A_points_self', 'A_points_Emp2', 'A_points_Emp3', 'A_points_Emp4', 'B_points_self', 'B_points_Emp2', 'B_points_Emp3', 'B_points_Emp4', 'decision_time'] @staticmethod def before_next_page(player, timeout_happened): choice_set_a = ['1.5', '1.6', '1.7', '1.8', '1.9', '2.0', '2.1', '2.2', '2.3', '2.4', '2.5'] choice_set_b = ['0.5', '0.6', '0.7', '0.8', '0.9', '1.0', '1.1', '1.2', '1.3', '1.4', '1.5'] multiplier_a = random.choice(choice_set_a) multiplier_b = random.choice(choice_set_b) player.A_points_multiplier = multiplier_a player.B_points_multiplier = multiplier_b player.A_points_self_output = player.A_points_self * 2 player.B_points_self_output = player.B_points_self * 1 player.total_self_output = player.A_points_self_output + player.B_points_self_output player.self_compensation = '{0:.2f}'.format(player.total_self_output / 50) player.A_points_output_Emp2 = str(Decimal(player.A_points_Emp2) * Decimal(player.A_points_multiplier)) player.A_points_output_Emp3 = str(Decimal(player.A_points_Emp3) * Decimal(player.A_points_multiplier)) player.A_points_output_Emp4 = str(Decimal(player.A_points_Emp4) * Decimal(player.A_points_multiplier)) player.B_points_output_Emp2 = str(Decimal(player.B_points_Emp2) * Decimal(player.B_points_multiplier)) player.B_points_output_Emp3 = str(Decimal(player.B_points_Emp3) * Decimal(player.B_points_multiplier)) player.B_points_output_Emp4 = str(Decimal(player.B_points_Emp4) * Decimal(player.B_points_multiplier)) player.total_output_Emp2 = str(Decimal(player.A_points_output_Emp2) + Decimal(player.B_points_output_Emp2)) player.total_output_Emp3 = str(Decimal(player.A_points_output_Emp3) + Decimal(player.B_points_output_Emp3)) player.total_output_Emp4 = str(Decimal(player.A_points_output_Emp4) + Decimal(player.B_points_output_Emp4)) player.total_help_given = (player.A_points_Emp2 + player.A_points_Emp3 + player.A_points_Emp4 + player.B_points_Emp2 + player.B_points_Emp3 + player.B_points_Emp4) class PostTask(Page): pass class PEQ1(Page): form_model = 'player' form_fields = ['decision_difficulty', 'helping_expectations_personal','helping_expectations_general', 'difficulty_choosing_helpee', 'relative_helping','obligated_helping','helping_needed', 'helping_deserved', 'helping_synergy', 'helping_grateful','manager_wants', 'others_right_thing','others_manager_wants','helping_feels_good','helping_own_reward' ] class PEQ2(Page): form_model = 'player' @staticmethod def get_form_fields(player): if player.condition == 2 or player.condition == 4: return ['helping_if_unobservable', 'A_points_observable', 'B_points_observable', 'group_id_1', 'group_id_2', 'group_id_3', 'group_id_4', 'group_id_5', 'group_id_6', 'affect_enthusiastic', 'affect_upset', 'affect_interested', 'affect_distressed', 'affect_determined', 'affect_nervous', 'age', 'gender', 'education', 'work_experience'] else: return ['helping_if_observable', 'A_points_observable', 'B_points_observable', 'group_id_1', 'group_id_2', 'group_id_3', 'group_id_4', 'group_id_5', 'group_id_6', 'affect_enthusiastic', 'affect_upset', 'affect_interested', 'affect_distressed', 'affect_determined', 'affect_nervous', 'age', 'gender', 'education', 'work_experience'] class ExitResults(Page): pass page_sequence = \ [ IC, IC_Decline, DuplicateWorker, GenInstructions, TaskInstructions, TaskInstructions2, PerformanceEval, Payoffs, KnowledgeCheck, Decision, PostTask, PEQ1, PEQ2, ExitResults ]