from otree.api import * import psycopg2 import sqlite3 import math class C(BaseConstants): NAME_IN_URL = 'performance_evaluation_sp' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class OnlineWorkers(ExtraModel): worker_id = models.CharField(max_length=50) class EmployeeGroup(ExtraModel): condition = models.IntegerField() group_id = models.IntegerField() is_taken = models.IntegerField() total_output_E1 = models.IntegerField() help_given_E1 = models.IntegerField() help_received_E1 = models.IntegerField() total_output_E2 = models.IntegerField() help_given_E2 = models.IntegerField() help_received_E2 = models.IntegerField() total_output_E3 = models.IntegerField() help_given_E3 = models.IntegerField() help_received_E3 = models.IntegerField() total_output_E4 = models.IntegerField() help_given_E4 = models.IntegerField() help_received_E4 = models.IntegerField() class EmployeeMatch(ExtraModel): condition = models.IntegerField() group_id = models.IntegerField() group_taken = models.IntegerField(initial=0) class Player(BasePlayer): worker_id = models.CharField(initial='e') mturk_dupe = models.IntegerField() participant_number = models.IntegerField(default=0) total_compensation = models.StringField(default='Not Finished') player_label = models.StringField() condition = 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=['True', 'False'], 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()) kc11 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) kc12 = models.StringField(initial=None, choices=['True', 'False'], verbose_name='', widget=widgets.RadioSelect()) employee_group_id = models.IntegerField() total_output_E1 = models.IntegerField() #Also store performance information for ease of access help_given_E1 = models.IntegerField() help_received_E1 = models.IntegerField() total_output_E2 = models.IntegerField() help_given_E2 = models.IntegerField() help_received_E2 = models.IntegerField() total_output_E3 = models.IntegerField() help_given_E3 = models.IntegerField() help_received_E3 = models.IntegerField() total_output_E4 = models.IntegerField() help_given_E4 = models.IntegerField() help_received_E4 = models.IntegerField() rating_E1 = models.IntegerField() bonus_E1 = models.IntegerField() rating_E2 = models.IntegerField() bonus_E2 = models.IntegerField() rating_E3 = models.IntegerField() bonus_E3 = models.IntegerField() rating_E4 = models.IntegerField() bonus_E4 = models.IntegerField() eval_decision_time = models.StringField() #PEQ rating_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()) bonus_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()) employee_task_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 = models.StringField(initial=None, choices=[('1', '1 = Many fewer than expected.'), ('2', '2 '), ('3', '3 '), ('4', '4 = About the same as expected.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Many more than expected.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_point_type = models.StringField(initial=None, choices=[('1', '1 = Far more A points than B points.'), ('2', '2 '), ('3', '3 '), ('4', '4 = About the same amount of each.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Far more B points than A points.')], 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_motivation = models.StringField(initial=None, choices=[('1', '1 = Much more because they felt it was the right thing to do.'), ('2', '2 '), ('3', '3 '), ('4', '4 = About equally because they felt it was the right thing to do and beacuse they thought it would improve their performance evaluation.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Much more because they felt it would improve their performance evaluation.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) helping_motivation_bonus = models.StringField(initial=None, choices=[('1', '1 = Much more because they felt it was the right thing to do.'), ('2', '2 '), ('3', '3 '), ('4', '4 = About equally because they felt it was the right thing to do and beacuse they thought it would increase their bonus.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Much more because they felt it would increase their bonus.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) hypothetical_helping = models.StringField(initial=None, choices=[('1', '1 = None at all.'), ('2', '2 '), ('3', '3 '), ('4', '4 = About the same as I used to increase my own total output.'), ('5', '5 '), ('6', '6 '), ('7', '7 = All of them.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) company_expectations = models.StringField(initial=None, choices=[('1', '1 = None at all.'), ('2', '2 '), ('3', '3 '), ('4', '4 = About the same as they used to increase their own total output.'), ('5', '5 '), ('6', '6 '), ('7', '7 = All of them.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) high_output_selfish = 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()) high_output_helped = 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_increased_rating = 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()) rating_output_only = 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()) assume_nobody_helped = 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()) assume_everybody_helped = 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()) rating_explanation = models.LongStringField(verbose_name='') bonus_explanation = models.LongStringField(verbose_name='') helping_output = models.IntegerField(verbose_name='') 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='') worker_id = models.StringField(initial='e') mturk_dupe = models.IntegerField(initial=0) # 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 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', 'kc11'] else: return ['kc1', 'kc2', 'kc3', 'kc4', 'kc5', 'kc6', 'kc7', 'kc8', 'kc9', 'kc10'] def before_next_page(player, timeout_happened): conn = psycopg2.connect(database="d843cclkr6ovgn", user="uigdr2bmq9irl", password="pc314696db376127251d8f370b2d74d5c429ca12e964769f21ac05c08fc6b7ef6", host="cf9gid2f6uallg.cluster-czrs8kj4isg7.us-east-1.rds.amazonaws.com", port=5432) #conn = sqlite3.connect("db.sqlite3") str_condition = str(player.condition) cursor = conn.cursor() cursor.execute('select * from helping_choice_manager_sp_employeegroup where ' 'group_id = (select min(group_id) from helping_choice_manager_sp_employeegroup where is_taken = 0 and condition=' + str_condition + ')') group_data = cursor.fetchone() if group_data is None: player.employee_group_id = -1 cursor.close() conn.commit() conn.close() else: str_group = str(group_data[2]) cursor.execute( 'update helping_choice_manager_sp_employeegroup set is_taken=1 where condition=' + str_condition + ' and (group_id=' + str_group + ')') conn.commit() player.employee_group_id = group_data[2] player.total_output_E1 = group_data[4] player.help_given_E1 = group_data[5] player.help_received_E1 = group_data[6] player.total_output_E2 = group_data[7] player.help_given_E2 = group_data[8] player.help_received_E2 = group_data[9] player.total_output_E3 = group_data[10] player.help_given_E3 = group_data[11] player.help_received_E3 = group_data[12] player.total_output_E4 = group_data[13] player.help_given_E4 = group_data[14] player.help_received_E4 = group_data[15] cursor.close() conn.commit() conn.close() class EarlyExit(Page): @staticmethod def is_displayed(player: Player): return player.employee_group_id == -1 class Evaluation(Page): form_model = 'player' @staticmethod def get_form_fields(player): if player.condition == 3 or player.condition == 4: return ['rating_E1', 'rating_E2', 'rating_E3', 'rating_E4', 'bonus_E1', 'bonus_E2', 'bonus_E3', 'bonus_E4', 'eval_decision_time'] else: return ['rating_E1', 'rating_E2', 'rating_E3', 'rating_E4', 'eval_decision_time'] class PEQ1(Page): form_model = 'player' @staticmethod def get_form_fields(player): if player.condition == 4: return ['rating_difficulty', 'bonus_difficulty','employee_task_difficulty', 'helping_expectations', 'helping_point_type', 'obligated_helping', 'helping_motivation', 'helping_motivation_bonus', 'hypothetical_helping', 'company_expectations'] elif player.condition == 3: return ['rating_difficulty', 'bonus_difficulty','employee_task_difficulty', 'helping_point_type', 'obligated_helping', 'helping_motivation', 'helping_motivation_bonus', 'hypothetical_helping', 'company_expectations', 'high_output_selfish', 'high_output_helped'] elif player.condition == 2: return ['rating_difficulty', 'employee_task_difficulty', 'helping_expectations', 'helping_point_type', 'obligated_helping', 'helping_motivation', 'hypothetical_helping', 'company_expectations'] else: return ['rating_difficulty', 'employee_task_difficulty', 'helping_point_type', 'obligated_helping', 'helping_motivation', 'hypothetical_helping', 'company_expectations', 'high_output_selfish', 'high_output_helped'] class PEQ2(Page): form_model = 'player' @staticmethod def get_form_fields(player): if player.condition == 4: return ['helping_increased_rating', 'rating_output_only', 'helping_feels_good', 'helping_own_reward', 'rating_explanation', 'bonus_explanation', 'helping_output', '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', 'gender', 'age', 'work_experience', 'education'] elif player.condition == 3: return ['assume_nobody_helped', 'assume_everybody_helped', 'helping_feels_good', 'helping_own_reward', 'rating_explanation', 'bonus_explanation', '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', 'gender', 'age', 'work_experience', 'education'] elif player.condition == 2: return ['helping_increased_rating', 'rating_output_only', 'helping_feels_good', 'helping_own_reward', 'rating_explanation', 'helping_output', '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', 'gender', 'age', 'work_experience', 'education'] else: return ['assume_nobody_helped', 'assume_everybody_helped', 'helping_feels_good', 'helping_own_reward', 'rating_explanation', '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', 'gender', 'age', 'work_experience', 'education'] class ExitResults(Page): pass page_sequence = \ [ IC, IC_Decline, DuplicateWorker, GenInstructions, TaskInstructions, TaskInstructions2, PerformanceEval, Payoffs, KnowledgeCheck, EarlyExit, Evaluation, PEQ1, PEQ2, ExitResults ]