from otree.api import * import time import random import math from decimal import Decimal import psycopg2 import sqlite3 import math class C(BaseConstants): NAME_IN_URL = 'project_work_s2' PLAYERS_PER_GROUP = 3 NUM_ROUNDS = 1 class Group(BaseGroup): pass class Subsession(BaseSubsession): pass class Player(BasePlayer): active_flag = models.IntegerField(initial=0) mgr_ready = models.IntegerField(initial=0) all_ready = models.IntegerField(initial=0) worker_id = models.CharField(initial='e') mturk_dupe = models.IntegerField(initial=0) participant_number = models.IntegerField(default=0) condition = models.IntegerField() condition_label = models.StringField(default='NA') team_id = models.IntegerField(default=0) 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()) manager_id = models.IntegerField() s1_contribution = models.FloatField(verbose_name='', default=-1.00) s1_decision_time = models.StringField() s1_pay = models.FloatField() s1_coworker_1_contribution = models.FloatField() s1_coworker_2_contribution = models.FloatField() s1_team_contribution = models.FloatField() s2_control = models.IntegerField(default=0) s2_contribution = models.FloatField(default=-1.00) # Setting default of -1.00 for manager check s2_decision_time = models.StringField() s2_pay = models.FloatField() s2_coworker_1_contribution = models.FloatField() s2_coworker_2_contribution = models.FloatField() s2_team_contribution = models.FloatField() total_pay = models.FloatField() #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()) downward_trust_coworkers = 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()) upward_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()) horizontal_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()) manager_affinity = 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()) coworkers_high_contributions = 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()) 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()) coworker_affinity = 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_priority = models.StringField(initial=None, choices=[('a', 'My well-being'), ('b', 'Their own interests'), ('c', 'Both equally')], verbose_name='', widget=widgets.RadioSelect()) manager_priority_magnitude = models.StringField(initial=None, choices=[('1', '1 = Slightly more'), ('2', '2 '), ('3', '3 = Moderately more'), ('4', '4 '), ('5', '5 = Significantly more')], verbose_name='', widget=widgets.RadioSelect()) manager_control = models.StringField(initial=None, choices=[('1', '1 = No control'), ('2', '2 = A little control'), ('3', '3 = A moderate amount of control'), ('4', '4 = A lot of control'), ('5', '5 = Complete control')], verbose_name='', widget=widgets.RadioSelectHorizontal()) control_attribution = models.StringField(initial=None, choices=[('a', 'Manager B'), ('b', 'Other Workers'), ('c', 'Both equally')], verbose_name='', widget=widgets.RadioSelect()) attribution_magnitude = models.StringField(initial=None, choices=[('1', '1 = Slightly more'), ('2', '2 '), ('3', '3 = Moderately more'), ('4', '4 '), ('5', '5 = Significantly more')], verbose_name='', widget=widgets.RadioSelect()) s2_autonomy = 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()) s2_mgr_intrusion = 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()) s2_mgr_fairness = 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()) s2_control_fairness = 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()) s2_coworker_equity = 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()) s2_manager_bonus = 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()) s2_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()) s2_coworker_competition = 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()) s2_mgr_expectations = models.FloatField(verbose_name='') s2_coworker_info_effect = models.StringField(initial=None, choices=[('1', '1 = It made me want to contribute much less.'), ('2', '2 '), ('3', '3 '), ('4', '4 = It had no effect on my decision.'), ('5', '5 '), ('6', '6 '), ('7', '7 = It made me want to contribute much more.')], verbose_name='', widget=widgets.RadioSelectHorizontal()) control_reaction = models.StringField(verbose_name='') manager_motivation = models.StringField(verbose_name='') 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()) 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='') total_compensation = models.StringField(default='Not Finished') pay_method = models.StringField(initial=None, choices=[('a', 'Receive cash.'), ('b', 'Receive electronically via CashApp.'), ('c', 'Receive electronically via Venmo.'), ('d', 'Receive electronically via PayPal.')], verbose_name='', widget=widgets.RadioSelect()) pay_id = models.StringField(verbose_name='') email = models.StringField(verbose_name='') first_name = models.StringField(verbose_name='') last_name = models.StringField(verbose_name='') referring_prof = models.StringField(verbose_name='') class MgrAssignment(ExtraModel): manager_id = models.IntegerField() group_id = models.IntegerField() control_imposed = models.IntegerField() # 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 PostTask1(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return False else: return True @staticmethod def vars_for_template(player): return dict(s1_contribution='{0:.2f}'.format(player.s1_contribution), s1_pay='{0:.2f}'.format(player.s1_pay)) class S1Update(Page): @staticmethod def before_next_page(player, timeout_happened): player.s1_contribution = player.participant.s1_contribution player.s1_decision_time = player.participant.s1_decision_time player.s1_pay = player.participant.s1_pay player.participant_number = player.participant.participant_number class GrpCheck(Page): @staticmethod def is_displayed(player): if player.all_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") str_session = str(player.session_id) cursor = conn.cursor() cursor.execute('select min(participant_id) from knowledge_of_effort_employee_s2_player where active_flag = 1' ' and session_id =' + str_session) this_participant = cursor.fetchone() # cursor.close() #Do the group processing only if it's the first participant, so a bunch aren't doing it at one time if this_participant[0] == player.participant_id: # Make sure all participants in the session have finished stage 1 and grouping can be done based on # contributions cursor.execute('select participant_id from knowledge_of_effort_employee_s2_player where ' 'active_flag = 1 and s1_contribution = -1.00 and session_id =' + str_session) participant_not_ready = cursor.fetchone() # cursor.close() if participant_not_ready is None: # Assign groups # Check number of participants. This way it's flexible as long as we have multiple teams of 3. cursor.execute('select count(p.participant_id) as num_participants from ' 'knowledge_of_effort_employee_s2_player p where p.s1_contribution > -1.00 ' 'and active_flag = 1 and session_id =' + str_session) count_cursor = cursor.fetchone() num_participants = count_cursor[0] num_teams = int(num_participants / 3) # For this, will either be 4, 5, or 6 num_advancing_participants = num_teams * 3 str_num_advancing_participants = str(num_advancing_participants) # List of advancing participants will be the "first" through to make max groups of 3, so below is taking # the top ("limit") that equals the number of advancing participants. Next just need to update the # leftover people... # Need list of participants, by descending order of stage 1 contribution # Include row numbers so I can group based on pre-determined groupings if num_advancing_participants == 18: cursor.execute('select p.participant_id, p.s1_contribution, row_num, ' 'case ' 'when row_num in (1, 4, 7) then 1 ' 'when row_num in (10, 13, 16) then 2 ' 'when row_num in (2, 5, 8) then 3 ' 'when row_num in (11, 14, 17) then 4 ' 'when row_num in (3, 6, 18) then 5 ' 'when row_num in (9, 12, 15) then 6 ' 'end as team_number ' 'from ' '( select p.participant_id, p.s1_contribution, ' 'ROW_NUMBER() OVER (ORDER BY p.s1_contribution desc) AS row_num ' 'from knowledge_of_effort_employee_s2_player p where active_flag = 1 and session_id =' + str_session + ' limit 18) p ' 'order by team_number, row_num') elif num_advancing_participants == 15: cursor.execute('select p.participant_id, p.s1_contribution, row_num, ' 'case ' 'when row_num in (1, 4, 7) then 1 ' 'when row_num in (10, 13, 2) then 2 ' 'when row_num in (5, 8, 11) then 3 ' 'when row_num in (3, 6, 14) then 4 ' 'when row_num in (9, 12, 15) then 5 ' 'end as team_number ' 'from ' '( select p.participant_id, p.s1_contribution, ' 'ROW_NUMBER() OVER (ORDER BY p.s1_contribution desc) AS row_num ' 'from knowledge_of_effort_employee_s2_player p where active_flag = 1 and session_id =' + str_session + ' limit 15) p ' 'order by team_number, row_num') elif num_advancing_participants == 12: cursor.execute('select p.participant_id, p.s1_contribution, row_num, ' 'case ' 'when row_num in (1, 4, 7) then 1 ' 'when row_num in (2, 5, 10) then 2 ' 'when row_num in (3, 8, 11) then 3 ' 'when row_num in (6, 9, 12) then 4 ' 'end as team_number ' 'from ' '( select p.participant_id, p.s1_contribution, ' 'ROW_NUMBER() OVER (ORDER BY p.s1_contribution desc) AS row_num ' 'from knowledge_of_effort_employee_s2_player p where active_flag = 1 and session_id =' + str_session + ' limit 12) p ' 'order by team_number, row_num') elif num_advancing_participants == 9: cursor.execute('select p.participant_id, p.s1_contribution, row_num, ' 'case ' 'when row_num in (1, 3, 5) then 1 ' 'when row_num in (2, 7, 9) then 2 ' 'when row_num in (4, 6, 8) then 3 ' 'end as team_number ' 'from ' '( select p.participant_id, p.s1_contribution, ' 'ROW_NUMBER() OVER (ORDER BY p.s1_contribution desc) AS row_num ' 'from knowledge_of_effort_employee_s2_player p where active_flag = 1 and session_id =' + str_session + ' limit 9) p ' 'order by team_number, row_num') elif num_advancing_participants == 6: cursor.execute('select p.participant_id, p.s1_contribution, row_num, ' 'case ' 'when row_num in (1, 3, 5) then 1 ' 'when row_num in (2, 4, 6) then 2 ' 'end as team_number ' 'from ' '( select p.participant_id, p.s1_contribution, ' 'ROW_NUMBER() OVER (ORDER BY p.s1_contribution desc) AS row_num ' 'from knowledge_of_effort_employee_s2_player p where active_flag = 1 and session_id =' + str_session + ' limit 6) p ' 'order by team_number, row_num') elif num_advancing_participants == 3: cursor.execute('select p.participant_id, p.s1_contribution, row_num, ' 'case ' 'when row_num in (1, 2, 3) then 1 ' 'end as team_number ' 'from ' '( select p.participant_id, p.s1_contribution, ' 'ROW_NUMBER() OVER (ORDER BY p.s1_contribution desc) AS row_num ' 'from knowledge_of_effort_employee_s2_player p where active_flag = 1 and session_id =' + str_session + ' limit 3) p ' 'order by team_number, row_num') i = 0 j = 0 cursor2 = conn.cursor() # In the event of multiple sessions for these conditions, need to make sure assignment table does not # end up with duplicate team ids that make it appear that some participants are not finished. cursor2.execute('select max(team_id) as high_team_id from knowledge_of_effort_employee_s2_player') team_id_cursor = cursor2.fetchone() if team_id_cursor is None: team_id = 1000 else: team_id = team_id_cursor[0] + 1000 while i < num_teams: # Teams of 3 based on laid out groupings to promote heterogeneity this_team = cursor.fetchmany(3) team_contribution = str(this_team[0][1] + this_team[1][1] + this_team[2][1]) cursor2.execute('update knowledge_of_effort_employee_s2_player set team_id = ' + str(team_id) + ', ' 's1_coworker_1_contribution = ' + str(this_team[1][1]) + ', ' 's1_coworker_2_contribution = ' + str(this_team[2][1]) + ', ' 's1_team_contribution = ' + team_contribution + ' ' ' where participant_id = ' + str(this_team[0][0])) conn.commit() cursor2.execute('update knowledge_of_effort_employee_s2_player set team_id = ' + str(team_id) + ', ' 's1_coworker_1_contribution = ' + str(this_team[0][1]) + ', ' 's1_coworker_2_contribution = ' + str(this_team[2][1]) + ', ' 's1_team_contribution = ' + team_contribution + ' ' ' where participant_id = ' + str(this_team[1][0])) conn.commit() cursor2.execute('update knowledge_of_effort_employee_s2_player set team_id = ' + str(team_id) + ', ' 's1_coworker_1_contribution = ' + str(this_team[0][1]) + ', ' 's1_coworker_2_contribution = ' + str(this_team[1][1]) + ', ' 's1_team_contribution = ' + team_contribution + ' ' ' where participant_id = ' + str(this_team[2][0])) conn.commit() i += 1 team_id += 1 # Update employees to give the all clear for everybody cursor.execute('update knowledge_of_effort_employee_s2_player set all_ready = 1') conn.commit() # Since team assignment is done for only the advancing multiples of 3, anyone with a team_id at the default # and an active_flag = 1 at this point is a leftover. Can update en mass rather than looping through... cursor.execute('update knowledge_of_effort_employee_s2_player set active_flag = 99 where active_flag = 1' ' and team_id = 0') conn.commit() cursor.close() cursor2.close() conn.commit() conn.close() class TaskInstructions2(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return False else: return True form_model = 'player' form_fields = ['kc4', 'kc5', 'kc6', 'kc7'] @staticmethod def vars_for_template(player): return dict(s1_team_contribution='{0:.2f}'.format(player.s1_team_contribution), s1_coworker_1_contribution='{0:.2f}'.format(player.s1_coworker_1_contribution), s1_coworker_2_contribution='{0:.2f}'.format(player.s1_coworker_2_contribution)) @staticmethod def before_next_page(player, timeout_happened): player.active_flag = 1 if player.condition == 2: player.condition_label = "Team" elif player.condition == 3: player.condition_label = "Full" class KnowledgeCheck2(Page): form_model = 'player' form_fields = ['kc4', 'kc5', 'kc6', 'kc7'] @staticmethod def vars_for_template(player): return dict(s1_team_contribution='{0:.2f}'.format(player.s1_team_contribution), s1_coworker_1_contribution='{0:.2f}'.format(player.s1_coworker_1_contribution), s1_coworker_2_contribution='{0:.2f}'.format(player.s1_coworker_2_contribution)) class MgrCheck(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return False elif player.mgr_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") str_session = str(player.session_id) cursor = conn.cursor() cursor.execute('select min(participant_id) from knowledge_of_effort_employee_s2_player where active_flag = 1' ' and session_id =' + str_session) this_participant = cursor.fetchone() # cursor.close() #Do the group processing only if it's the first participant, so a bunch aren't doing it at one time if this_participant[0] == player.participant_id: cursor.execute('select manager_id from knowledge_of_effort_manager_managerlist where do_not_pick = 0' ' and control_imposed = 9 ') mgr_not_ready = cursor.fetchone() # cursor.close() if mgr_not_ready is None: # Assign groups # Need a count of the active teams; those with active_flag=1; Don't need to worry about # session number because all employees will be active_flag = 0 until they start the experiment. #************************* 9/11/2025 - With change to grouping, it's now team_id like the other conditions # If we go back to random, just put everything back to group_id cursor.execute('select distinct team_id from knowledge_of_effort_employee_s2_player ' 'where active_flag = 1 and team_id > 0 order by team_id') team_list = cursor.fetchall() num_teams = len(team_list) # cursor.close() # Get first and last group id cursor.execute('select min(team_id) as first_group, max(team_id) as last_group from ' 'knowledge_of_effort_employee_s2_player where active_flag = 1 and team_id > 0') team_identifiers = cursor.fetchone() first_team = team_identifiers[0] last_team = team_identifiers[1] # cursor.close() # Get mgrs who chose control and who didn't, and counts. cursor.execute('select manager_id from knowledge_of_effort_manager_managerlist where ' 'do_not_pick = 0 and control_imposed = 0') mgrs_no = cursor.fetchall() no_count = len(mgrs_no) # cursor.close() cursor.execute('select manager_id from knowledge_of_effort_manager_managerlist where ' 'do_not_pick = 0 and control_imposed = 1') mgrs_control = cursor.fetchall() control_count = len(mgrs_control) # cursor.close() # If there is at least one mgr who chose the control and at least one who did not..., if control_count > 0 and no_count > 0: # All the no control managers get the same group (go with the min group id) for row in mgrs_no: cursor.execute('insert into knowledge_of_effort_employee_s2_mgrassignment (manager_id, group_id, control_imposed) values ' '('+str(row[0])+', '+str(first_team)+' ,0)') conn.commit() # Divide up rest of the teams for the yes managers # Need to know which is bigger, number of teams or number of yes managers... if control_count > num_teams - 1: # If more control managers than teams, cycle through teams as needed i = 1 for row in mgrs_control: cursor.execute('insert into knowledge_of_effort_employee_s2_mgrassignment (manager_id, group_id, control_imposed) values ' '('+str(row[0])+', '+str(team_list[i][0])+', 1)') conn.commit() if i + 1 == num_teams: # If reached the end of the team list, reset that to the start i = 0 i += 1 elif num_teams - 1 > control_count: # More teams than control managers i = 0 j = -1 for row in team_list: if i > 0: # Skip first row since this group goes to the no control managers cursor.execute('insert into knowledge_of_effort_employee_s2_mgrassignment (manager_id, group_id, control_imposed) values ' '('+str(mgrs_control[j][0])+', '+str(row[0])+', 1)') conn.commit() if j + 1 == control_count: # If reached the end of the mgr list, reset that to the start j = -1 i += 1 j += 1 else: # Same number, then it's one for one i = 0 for row in team_list: if i > 0: cursor.execute('insert into knowledge_of_effort_employee_s2_mgrassignment (manager_id, group_id, control_imposed) values ' '(' + str(mgrs_control[i-1][0]) + ', ' + str(row[0]) + ', 1)') conn.commit() i += 1 # Otherwise if one of the groups has zero mgrs, just divide teams among that group... # No managers picked no control elif control_count > 0 and no_count == 0: if control_count > num_teams: i = 0 for row in mgrs_control: cursor.execute('insert into knowledge_of_effort_employee_s2_mgrassignment (manager_id, group_id, control_imposed) values ' '('+str(row[0])+', '+str(team_list[i][0])+', 1)') conn.commit() i += 1 if i == num_teams: i = 0 elif control_count < num_teams or control_count == num_teams: i = 0 for row in team_list: cursor.execute('insert into knowledge_of_effort_employee_s2_mgrassignment (manager_id, group_id, control_imposed) values ' '('+str(mgrs_control[i][0])+', '+str(row[0])+', 1)') conn.commit() i += 1 if i == control_count: i = 0 # All managers picked no control elif control_count == 0 and no_count > 0: if no_count > num_teams: i = 0 for row in mgrs_no: cursor.execute('insert into knowledge_of_effort_employee_s2_mgrassignment (manager_id, group_id, control_imposed) values ' '('+str(row[0])+', '+str(team_list[i][0])+', 0)') conn.commit() i += 1 if i == num_teams: i = 0 elif no_count < num_teams or no_count == num_teams: i = 0 for row in team_list: cursor.execute('insert into knowledge_of_effort_employee_s2_mgrassignment (manager_id, group_id, control_imposed) values ' '('+str(mgrs_no[i][0])+', '+str(row[0])+', 0)') conn.commit() i += 1 if i == no_count: i = 0 # Have to update manager_id in player table. Do that on next looping page # Update all employees to indicate managers are assigned. This will be every employee record in the same session # where active_flag = 1, since that is triggered back early in stage 1 and 'future' participants will # be showing as 0. Next auto-submit page update mgr_ready = 2 and will update manager_id and control in each # employee's record. cursor.execute('update knowledge_of_effort_employee_s2_player set mgr_ready = 1 where ' ' session_id = ' + str_session + ' and active_flag = 1') conn.commit() # Update managerlist table to set do_not_pick = 1 for this "sub-session" so that I don't have to do it manually cursor.execute('update knowledge_of_effort_manager_managerlist set do_not_pick = 1') conn.commit() cursor.close() conn.commit() conn.close() class MgrUpdate(Page): # This page will be reached when all managers/groups are matched. # Update manager_id and control in each employee's record. @staticmethod def is_displayed(player): if player.active_flag == 99: return False elif player.mgr_ready == 1: 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") str_participant_id = str(player.participant_id) cursor = conn.cursor() cursor.execute('select m.manager_id, control_imposed from knowledge_of_effort_employee_s2_player p inner join' ' knowledge_of_effort_employee_s2_mgrassignment m on p.team_id = m.group_id where' ' p.participant_id =' + str_participant_id) this_participant = cursor.fetchone() player.manager_id = this_participant[0] player.s2_control = this_participant[1] cursor.close() conn.commit() conn.close() player.mgr_ready = 2 class Decision2(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return False else: return True form_model = 'player' form_fields = ['s2_contribution', 's2_decision_time'] def before_next_page(player, timeout_happened): player.s2_pay = 2.00 - player.s2_contribution player.total_pay = player.s1_pay + player.s2_pay player.active_flag = 2 #So manager check can find these who are complete but in the "active" session class GroupWait(WaitPage): #Make sure using forward slash in template name! #template_name = 'helping_behavior_employee_task/CWaitPage2.html' body_text = "Please wait briefly while others in your group arrive..." title_text = "" group_by_arrival_time = True @staticmethod def after_all_players_arrive(group: Group): p1 = group.get_player_by_id(1) p2 = group.get_player_by_id(2) p3 = group.get_player_by_id(3) p1.s1_contribution = p1.participant.s1_contribution p1.s1_decision_time = p1.participant.s1_decision_time p1.s1_pay = p1.participant.s1_pay p1.participant_number = p1.participant.participant_number # p1.manager_id = p1.participant.manager_id p2.s1_contribution = p2.participant.s1_contribution p2.s1_decision_time = p2.participant.s1_decision_time p2.s1_pay = p2.participant.s1_pay p2.participant_number = p2.participant.participant_number # p2.manager_id = p2.participant.manager_id p3.s1_contribution = p3.participant.s1_contribution p3.s1_decision_time = p3.participant.s1_decision_time p3.s1_pay = p3.participant.s1_pay p3.participant_number = p3.participant.participant_number # p3.manager_id = p3.participant.manager_id p1.s1_coworker_1_contribution = p2.s1_contribution p1.s1_coworker_2_contribution = p3.s1_contribution p2.s1_coworker_1_contribution = p1.s1_contribution p2.s1_coworker_2_contribution = p3.s1_contribution p3.s1_coworker_1_contribution = p1.s1_contribution p3.s1_coworker_2_contribution = p2.s1_contribution p1.s1_team_contribution = p1.s1_contribution + p2.s1_contribution + p3.s1_contribution p2.s1_team_contribution = p1.s1_team_contribution p3.s1_team_contribution = p1.s1_team_contribution class PEQ1(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return False else: return True form_model = 'player' form_fields = ['downward_trust', 'downward_trust_coworkers', 'upward_trust','horizontal_trust','manager_affinity', 'coworkers_high_contributions', 'team_identification', 'coworker_affinity', 'manager_priority', 'manager_priority_magnitude', 'manager_control', 'control_attribution', 'attribution_magnitude', 's2_autonomy', 's2_mgr_intrusion', 's2_mgr_fairness','s2_control_fairness', 's2_coworker_equity', 's2_manager_bonus', 's2_right_thing', 's2_coworker_competition'] @staticmethod def vars_for_template(player): return dict(s2_contribution='{0:.2f}'.format(player.s2_contribution)) class PEQ2(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return False else: return True form_model = 'player' @staticmethod def get_form_fields(player): if player.s2_control == 1: return ['s2_mgr_expectations', 's2_coworker_info_effect', 'control_reaction','manager_motivation', 'helping_energizes', 'helping_importance', 'helping_preference', 'best_while_helping', 'like_helping', 'affect_enthusiastic', 'affect_upset', 'affect_interested', 'affect_distressed', 'affect_determined', 'affect_nervous', 'gender', 'age', 'work_experience', 'major', 'pay_method', 'pay_id', 'email', 'first_name', 'last_name', 'referring_prof'] else: return ['s2_mgr_expectations', 's2_coworker_info_effect', 'control_reaction','manager_motivation', 'helping_energizes', 'helping_importance', 'helping_preference', 'best_while_helping', 'like_helping', 'affect_enthusiastic', 'affect_upset', 'affect_interested', 'affect_distressed', 'affect_determined', 'affect_nervous', 'gender', 'age', 'work_experience', 'major', 'pay_method', 'pay_id', 'email', 'first_name', 'last_name', 'referring_prof'] class PEQ2Alt(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return True else: return False form_model = 'player' form_fields = ['pay_method', 'pay_id', 'email', 'first_name', 'last_name', 'referring_prof'] class ExitResults(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return False else: return True @staticmethod def vars_for_template(player): return dict(s1_contribution='{0:.2f}'.format(player.s1_contribution), s1_pay='{0:.2f}'.format(player.s1_pay), s2_contribution='{0:.2f}'.format(player.s2_contribution), s2_pay='{0:.2f}'.format(player.s2_pay), total_pay='{0:.2f}'.format(player.total_pay),) class ExitResultsAlt(Page): @staticmethod def is_displayed(player): if player.active_flag == 99: return True else: return False page_sequence = \ [ S1Update, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, GrpCheck, #GrpWait, --For random grouping, just needed this and nothing above it... PostTask1, TaskInstructions2, #KnowledgeCheck2, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrCheck, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, MgrUpdate, Decision2, PEQ1, PEQ2, PEQ2Alt, ExitResultsAlt, ExitResults ]