from otree.api import * import time import random import math from decimal import Decimal import psycopg2 class C(BaseConstants): NAME_IN_URL = 'reset_it' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 class Group(BaseGroup): pass class Subsession(BaseSubsession): pass class Player(BasePlayer): active_flag = models.IntegerField(initial=0) worker_id = models.CharField(initial='e') mturk_dupe = models.IntegerField(initial=0) participant_number = models.IntegerField(default=0) total_compensation = models.StringField(default='Not Finished') 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()) s1_team_contribution = models.FloatField() s2_team_contribution = models.FloatField() control_decision = models.IntegerField() control_decision_time = models.StringField() s1_bonus = models.FloatField() s2_bonus = models.FloatField() s1_pay = models.FloatField() s2_pay = models.FloatField() total_pay = models.FloatField() workers_ready = models.IntegerField(initial=0) #PEQ downward_trust = 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()) contribution_expectation = models.FloatField(verbose_name='') team_identification = 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_energizes = 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_importance = 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_preference = 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()) best_while_helping = 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()) like_helping = 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()) control_effect = models.StringField(initial=None, choices=[('1', '1 = Greatly decrease contributions.'), ('2', '2 '), ('3', '3 '), ('4', '4 = No effect on contributions.'), ('5', '5 '), ('6', '6 '), ('7', '7 = Greatly increase contributions.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) high_coworker_effort = models.StringField(initial=None, choices=[('1', '1 = It would make me want to contribute much less.'), ('2', '2 '), ('3', '3 '), ('4', '4 = It would have no effect on my decision.'), ('5', '5 '), ('6', '6 '), ('7', '7 = It would make me want to contribute much more.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) control_effect_self = models.StringField(initial=None, choices=[('1', '1 = I would have been far less likely to impose the minimum.'), ('2', '2 '), ('3', '3 '), ('4', '4 = It would have no effect on my decision.'), ('5', '5 '), ('6', '6 '), ('7', '7 = I would have been far more likely to impose the minimum.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) control_amount = models.FloatField(verbose_name='') control_motivation = models.StringField(verbose_name='') 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) major = models.StringField(verbose_name='') class ManagerList(ExtraModel): manager_id = models.IntegerField() #Player ID for manager group_id = models.IntegerField() #Group ID for match - can be many to one control_imposed = models.IntegerField() #Store yes/no for control? Not sure it's needed do_not_pick = models.IntegerField() #So I can keep track of sessions and not pick managers from "old" sessions #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): @staticmethod def before_next_page(player, timeout_happened): ManagerList.create(manager_id=player.participant_id, group_id=0, control_imposed=9, do_not_pick=0) #This way, can check # for workers to make sure all managers have made control decision. Need to spread out # worker groups across managers. player.active_flag = 1 #This is so that for workers, I can find all the managers in the session without having # to do separate oTree sessions for each lab session. class TaskInstructions1(Page): pass class TaskInstructions2(Page): pass class KnowledgeCheck1(Page): form_model = 'player' form_fields = ['kc1', 'kc2', 'kc3'] class KnowledgeCheck2(Page): form_model = 'player' form_fields = ['kc4', 'kc5', 'kc6'] class Decision1(Page): form_model = 'player' form_fields = ['control_decision', 'control_decision_time'] @staticmethod 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_manager_id = str(player.participant_id) str_control_decision = str(player.control_decision) cursor = conn.cursor() cursor.execute( 'update knowledge_of_effort_manager_managerlist set control_imposed=' + str_control_decision + ' where manager_id=' + str_manager_id) conn.commit() cursor.close() conn.close() class PostTask1(Page): pass class PEQ1(Page): form_model = 'player' form_fields = ['downward_trust', 'contribution_expectation', 'team_identification', 'helping_energizes', 'helping_importance', 'helping_preference', 'best_while_helping', 'like_helping', 'control_effect', 'high_coworker_effort', 'control_effect_self', 'control_amount', 'control_motivation', 'affect_enthusiastic', 'affect_upset', 'affect_interested', 'affect_distressed', 'affect_determined', 'affect_nervous', 'gender', 'age', 'work_experience', 'major'] class WkCheck(Page): # Need to check to see that all workers assigned to this manager are done with stage 2. @staticmethod def is_displayed(player): if player.workers_ready == 0: return True else: return False @staticmethod 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") cursor = conn.cursor() # Might as well have managers wait for all participants to be done with both stages before exit. cursor.execute('select distinct e.participant_id from knowledge_of_effort_employee_s2_player e where ' 'e.active_flag = 1 and (e.s1_contribution = -1 or e.s2_contribution = -1) union all ' 'select distinct e.participant_id from knowledge_of_effort_employee_s2_lh_player e where ' 'e.active_flag = 1 and (e.s1_contribution = -1 or e.s2_contribution = -1)') unfinished_worker = cursor.fetchone() if unfinished_worker is None: player.workers_ready = 1 ##################################### #Need to pull from s2_lh_player table as well for the low/no/high conditions. cursor.execute('select sum(s1_team_contr) as total_s1, sum(s2_team_contr) as total_s2, sum(num_groups) ' 'as total_groups from (select sum(e.s1_contribution) as s1_team_contr, ' 'sum(e.s2_contribution) as s2_team_contr, count(distinct e.group_id) as num_groups from ' 'knowledge_of_effort_employee_s2_player e where e.manager_id = ' + str(player.participant_id) + ' union all select sum(e.s1_contribution) as s1_team_contr, sum(e.s2_contribution) ' 'as s2_team_contr, count(distinct e.team_id) as num_groups from ' 'knowledge_of_effort_employee_s2_lh_player e where e.manager_id = ' + str(player.participant_id) +')') mgr_results = cursor.fetchone() player.s1_team_contribution = mgr_results[0] player.s2_team_contribution = mgr_results[1] num_groups = float(mgr_results[2]) if player.s1_team_contribution / (num_groups/float(3.0)) > float(0.33): player.s1_bonus = 1.00 else: player.s1_bonus = 0.00 if player.s2_team_contribution / (num_groups/float(3.0)) > float(0.33): player.s2_bonus = 1.00 else: player.s2_bonus = 0.00 player.s1_pay = 2.00 + player.s1_bonus player.s2_pay = 2.00 + player.s2_bonus player.total_pay = player.s1_pay + player.s2_pay cursor.close() conn.commit() conn.close() class ExitResults(Page): @staticmethod def vars_for_template(player): return dict(s1_bonus='{0:.2f}'.format(player.s1_bonus), s1_pay='{0:.2f}'.format(player.s1_pay), s2_bonus='{0:.2f}'.format(player.s2_bonus), s2_pay='{0:.2f}'.format(player.s2_pay), total_pay='{0:.2f}'.format(player.total_pay),) class Decision1(Page): @staticmethod 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") cursor = conn.cursor() cursor.execute( 'delete from knowledge_of_effort_manager_player') cursor.execute( 'delete from knowledge_of_effort_manager_group') cursor.execute( 'delete from knowledge_of_effort_manager_managerlist') cursor.execute( 'delete from knowledge_of_effort_manager_subsession') cursor.execute( 'delete from knowledge_of_effort_employee_player') cursor.execute( 'delete from knowledge_of_effort_employee_group') cursor.execute( 'delete from knowledge_of_effort_employee_subsession') cursor.execute( 'delete from knowledge_of_effort_employee_s2_player') cursor.execute( 'delete from knowledge_of_effort_employee_s2_group') cursor.execute( 'delete from knowledge_of_effort_employee_s2_subsession') cursor.execute( 'delete from knowledge_of_effort_employee_s2_mgrassignment') cursor.execute( 'delete from knowledge_of_effort_employee_s2_lh_player') cursor.execute( 'delete from knowledge_of_effort_employee_s2_lh_group') cursor.execute( 'delete from knowledge_of_effort_employee_s2_lh_subsession') cursor.execute( 'delete from knowledge_of_effort_employee_s2_lh_mgrassignment') conn.commit() cursor.close() conn.close() class End(Page): pass page_sequence = \ [ Decision1, End ]