from otree.api import * import random import time doc = """ simple experimental design for both treatments and voting """ class C(BaseConstants): TREATMENT = "MIXED" # add/select before starting the show "MIXED"/"INDIVIDUAL"/"COLLECTIVE" NAME_IN_URL = 'WORKHORSE' # CHANGE before deploying wr to other treatments PLAYERS_PER_GROUP = 4 # workers per group + 1 manager included ###check! MIN_ROUNDS = 5 ###check! MAX_ROUNDS = 6 ###check! NUM_ROUNDS = random.randint(MIN_ROUNDS, MAX_ROUNDS) ## SETTLE POLICY BEFORE STARTING W_MULTIPLIER = 1 M_MULTIPLIER = 1 COMP_COST = 2 ###check! FIX_COST = 20 ###check! MIN_ISSUE = 5 WORSENING = 40 # probability 40% that the issue worsens, integer between 0 and 100 ###check! PROB_ISSUE_THE_SAME = 0 # meaning 99% chance to worsen TIME_LIMIT = 5 # time per round ###check! BONUS = 5 # BONUS IN ECU EVAL = random.randint(1, NUM_ROUNDS) ## random period to allocate payoff PARTICIP_W = 5 ## participation fees PARTICIP_M = 5 BONUS_BUDGET = 10 ## WHAT THIS MEANS?? REDUNDANT?? B_MULTIPLIER = 2 BONUS_SHARE = .2 ###check! CHAT_TIME_LIMIT = 5 ###check! ECUEUR = 1/10 # 1eur to 20 ecu COMP_COST = 2 # cost per complaining person ###check! -- already defined # ISSUE STARTING SETTINGS ISSUE_START = 5000 ISSUE_FINISH0 = 5000 ISSUE_FINISH1 = 10000 ISSUE_FINISH2 = 15000 ISSUE_FINISH3 = 25000 ISSUE_FINISH4 = 45000 ####### SLIDER SETTINGS ###### SLIDER_W = 40 ## graphics SLIDER_H = 10 SLIDER_MAX = "100" ### max and min values of sliders SLIDER_MIN = "0" class Subsession(BaseSubsession): pass class Group(BaseGroup): delay = models.FloatField(min=0, initial=0) eval_round = models.FloatField(min=0, initial=C.NUM_ROUNDS) complaint = models.StringField(initial = "No complaint") #"Individual complaint") w1_bon = models.FloatField(min=0, max=100,initial=0, label=" The amount to Worker 1") w2_bon = models.FloatField(min=0, max=100,initial=0, label=" The amount to Worker 2") w3_bon = models.FloatField(min=0, max=100,initial=0, label=" The amount to Worker 3") delayW1 = models.IntegerField(min=0, initial=0) delayW2 = models.IntegerField(min=0, initial=0) delayW3 = models.IntegerField(min=0, initial=0) complaining_cost = models.FloatField(min = 0, initial = 0) aloha = models.IntegerField(initial = 0) pass class Player(BasePlayer): treatment = models.StringField(choices=["MIXED", "COLLECTIVE", "INDIVIDUAL"], widget=widgets.RadioSelectHorizontal, initial = C.TREATMENT) p_number_sent = models.IntegerField(min=0, label=" ") p_decision = models.StringField(choices=["Yes", "No"], widget=widgets.RadioSelectHorizontal, initial = "No", label=" ") p_complain = models.StringField(choices=["Yes", "No"], widget=widgets.RadioSelectHorizontal, label=" ") complaining_choice = models.StringField(choices=["Collective complaint", "Individual complaint"], widget=widgets.RadioSelectHorizontal, label=" ") missed_units = models.IntegerField(min=0, initial=0, label=" ", max=1000) fix = models.BooleanField() round_payoff = models.FloatField(min=0, initial=0) final_payoff = models.FloatField(min=0, initial=0) answer_1 = models.StringField(choices=['30%', '60%'], label="Question 1: What is the probability that the issue will not occur" " or will not get worse in the next round?", widget=widgets.RadioSelect) answer_2 = models.StringField(choices=['58 ECU', '61 ECU', '65 ECU', "73 ECU"], label="Question 2: There is 78 ECU in the company budget and" " the manager decides to fix the issue. How many ECU will be left in the budget" " after that action?", widget=widgets.RadioSelect) answer_3 = models.StringField(choices=['Collective', 'Individual'], label="Question 3: If you vote to complain Individually" " and both of your fellow workers vote to complain Collectively," " what will be the final complaint?", widget=widgets.RadioSelect) answer_4 = models.StringField(choices=['Yes', 'No'], label="Question 5: Can the manager see the workers' communication?", widget=widgets.RadioSelect) answer_5 = models.StringField(choices=['2 ECU', '4 ECU', "6 ECU", "8 ECU"], label="Question 4: How much would such a complaint from Question 3" " subtract from manager's payoff?", widget=widgets.RadioSelect) ## sliders points = models.IntegerField(initial=0, min=0) slider_value1 = models.FloatField(min=0, max=100) slider_value2 = models.FloatField(min=0, max=100) slider_value3 = models.FloatField(min=0, max=100) slider_value4 = models.FloatField(min=0, max=100) slider_value5 = models.FloatField(min=0, max=100) slider_value6 = models.FloatField(min=0, max=100) slider_value7 = models.FloatField(min=0, max=100) slider_value8 = models.FloatField(min=0, max=100) slider_value9 = models.FloatField(min=0, max=100) slider_value10 = models.FloatField(min=0, max=100) slider_value11 = models.FloatField(min=0, max=100) slider_value12 = models.FloatField(min=0, max=100) slider_value13 = models.FloatField(min=0, max=100) slider_value14 = models.FloatField(min=0, max=100) slider_value15 = models.FloatField(min=0, max=100) slider_value16 = models.FloatField(min=0, max=100) slider_value17 = models.FloatField(min=0, max=100) slider_value18 = models.FloatField(min=0, max=100) slider_value19 = models.FloatField(min=0, max=100) slider_value20 = models.FloatField(min=0, max=100) slider_value21 = models.FloatField(min=0, max=100) slider_value22 = models.FloatField(min=0, max=100) slider_value23 = models.FloatField(min=0, max=100) slider_value24 = models.FloatField(min=0, max=100) slider_value25 = models.FloatField(min=0, max=100) slider_value26 = models.FloatField(min=0, max=100) slider_value27 = models.FloatField(min=0, max=100) slider_value28 = models.FloatField(min=0, max=100) slider_value29 = models.FloatField(min=0, max=100) slider_value30 = models.FloatField(min=0, max=100) slider_value31 = models.FloatField(min=0, max=100) slider_value32 = models.FloatField(min=0, max=100) slider_value33 = models.FloatField(min=0, max=100) slider_value34 = models.FloatField(min=0, max=100) slider_value35 = models.FloatField(min=0, max=100) slider_value36 = models.FloatField(min=0, max=100) slider_value37 = models.FloatField(min=0, max=100) slider_value38 = models.FloatField(min=0, max=100) slider_value39 = models.FloatField(min=0, max=100) slider_value40 = models.FloatField(min=0, max=100) ## random numbers n_1 = models.IntegerField(initial=0, min=0, max=100) n_2 = models.IntegerField(initial=0, min=0, max=100) n_3 = models.IntegerField(initial=0, min=0, max=100) n_4 = models.IntegerField(initial=0, min=0, max=100) n_5 = models.IntegerField(initial=0, min=0, max=100) n_6 = models.IntegerField(initial=0, min=0, max=100) n_7 = models.IntegerField(initial=0, min=0, max=100) n_8 = models.IntegerField(initial=0, min=0, max=100) n_9 = models.IntegerField(initial=0, min=0, max=100) n_10 = models.IntegerField(initial=0, min=0, max=100) n_11 = models.IntegerField(initial=0, min=0, max=100) n_12 = models.IntegerField(initial=0, min=0, max=100) n_13 = models.IntegerField(initial=0, min=0, max=100) n_14 = models.IntegerField(initial=0, min=0, max=100) n_15 = models.IntegerField(initial=0, min=0, max=100) n_16 = models.IntegerField(initial=0, min=0, max=100) n_17 = models.IntegerField(initial=0, min=0, max=100) n_18 = models.IntegerField(initial=0, min=0, max=100) n_19 = models.IntegerField(initial=0, min=0, max=100) n_20 = models.IntegerField(initial=0, min=0, max=100) n_21 = models.IntegerField(initial=0, min=0, max=100) n_22 = models.IntegerField(initial=0, min=0, max=100) n_23 = models.IntegerField(initial=0, min=0, max=100) n_24 = models.IntegerField(initial=0, min=0, max=100) n_25 = models.IntegerField(initial=0, min=0, max=100) n_26 = models.IntegerField(initial=0, min=0, max=100) n_27 = models.IntegerField(initial=0, min=0, max=100) n_28 = models.IntegerField(initial=0, min=0, max=100) n_29 = models.IntegerField(initial=0, min=0, max=100) n_30 = models.IntegerField(initial=0, min=0, max=100) n_31 = models.IntegerField(initial=0, min=0, max=100) n_32 = models.IntegerField(initial=0, min=0, max=100) n_33 = models.IntegerField(initial=0, min=0, max=100) n_34 = models.IntegerField(initial=0, min=0, max=100) n_35 = models.IntegerField(initial=0, min=0, max=100) n_36 = models.IntegerField(initial=0, min=0, max=100) n_37 = models.IntegerField(initial=0, min=0, max=100) n_38 = models.IntegerField(initial=0, min=0, max=100) n_39 = models.IntegerField(initial=0, min=0, max=100) n_40 = models.IntegerField(initial=0, min=0, max=100) pass # PAGES class OOstart(Page): pass class Welcome(Page): def is_displayed(player): return player.round_number == 1 pass class InstructionsW(Page): def is_displayed(player): return player.id_in_group != 1 and player.round_number == 1 def vars_for_template(player): return {'experiment_id': player.id_in_group - 1} pass class InstructionsM(Page): def is_displayed(player): return player.id_in_group == 1 and player.round_number == 1 def vars_for_template(player): return {'experiment_id': player.id_in_group} pass ###class Comprehension(Page): ## pass ### COMPREHENSION class Comprehension(Page): form_model = 'player' form_fields = ['answer_1', 'answer_2', "answer_3","answer_5", "answer_4"] def is_displayed(player): return player.round_number == 1 def error_message(self, values): errors = [] if values['answer_1'] != '60%': errors.append('Question 1 is incorrect.') if values['answer_2'] != '58 ECU': errors.append('Question 2 is incorrect.') if values['answer_3'] != 'Collective': errors.append('Question 3 is incorrect.') if values['answer_4'] != 'No': errors.append('Question 5 is incorrect.') if values['answer_5'] != '6 ECU': errors.append('Question 4 is incorrect.') if errors: return errors ###### # if values['answer_3'] != 'Collective': # errors.append('Question 3 is incorrect.') ### #### REAL EFFORT TASKS class S_Starter(Page): def is_displayed(player): return player.id_in_group != 1 class SRound0(Page): form_model = "player" form_fields = ['slider_value1', 'slider_value2', 'slider_value3', 'slider_value4', 'slider_value5', 'slider_value6', 'slider_value7', 'slider_value8', 'slider_value9', 'slider_value10', 'slider_value11', 'slider_value12', 'slider_value13', 'slider_value14', 'slider_value15', 'slider_value16', 'slider_value17', 'slider_value18', 'slider_value19', 'slider_value20', 'slider_value21', 'slider_value22', 'slider_value23', 'slider_value24', 'slider_value25', 'slider_value26', 'slider_value27', 'slider_value28', 'slider_value29', 'slider_value30', 'slider_value31', 'slider_value32', 'slider_value33', 'slider_value34', 'slider_value35', 'slider_value36', 'slider_value37', 'slider_value38', 'slider_value39', 'slider_value40', "p_number_sent"] def is_displayed(player): if player.round_number == 1: return player.id_in_group != 1 else: past_player = player.in_round(player.round_number - 1) return ((player.id_in_group == 2 and past_player.group.delayW1 == 0) or (player.id_in_group == 3 and past_player.group.delayW2 == 0) or (player.id_in_group == 4 and past_player.group.delayW3 == 0)) timeout_seconds = C.TIME_LIMIT @staticmethod def vars_for_template(player: Player): start_issue = C.ISSUE_START player.n_1 = random.randint(1, 100) player.n_2 = random.randint(1, 100) player.n_3 = random.randint(1, 100) player.n_4 = random.randint(1, 100) player.n_5 = random.randint(1, 100) player.n_6 = random.randint(1, 100) player.n_7 = random.randint(1, 100) player.n_8 = random.randint(1, 100) player.n_9 = random.randint(1, 100) player.n_10 = random.randint(1, 100) player.n_11 = random.randint(1, 100) player.n_12 = random.randint(1, 100) player.n_13 = random.randint(1, 100) player.n_14 = random.randint(1, 100) player.n_15 = random.randint(1, 100) player.n_16 = random.randint(1, 100) player.n_17 = random.randint(1, 100) player.n_18 = random.randint(1, 100) player.n_19 = random.randint(1, 100) player.n_20 = random.randint(1, 100) player.n_21 = random.randint(1, 100) player.n_22 = random.randint(1, 100) player.n_23 = random.randint(1, 100) player.n_24 = random.randint(1, 100) player.n_25 = random.randint(1, 100) player.n_26 = random.randint(1, 100) player.n_27 = random.randint(1, 100) player.n_28 = random.randint(1, 100) player.n_29 = random.randint(1, 100) player.n_30 = random.randint(1, 100) player.n_31 = random.randint(1, 100) player.n_32 = random.randint(1, 100) player.n_33 = random.randint(1, 100) player.n_34 = random.randint(1, 100) player.n_35 = random.randint(1, 100) player.n_36 = random.randint(1, 100) player.n_37 = random.randint(1, 100) player.n_38 = random.randint(1, 100) player.n_39 = random.randint(1, 100) player.n_40 = random.randint(1, 100) @staticmethod def before_next_page(player, timeout_happened): if player.slider_value1 == player.n_1: player.points += 1 if player.slider_value2 == player.n_2: player.points += 1 if player.slider_value3 == player.n_3: player.points += 1 if player.slider_value4 == player.n_4: player.points += 1 if player.slider_value5 == player.n_5: player.points += 1 if player.slider_value6 == player.n_6: player.points += 1 if player.slider_value7 == player.n_7: player.points += 1 if player.slider_value8 == player.n_8: player.points += 1 if player.slider_value9 == player.n_9: player.points += 1 if player.slider_value10 == player.n_10: player.points += 1 if player.slider_value11 == player.n_11: player.points += 1 if player.slider_value12 == player.n_12: player.points += 1 if player.slider_value13 == player.n_13: player.points += 1 if player.slider_value14 == player.n_14: player.points += 1 if player.slider_value15 == player.n_15: player.points += 1 if player.slider_value16 == player.n_16: player.points += 1 if player.slider_value17 == player.n_17: player.points += 1 if player.slider_value18 == player.n_18: player.points += 1 if player.slider_value19 == player.n_19: player.points += 1 if player.slider_value20 == player.n_20: player.points += 1 if player.slider_value21 == player.n_21: player.points += 1 if player.slider_value22 == player.n_22: player.points += 1 if player.slider_value23 == player.n_23: player.points += 1 if player.slider_value24 == player.n_24: player.points += 1 if player.slider_value25 == player.n_25: player.points += 1 if player.slider_value26 == player.n_26: player.points += 1 if player.slider_value27 == player.n_27: player.points += 1 if player.slider_value28 == player.n_28: player.points += 1 if player.slider_value29 == player.n_29: player.points += 1 if player.slider_value30 == player.n_30: player.points += 1 if player.slider_value31 == player.n_31: player.points += 1 if player.slider_value32 == player.n_32: player.points += 1 if player.slider_value33 == player.n_33: player.points += 1 if player.slider_value34 == player.n_34: player.points += 1 if player.slider_value35 == player.n_35: player.points += 1 if player.slider_value36 == player.n_36: player.points += 1 if player.slider_value37 == player.n_37: player.points += 1 if player.slider_value38 == player.n_38: player.points += 1 if player.slider_value39 == player.n_39: player.points += 1 if player.slider_value40 == player.n_40: player.points += 1 player.p_number_sent = player.points pass class SRound1(Page): form_model = "player" form_fields = ['slider_value1', 'slider_value2', 'slider_value3', 'slider_value4', 'slider_value5', 'slider_value6', 'slider_value7', 'slider_value8', 'slider_value9', 'slider_value10', 'slider_value11', 'slider_value12', 'slider_value13', 'slider_value14', 'slider_value15', 'slider_value16', 'slider_value17', 'slider_value18', 'slider_value19', 'slider_value20', 'slider_value21', 'slider_value22', 'slider_value23', 'slider_value24', 'slider_value25', 'slider_value26', 'slider_value27', 'slider_value28', 'slider_value29', 'slider_value30', 'slider_value31', 'slider_value32', 'slider_value33', 'slider_value34', 'slider_value35', 'slider_value36', 'slider_value37', 'slider_value38', 'slider_value39', 'slider_value40', "p_number_sent"] def is_displayed(player): rund = max(player.round_number - 1, 1) past_player = player.in_round(rund) return ((player.id_in_group == 2 and past_player.group.delayW1 == 5) or (player.id_in_group == 3 and past_player.group.delayW2 == 5) or (player.id_in_group == 4 and past_player.group.delayW3 == 5)) timeout_seconds = C.TIME_LIMIT @staticmethod def vars_for_template(player: Player): start_issue = C.ISSUE_START player.n_1 = random.randint(1, 100) player.n_2 = random.randint(1, 100) player.n_3 = random.randint(1, 100) player.n_4 = random.randint(1, 100) player.n_5 = random.randint(1, 100) player.n_6 = random.randint(1, 100) player.n_7 = random.randint(1, 100) player.n_8 = random.randint(1, 100) player.n_9 = random.randint(1, 100) player.n_10 = random.randint(1, 100) player.n_11 = random.randint(1, 100) player.n_12 = random.randint(1, 100) player.n_13 = random.randint(1, 100) player.n_14 = random.randint(1, 100) player.n_15 = random.randint(1, 100) player.n_16 = random.randint(1, 100) player.n_17 = random.randint(1, 100) player.n_18 = random.randint(1, 100) player.n_19 = random.randint(1, 100) player.n_20 = random.randint(1, 100) player.n_21 = random.randint(1, 100) player.n_22 = random.randint(1, 100) player.n_23 = random.randint(1, 100) player.n_24 = random.randint(1, 100) player.n_25 = random.randint(1, 100) player.n_26 = random.randint(1, 100) player.n_27 = random.randint(1, 100) player.n_28 = random.randint(1, 100) player.n_29 = random.randint(1, 100) player.n_30 = random.randint(1, 100) player.n_31 = random.randint(1, 100) player.n_32 = random.randint(1, 100) player.n_33 = random.randint(1, 100) player.n_34 = random.randint(1, 100) player.n_35 = random.randint(1, 100) player.n_36 = random.randint(1, 100) player.n_37 = random.randint(1, 100) player.n_38 = random.randint(1, 100) player.n_39 = random.randint(1, 100) player.n_40 = random.randint(1, 100) @staticmethod def before_next_page(player, timeout_happened): if player.slider_value1 == player.n_1: player.points += 1 if player.slider_value2 == player.n_2: player.points += 1 if player.slider_value3 == player.n_3: player.points += 1 if player.slider_value4 == player.n_4: player.points += 1 if player.slider_value5 == player.n_5: player.points += 1 if player.slider_value6 == player.n_6: player.points += 1 if player.slider_value7 == player.n_7: player.points += 1 if player.slider_value8 == player.n_8: player.points += 1 if player.slider_value9 == player.n_9: player.points += 1 if player.slider_value10 == player.n_10: player.points += 1 if player.slider_value11 == player.n_11: player.points += 1 if player.slider_value12 == player.n_12: player.points += 1 if player.slider_value13 == player.n_13: player.points += 1 if player.slider_value14 == player.n_14: player.points += 1 if player.slider_value15 == player.n_15: player.points += 1 if player.slider_value16 == player.n_16: player.points += 1 if player.slider_value17 == player.n_17: player.points += 1 if player.slider_value18 == player.n_18: player.points += 1 if player.slider_value19 == player.n_19: player.points += 1 if player.slider_value20 == player.n_20: player.points += 1 if player.slider_value21 == player.n_21: player.points += 1 if player.slider_value22 == player.n_22: player.points += 1 if player.slider_value23 == player.n_23: player.points += 1 if player.slider_value24 == player.n_24: player.points += 1 if player.slider_value25 == player.n_25: player.points += 1 if player.slider_value26 == player.n_26: player.points += 1 if player.slider_value27 == player.n_27: player.points += 1 if player.slider_value28 == player.n_28: player.points += 1 if player.slider_value29 == player.n_29: player.points += 1 if player.slider_value30 == player.n_30: player.points += 1 if player.slider_value31 == player.n_31: player.points += 1 if player.slider_value32 == player.n_32: player.points += 1 if player.slider_value33 == player.n_33: player.points += 1 if player.slider_value34 == player.n_34: player.points += 1 if player.slider_value35 == player.n_35: player.points += 1 if player.slider_value36 == player.n_36: player.points += 1 if player.slider_value37 == player.n_37: player.points += 1 if player.slider_value38 == player.n_38: player.points += 1 if player.slider_value39 == player.n_39: player.points += 1 if player.slider_value40 == player.n_40: player.points += 1 player.p_number_sent = player.points pass class SRound2(Page): form_model = "player" form_fields = ['slider_value1', 'slider_value2', 'slider_value3', 'slider_value4', 'slider_value5', 'slider_value6', 'slider_value7', 'slider_value8', 'slider_value9', 'slider_value10', 'slider_value11', 'slider_value12', 'slider_value13', 'slider_value14', 'slider_value15', 'slider_value16', 'slider_value17', 'slider_value18', 'slider_value19', 'slider_value20', 'slider_value21', 'slider_value22', 'slider_value23', 'slider_value24', 'slider_value25', 'slider_value26', 'slider_value27', 'slider_value28', 'slider_value29', 'slider_value30', 'slider_value31', 'slider_value32', 'slider_value33', 'slider_value34', 'slider_value35', 'slider_value36', 'slider_value37', 'slider_value38', 'slider_value39', 'slider_value40', "p_number_sent"] def is_displayed(player): rund = max(player.round_number - 1, 1) past_player = player.in_round(rund) return ((player.id_in_group == 2 and past_player.group.delayW1 == 10) or (player.id_in_group == 3 and past_player.group.delayW2 == 10) or (player.id_in_group == 4 and past_player.group.delayW3 == 10)) timeout_seconds = C.TIME_LIMIT @staticmethod def vars_for_template(player: Player): start_issue = C.ISSUE_START player.n_1 = random.randint(1, 100) player.n_2 = random.randint(1, 100) player.n_3 = random.randint(1, 100) player.n_4 = random.randint(1, 100) player.n_5 = random.randint(1, 100) player.n_6 = random.randint(1, 100) player.n_7 = random.randint(1, 100) player.n_8 = random.randint(1, 100) player.n_9 = random.randint(1, 100) player.n_10 = random.randint(1, 100) player.n_11 = random.randint(1, 100) player.n_12 = random.randint(1, 100) player.n_13 = random.randint(1, 100) player.n_14 = random.randint(1, 100) player.n_15 = random.randint(1, 100) player.n_16 = random.randint(1, 100) player.n_17 = random.randint(1, 100) player.n_18 = random.randint(1, 100) player.n_19 = random.randint(1, 100) player.n_20 = random.randint(1, 100) player.n_21 = random.randint(1, 100) player.n_22 = random.randint(1, 100) player.n_23 = random.randint(1, 100) player.n_24 = random.randint(1, 100) player.n_25 = random.randint(1, 100) player.n_26 = random.randint(1, 100) player.n_27 = random.randint(1, 100) player.n_28 = random.randint(1, 100) player.n_29 = random.randint(1, 100) player.n_30 = random.randint(1, 100) player.n_31 = random.randint(1, 100) player.n_32 = random.randint(1, 100) player.n_33 = random.randint(1, 100) player.n_34 = random.randint(1, 100) player.n_35 = random.randint(1, 100) player.n_36 = random.randint(1, 100) player.n_37 = random.randint(1, 100) player.n_38 = random.randint(1, 100) player.n_39 = random.randint(1, 100) player.n_40 = random.randint(1, 100) @staticmethod def before_next_page(player, timeout_happened): if player.slider_value1 == player.n_1: player.points += 1 if player.slider_value2 == player.n_2: player.points += 1 if player.slider_value3 == player.n_3: player.points += 1 if player.slider_value4 == player.n_4: player.points += 1 if player.slider_value5 == player.n_5: player.points += 1 if player.slider_value6 == player.n_6: player.points += 1 if player.slider_value7 == player.n_7: player.points += 1 if player.slider_value8 == player.n_8: player.points += 1 if player.slider_value9 == player.n_9: player.points += 1 if player.slider_value10 == player.n_10: player.points += 1 if player.slider_value11 == player.n_11: player.points += 1 if player.slider_value12 == player.n_12: player.points += 1 if player.slider_value13 == player.n_13: player.points += 1 if player.slider_value14 == player.n_14: player.points += 1 if player.slider_value15 == player.n_15: player.points += 1 if player.slider_value16 == player.n_16: player.points += 1 if player.slider_value17 == player.n_17: player.points += 1 if player.slider_value18 == player.n_18: player.points += 1 if player.slider_value19 == player.n_19: player.points += 1 if player.slider_value20 == player.n_20: player.points += 1 if player.slider_value21 == player.n_21: player.points += 1 if player.slider_value22 == player.n_22: player.points += 1 if player.slider_value23 == player.n_23: player.points += 1 if player.slider_value24 == player.n_24: player.points += 1 if player.slider_value25 == player.n_25: player.points += 1 if player.slider_value26 == player.n_26: player.points += 1 if player.slider_value27 == player.n_27: player.points += 1 if player.slider_value28 == player.n_28: player.points += 1 if player.slider_value29 == player.n_29: player.points += 1 if player.slider_value30 == player.n_30: player.points += 1 if player.slider_value31 == player.n_31: player.points += 1 if player.slider_value32 == player.n_32: player.points += 1 if player.slider_value33 == player.n_33: player.points += 1 if player.slider_value34 == player.n_34: player.points += 1 if player.slider_value35 == player.n_35: player.points += 1 if player.slider_value36 == player.n_36: player.points += 1 if player.slider_value37 == player.n_37: player.points += 1 if player.slider_value38 == player.n_38: player.points += 1 if player.slider_value39 == player.n_39: player.points += 1 if player.slider_value40 == player.n_40: player.points += 1 player.p_number_sent = player.points pass class SRound3(Page): form_model = "player" form_fields = ['slider_value1', 'slider_value2', 'slider_value3', 'slider_value4', 'slider_value5', 'slider_value6', 'slider_value7', 'slider_value8', 'slider_value9', 'slider_value10', 'slider_value11', 'slider_value12', 'slider_value13', 'slider_value14', 'slider_value15', 'slider_value16', 'slider_value17', 'slider_value18', 'slider_value19', 'slider_value20', 'slider_value21', 'slider_value22', 'slider_value23', 'slider_value24', 'slider_value25', 'slider_value26', 'slider_value27', 'slider_value28', 'slider_value29', 'slider_value30', 'slider_value31', 'slider_value32', 'slider_value33', 'slider_value34', 'slider_value35', 'slider_value36', 'slider_value37', 'slider_value38', 'slider_value39', 'slider_value40', "p_number_sent"] def is_displayed(player): rund = max(player.round_number - 1,1) past_player = player.in_round(rund) return ((player.id_in_group == 2 and past_player.group.delayW1 == 20) or (player.id_in_group == 3 and past_player.group.delayW2 == 20) or (player.id_in_group == 4 and past_player.group.delayW3 == 20)) timeout_seconds = C.TIME_LIMIT @staticmethod def vars_for_template(player: Player): start_issue = C.ISSUE_START player.n_1 = random.randint(1, 100) player.n_2 = random.randint(1, 100) player.n_3 = random.randint(1, 100) player.n_4 = random.randint(1, 100) player.n_5 = random.randint(1, 100) player.n_6 = random.randint(1, 100) player.n_7 = random.randint(1, 100) player.n_8 = random.randint(1, 100) player.n_9 = random.randint(1, 100) player.n_10 = random.randint(1, 100) player.n_11 = random.randint(1, 100) player.n_12 = random.randint(1, 100) player.n_13 = random.randint(1, 100) player.n_14 = random.randint(1, 100) player.n_15 = random.randint(1, 100) player.n_16 = random.randint(1, 100) player.n_17 = random.randint(1, 100) player.n_18 = random.randint(1, 100) player.n_19 = random.randint(1, 100) player.n_20 = random.randint(1, 100) player.n_21 = random.randint(1, 100) player.n_22 = random.randint(1, 100) player.n_23 = random.randint(1, 100) player.n_24 = random.randint(1, 100) player.n_25 = random.randint(1, 100) player.n_26 = random.randint(1, 100) player.n_27 = random.randint(1, 100) player.n_28 = random.randint(1, 100) player.n_29 = random.randint(1, 100) player.n_30 = random.randint(1, 100) player.n_31 = random.randint(1, 100) player.n_32 = random.randint(1, 100) player.n_33 = random.randint(1, 100) player.n_34 = random.randint(1, 100) player.n_35 = random.randint(1, 100) player.n_36 = random.randint(1, 100) player.n_37 = random.randint(1, 100) player.n_38 = random.randint(1, 100) player.n_39 = random.randint(1, 100) player.n_40 = random.randint(1, 100) @staticmethod def before_next_page(player, timeout_happened): if player.slider_value1 == player.n_1: player.points += 1 if player.slider_value2 == player.n_2: player.points += 1 if player.slider_value3 == player.n_3: player.points += 1 if player.slider_value4 == player.n_4: player.points += 1 if player.slider_value5 == player.n_5: player.points += 1 if player.slider_value6 == player.n_6: player.points += 1 if player.slider_value7 == player.n_7: player.points += 1 if player.slider_value8 == player.n_8: player.points += 1 if player.slider_value9 == player.n_9: player.points += 1 if player.slider_value10 == player.n_10: player.points += 1 if player.slider_value11 == player.n_11: player.points += 1 if player.slider_value12 == player.n_12: player.points += 1 if player.slider_value13 == player.n_13: player.points += 1 if player.slider_value14 == player.n_14: player.points += 1 if player.slider_value15 == player.n_15: player.points += 1 if player.slider_value16 == player.n_16: player.points += 1 if player.slider_value17 == player.n_17: player.points += 1 if player.slider_value18 == player.n_18: player.points += 1 if player.slider_value19 == player.n_19: player.points += 1 if player.slider_value20 == player.n_20: player.points += 1 if player.slider_value21 == player.n_21: player.points += 1 if player.slider_value22 == player.n_22: player.points += 1 if player.slider_value23 == player.n_23: player.points += 1 if player.slider_value24 == player.n_24: player.points += 1 if player.slider_value25 == player.n_25: player.points += 1 if player.slider_value26 == player.n_26: player.points += 1 if player.slider_value27 == player.n_27: player.points += 1 if player.slider_value28 == player.n_28: player.points += 1 if player.slider_value29 == player.n_29: player.points += 1 if player.slider_value30 == player.n_30: player.points += 1 if player.slider_value31 == player.n_31: player.points += 1 if player.slider_value32 == player.n_32: player.points += 1 if player.slider_value33 == player.n_33: player.points += 1 if player.slider_value34 == player.n_34: player.points += 1 if player.slider_value35 == player.n_35: player.points += 1 if player.slider_value36 == player.n_36: player.points += 1 if player.slider_value37 == player.n_37: player.points += 1 if player.slider_value38 == player.n_38: player.points += 1 if player.slider_value39 == player.n_39: player.points += 1 if player.slider_value40 == player.n_40: player.points += 1 player.p_number_sent = player.points pass class SRound4(Page): form_model = "player" form_fields = ['slider_value1', 'slider_value2', 'slider_value3', 'slider_value4', 'slider_value5', 'slider_value6', 'slider_value7', 'slider_value8', 'slider_value9', 'slider_value10', 'slider_value11', 'slider_value12', 'slider_value13', 'slider_value14', 'slider_value15', 'slider_value16', 'slider_value17', 'slider_value18', 'slider_value19', 'slider_value20', 'slider_value21', 'slider_value22', 'slider_value23', 'slider_value24', 'slider_value25', 'slider_value26', 'slider_value27', 'slider_value28', 'slider_value29', 'slider_value30', 'slider_value31', 'slider_value32', 'slider_value33', 'slider_value34', 'slider_value35', 'slider_value36', 'slider_value37', 'slider_value38', 'slider_value39', 'slider_value40', "p_number_sent"] def is_displayed(player): rund = max(player.round_number - 1, 1) past_player = player.in_round(rund) return ((player.id_in_group == 2 and past_player.group.delayW1 > 20) or (player.id_in_group == 3 and past_player.group.delayW2 > 20) or (player.id_in_group == 4 and past_player.group.delayW3 > 20)) timeout_seconds = C.TIME_LIMIT @staticmethod def vars_for_template(player: Player): start_issue = C.ISSUE_START player.n_1 = random.randint(1, 100) player.n_2 = random.randint(1, 100) player.n_3 = random.randint(1, 100) player.n_4 = random.randint(1, 100) player.n_5 = random.randint(1, 100) player.n_6 = random.randint(1, 100) player.n_7 = random.randint(1, 100) player.n_8 = random.randint(1, 100) player.n_9 = random.randint(1, 100) player.n_10 = random.randint(1, 100) player.n_11 = random.randint(1, 100) player.n_12 = random.randint(1, 100) player.n_13 = random.randint(1, 100) player.n_14 = random.randint(1, 100) player.n_15 = random.randint(1, 100) player.n_16 = random.randint(1, 100) player.n_17 = random.randint(1, 100) player.n_18 = random.randint(1, 100) player.n_19 = random.randint(1, 100) player.n_20 = random.randint(1, 100) player.n_21 = random.randint(1, 100) player.n_22 = random.randint(1, 100) player.n_23 = random.randint(1, 100) player.n_24 = random.randint(1, 100) player.n_25 = random.randint(1, 100) player.n_26 = random.randint(1, 100) player.n_27 = random.randint(1, 100) player.n_28 = random.randint(1, 100) player.n_29 = random.randint(1, 100) player.n_30 = random.randint(1, 100) player.n_31 = random.randint(1, 100) player.n_32 = random.randint(1, 100) player.n_33 = random.randint(1, 100) player.n_34 = random.randint(1, 100) player.n_35 = random.randint(1, 100) player.n_36 = random.randint(1, 100) player.n_37 = random.randint(1, 100) player.n_38 = random.randint(1, 100) player.n_39 = random.randint(1, 100) player.n_40 = random.randint(1, 100) @staticmethod def before_next_page(player, timeout_happened): if player.slider_value1 == player.n_1: player.points += 1 if player.slider_value2 == player.n_2: player.points += 1 if player.slider_value3 == player.n_3: player.points += 1 if player.slider_value4 == player.n_4: player.points += 1 if player.slider_value5 == player.n_5: player.points += 1 if player.slider_value6 == player.n_6: player.points += 1 if player.slider_value7 == player.n_7: player.points += 1 if player.slider_value8 == player.n_8: player.points += 1 if player.slider_value9 == player.n_9: player.points += 1 if player.slider_value10 == player.n_10: player.points += 1 if player.slider_value11 == player.n_11: player.points += 1 if player.slider_value12 == player.n_12: player.points += 1 if player.slider_value13 == player.n_13: player.points += 1 if player.slider_value14 == player.n_14: player.points += 1 if player.slider_value15 == player.n_15: player.points += 1 if player.slider_value16 == player.n_16: player.points += 1 if player.slider_value17 == player.n_17: player.points += 1 if player.slider_value18 == player.n_18: player.points += 1 if player.slider_value19 == player.n_19: player.points += 1 if player.slider_value20 == player.n_20: player.points += 1 if player.slider_value21 == player.n_21: player.points += 1 if player.slider_value22 == player.n_22: player.points += 1 if player.slider_value23 == player.n_23: player.points += 1 if player.slider_value24 == player.n_24: player.points += 1 if player.slider_value25 == player.n_25: player.points += 1 if player.slider_value26 == player.n_26: player.points += 1 if player.slider_value27 == player.n_27: player.points += 1 if player.slider_value28 == player.n_28: player.points += 1 if player.slider_value29 == player.n_29: player.points += 1 if player.slider_value30 == player.n_30: player.points += 1 if player.slider_value31 == player.n_31: player.points += 1 if player.slider_value32 == player.n_32: player.points += 1 if player.slider_value33 == player.n_33: player.points += 1 if player.slider_value34 == player.n_34: player.points += 1 if player.slider_value35 == player.n_35: player.points += 1 if player.slider_value36 == player.n_36: player.points += 1 if player.slider_value37 == player.n_37: player.points += 1 if player.slider_value38 == player.n_38: player.points += 1 if player.slider_value39 == player.n_39: player.points += 1 if player.slider_value40 == player.n_40: player.points += 1 player.p_number_sent = player.points pass ### summary class TaskResult(Page): def is_displayed(player): return player.id_in_group != 1 def vars_for_template(player): production = player.p_number_sent if production == 1: unit = "unit" else: unit = "units" return{"prod":production, "unit":unit} #### CHAT class Chat(Page): #timeout_seconds = C.CHAT_TIME_LIMIT def is_displayed(player): return player.id_in_group != 1 @staticmethod def vars_for_template(player): rund = str(player.round_number) +"_"+ str(player.group.id) time = C.CHAT_TIME_LIMIT def chat_nickname(player): nick = 'Worker {}'.format(player.id_in_group - 1) nick1 = nick + "." + str(player.round_number) return nick return {"nickname": chat_nickname(player), "rund":rund, "time":time} #return dict( # nickname= chat_nickname(player) #) ### complaining process class Complaining(Page): form_model = 'player' form_fields = ['p_complain'] def is_displayed(player): return player.id_in_group != 1 pass class MissedUnits(Page): form_model = 'player' form_fields = ['missed_units'] def is_displayed(player): return player.id_in_group != 1 and player.p_complain == "Yes" pass class ComplainingChoice(Page): form_model = "player" form_fields = ["complaining_choice"] def is_displayed(player): return player.id_in_group != 1 and player.p_complain == "Yes" #### cont here!!!! pass ### ROUND Payoffs ## waipage before deciding the vote class MyWaitPage(WaitPage): def after_all_players_arrive(self): c_treshold = 0 try: d1 = self.group.get_player_by_id(2).complaining_choice c_treshold += 1 except: d1 = 0 try: d2 = self.group.get_player_by_id(3).complaining_choice c_treshold += 1 except: d2 = 0 try: d3 = self.group.get_player_by_id(4).complaining_choice c_treshold += 1 except: d3 = 0 #d3 = player.group.get_player_by_id(4) voting = 0 if d1 == "Collective complaint": voting += 1 if d1 == "Individual complaint": voting += -1 if d2 == "Collective complaint": voting += 1 if d2 == "Individual complaint": voting += -1 if d3 == "Collective complaint": voting += 1 if d3 == "Individual complaint": voting += -1 if (voting > 0 and c_treshold > 1): cc = "Collective complaint" elif voting <0: cc = "Individual complaint" elif voting == 0 and c_treshold > 0: x = random.randint(0, 1) if x == 0: cc = "Collective complaint" else: cc = "Individual complaint" else: cc = "No Complaint" self.group.complaint = cc #### ROUND PAYOFFS ############### class RoundPO_W(Page): def is_displayed(player): return player.id_in_group != 1 def vars_for_template(player): ## needs to be updated for more workers ## add treshold to the other treatments as well! xx = player.p_number_sent * C.W_MULTIPLIER xx_total = sum(p.round_payoff for p in player.in_previous_rounds()) +xx return {"payoff": xx, "total_payoff":xx_total, "comp": player.group.complaint} #"d1":d1, "d2":d2, "d3":d3} def before_next_page(player, timeout_happened): xx = player.p_number_sent * C.W_MULTIPLIER player.round_payoff = xx pass #### Manager's turn #observation class ManagerObserves(Page): def is_displayed(player): return player.id_in_group == 1 def vars_for_template(player): player_2 = player.group.get_player_by_id(2) player_2_value = player_2.p_number_sent player_3 = player.group.get_player_by_id(3) player_3_value = player_3.p_number_sent player_4 = player.group.get_player_by_id(4) player_4_value = player_4.p_number_sent revenue = (player_2_value + player_3_value + player_4_value ) * C.M_MULTIPLIER # + C.PARTICIP_M ## + player_4_value!! ## add players 4, 5, 6 ..... p2_vector = ([p.p_number_sent for p in player.group.get_player_by_id(2).in_previous_rounds()] + [player.group.get_player_by_id(2).p_number_sent]) p3_vector = ([p.p_number_sent for p in player.group.get_player_by_id(3).in_previous_rounds()] + [player.group.get_player_by_id(3).p_number_sent]) p4_vector = ([p.p_number_sent for p in player.group.get_player_by_id(4).in_previous_rounds()] + [player.group.get_player_by_id(4).p_number_sent]) if player_2_value == 1: unit2 = "unit" else: unit2 = "units" if player_3_value == 1: unit3 = "unit" else: unit3 = "units" if player_4_value == 1: unit4 = "unit" else: unit4 = "units" n = player.round_number names = ["Worker"] + [f"Round {i}" for i in range(1, n + 1)] return {"number_sent2": player_2_value, "number_sent3": player_3_value, "unit2" : unit2, "unit3" : unit3, "unit4":unit4, "revenue": revenue, "all2":p2_vector, "all3":p3_vector, "names":names, "all4":p4_vector , "number_sent4": player_4_value} pass #complaints overview #collective class CollectiveComplaint(Page): def is_displayed(player): return player.id_in_group == 1 and player.group.complaint == "Collective complaint" def vars_for_template(player): x1 = player.group.get_player_by_id(2).missed_units x2 = player.group.get_player_by_id(3).missed_units x3 = player.group.get_player_by_id(4).missed_units if (x1 + x2 + x3) <= 1: unit = "unit" else: unit = "units" cost = 0 x = 0 if player.group.get_player_by_id(2).p_complain == "Yes": x += x1 c1 = "Worker 1 " cost += C.COMP_COST else: c1 = "" if player.group.get_player_by_id(3).p_complain == "Yes": x += x2 c2 = "Worker 2 " cost += C.COMP_COST else: c2 = "" if player.group.get_player_by_id(4).p_complain == "Yes": x += x3 c3 = "Worker 3 " cost += C.COMP_COST else: c3 = "" player.group.complaining_cost = cost ### the following just modifies the pronouns in the message's text if (player.group.get_player_by_id(2).field_maybe_none("complaining_choice") == "Collective complaint" and player.group.get_player_by_id(3).field_maybe_none("complaining_choice") == "Collective complaint") or (player.group.get_player_by_id(2).field_maybe_none("complaining_choice") == "Collective complaint" and player.group.get_player_by_id(4).field_maybe_none("complaining_choice") == "Collective complaint") or (player.group.get_player_by_id(3).field_maybe_none("complaining_choice") == "Collective complaint" and player.group.get_player_by_id(4).field_maybe_none("complaining_choice") == "Collective complaint"): #if (player.group.get_player_by_id(2).field_maybe_none( # "complaining_choice") == "Collective complaint" and player.group.get_player_by_id( # 3).field_maybe_none("complaining_choice") == "Collective complaint"): pronoun1 = "we" pronoun2 = "our" else: pronoun1 = "I" pronoun2 = "my" return {"missed_units": x, "c1":c1, "c2":c2,"c3":c3, "pron1": pronoun1, "pron2":pronoun2, "unit":unit } def before_next_page(player, timeout_happened): player.group.get_player_by_id(1).p_decision = None pass #individual class IndividualComplaint1(Page): def is_displayed(player): return (player.id_in_group == 1 and player.group.complaint == "Individual complaint" and player.group.get_player_by_id(2).p_complain == "Yes") def vars_for_template(player): xx = player.group.get_player_by_id(2).missed_units if xx == 1: uni = "unit" else: uni = "units" return {"missed_units": xx, "uni": uni} def before_next_page(player, timeout_happened): player.group.get_player_by_id(1).p_decision = None player.group.complaining_cost += C.COMP_COST pass class IndividualComplaint2(Page): def is_displayed(player): return (player.id_in_group == 1 and player.group.complaint == "Individual complaint" and player.group.get_player_by_id(3).p_complain == "Yes") def vars_for_template(player): xx = player.group.get_player_by_id(3).missed_units if xx == 1: uni = "unit" else: uni = "units" return {"missed_units": xx, "uni": uni} def before_next_page(player, timeout_happened): player.group.get_player_by_id(1).p_decision = None player.group.complaining_cost += C.COMP_COST pass class IndividualComplaint3(Page): def is_displayed(player): return (player.id_in_group == 1 and player.group.complaint == "Individual complaint" and player.group.get_player_by_id(4).p_complain == "Yes") def vars_for_template(player): xx = player.group.get_player_by_id(4).missed_units if xx == 1: uni = "unit" else: uni = "units" return {"missed_units": xx, "uni": uni} def before_next_page(player, timeout_happened): player.group.get_player_by_id(1).p_decision = None player.group.complaining_cost += C.COMP_COST pass class Decision(Page): form_model = 'player' form_fields = ['p_decision'] def is_displayed(player): return (player.id_in_group == 1 and player.group.complaint != "No complaint") def vars_for_template(self): player_2 = self.group.get_player_by_id(2) player_2_value = player_2.p_number_sent player_3 = self.group.get_player_by_id(3) player_3_value = player_3.p_number_sent player_4 = self.group.get_player_by_id(4) player_4_value = player_4.p_number_sent revenue = (player_2_value + player_3_value + player_4_value) * C.M_MULTIPLIER #+...+ player_4_value...+ C.PARTICIP_M cost = C.FIX_COST total_budget = revenue + sum(p.round_payoff for p in self.in_previous_rounds()) #self.p_decision = None return {"number_sent2": player_2_value, "number_sent3": player_3_value, "number_sent4": player_4_value, "cost": cost, "revenue": revenue, "total":total_budget } #"number_sent4": player_4_value def before_next_page(player, timeout_happened): n1 = random.randint(0, 100) n2 = random.randint(0, 100) n3 = random.randint(0, 100) player.group.aloha = 5 if player.round_number >1: previous_player = player.in_round(player.round_number - 1) player.group.delayW1 = previous_player.group.delayW1 player.group.delayW2 = previous_player.group.delayW2 player.group.delayW3 = previous_player.group.delayW3 if n1 < C.WORSENING and player.group.delayW1 != 0: player.group.delayW1 *= 2 if n1 < C.WORSENING and player.group.delayW1 == 0: player.group.delayW1 = 5 if n2 < C.WORSENING and player.group.delayW2 != 0: player.group.delayW2 *= 2 if n2 < C.WORSENING and player.group.delayW2 == 0: player.group.delayW2 = 5 if n3 < C.WORSENING and player.group.delayW3 != 0: player.group.delayW3 *= 2 if n3 < C.WORSENING and player.group.delayW3 == 0: player.group.delayW3 = 5 if player.p_decision == "Yes": player.group.delayW1 = 0 player.group.delayW2 = 0 player.group.delayW3 = 0 pass class ManagerRoundPayoff(Page): def is_displayed(player): return player.id_in_group == 1 def vars_for_template(player): if player.p_decision == "Yes": xx = (player.group.get_player_by_id(2).p_number_sent + player.group.get_player_by_id(3).p_number_sent + player.group.get_player_by_id(4).p_number_sent )* C.M_MULTIPLIER - C.FIX_COST # ++ player.group.get_player_by_id(4).p_number_sent... + C.PARTICIP_W else: xx = (player.group.get_player_by_id(2).p_number_sent + player.group.get_player_by_id(3).p_number_sent + player.group.get_player_by_id(4).p_number_sent )* C.M_MULTIPLIER #++ player.group.get_player_by_id(4).p_number_sent...+ C.PARTICIP_W total = sum(p.round_payoff for p in player.in_previous_rounds() ) + xx return {"payoff": xx, "total": total} def before_next_page(player, timeout_happened): if player.p_decision == "Yes": xx = (player.group.get_player_by_id(2).p_number_sent + player.group.get_player_by_id(3).p_number_sent + player.group.get_player_by_id(4).p_number_sent )* C.M_MULTIPLIER - C.FIX_COST # + + player.group.get_player_by_id(4).p_number_sent.... + C.PARTICIP_M else: xx = (player.group.get_player_by_id(2).p_number_sent + player.group.get_player_by_id(3).p_number_sent + player.group.get_player_by_id(4).p_number_sent )* C.M_MULTIPLIER #+ + player.group.get_player_by_id(4).p_number_sent...+ C.PARTICIP_M player.round_payoff = xx pass #### total payoffs class ResultsW(Page): def is_displayed(player): return player.id_in_group != 1 def vars_for_template(player): produced = player.p_number_sent if produced == 1: uni = "unit" else: uni = "units" if player.p_complain == "No": comp = "did not" else: comp = "did" if player.group.get_player_by_id(1).p_decision == "Yes": dec = "The manager fixed the issue. In the next round no issue will occur." else: dec = "The manager did not fix the issue. In the next round the issue may occur." mode = player.group.complaint total = sum(p.round_payoff for p in player.in_previous_rounds() ) + produced return{ "prod": produced, "uni": uni, "comp": comp,"dec": dec, "mode":mode, "total":total} class ResultsM(Page): def is_displayed(player): return player.id_in_group == 1 def vars_for_template(self): player_2 = self.group.get_player_by_id(2) player_2_value = player_2.p_number_sent player_3 = self.group.get_player_by_id(3) player_3_value = player_3.p_number_sent player_4 = self.group.get_player_by_id(4) player_4_value = player_4.p_number_sent p_dec = self.group.get_player_by_id(1).p_decision rund = max(self.round_number - 1, 1) dellay = self.group.in_round(rund).delay roundd = self.round_number round_payoff = int(self.round_payoff) if self.p_decision == "No": fix = "You did not fix any issue." else: fix = "You fixed the issue." if player_2_value == 1: uni1 = "unit" else: uni1 = "units" if player_3_value == 1: uni2 = "unit" else: uni2 = "units" if player_4_value == 1: uni3 = "unit" else: uni3 = "units" total = sum(p.round_payoff for p in self.in_previous_rounds() ) +round_payoff return { 'p_decision': p_dec, "number_sent2": player_2_value, "number_sent3": player_3_value, "number_sent4": player_4_value, "del":dellay, "rund":roundd, "round_payoff": round_payoff, "fix": fix, "uni1": uni1, "uni2":uni2, "uni3": uni3, "total":total, } ### issue generation def before_next_page(self, timeout_happened): if self.group.get_player_by_id(1).p_decision == "No": ## if there is no issue it may get worse from 0 to 5 if self.group.in_round(max(self.round_number - 1,1)).delay == 0: randy = random.randint(1, 100) if randy >= C.PROB_ISSUE_THE_SAME: delay = C.MIN_ISSUE self.group.delay = delay else: randy = random.randint(1, 100) if randy >= C.PROB_ISSUE_THE_SAME: delly = 2 * self.group.in_round(max(self.round_number - 1,1)).delay self.group.delay = delly ## if "Yes" than issue disappers for the next round else: self.group.delay = 0 pass ## bonus class Bonus2(Page): form_model = "group" form_fields = ['w1_bon', "w2_bon" , "w3_bon"] def is_displayed(self): return self.round_number == C.NUM_ROUNDS and self.id_in_group == 1 and (self.group.get_player_by_id(2)) def vars_for_template(player): if player.group.get_player_by_id(1).p_decision == "Yes": budget = ((player.group.get_player_by_id(2).p_number_sent + player.group.get_player_by_id(3).p_number_sent) * C.M_MULTIPLIER - C.FIX_COST ) * C.BONUS_SHARE if budget <0: b = 0 else: b = round(budget, 2) else: budget = ((player.group.get_player_by_id(2).p_number_sent + player.group.get_player_by_id(3).p_number_sent) * C.M_MULTIPLIER ) * C.BONUS_SHARE if budget < 0: b = 0 else: b = round(budget, 2) return {"budget":b} def error_message(player, values): if player.group.get_player_by_id(1).p_decision == "Yes": budget = ((player.group.get_player_by_id(2).p_number_sent + player.group.get_player_by_id(3).p_number_sent) * C.M_MULTIPLIER - C.FIX_COST) * C.BONUS_SHARE if budget < 0: b = 0 else: b = round(budget, 2) else: budget = ((player.group.get_player_by_id(2).p_number_sent + player.group.get_player_by_id(3).p_number_sent) * C.M_MULTIPLIER) * C.BONUS_SHARE if budget < 0: b = 0 else: b = round(budget, 2) if values['w1_bon'] + values['w2_bon'] + values['w3_bon'] != b: return f"The sum of the three numbers must be exactly {b}." if values['w1_bon'] < 0: return "The amount to Worker 1 has to be non-negative." if values['w2_bon'] < 0: return "The amount to Worker 2 has to be non-negative." if values['w3_bon'] < 0: return "The amount to Worker 3 has to be non-negative." ### bonus 3 - share of company profit, cannot be negative - not displayed to the manager, # no negative values class Bonus3(Page): form_model = "group" form_fields = ['w1_bon', "w2_bon", "w3_bon"] def is_displayed(player): if player.in_round(C.EVAL).p_decision == "No": try: budget = (player.group.get_player_by_id(2).in_round(C.EVAL).field_maybe_none("p_number_sent") + player.group.get_player_by_id(3).in_round(C.EVAL).field_maybe_none("p_number_sent") + player.group.get_player_by_id(4).in_round(C.EVAL).field_maybe_none("p_number_sent")) except: budget = 0 else: try: budget = (player.group.get_player_by_id(2).in_round(C.EVAL).field_maybe_none("p_number_sent") + player.group.get_player_by_id(3).in_round(C.EVAL).field_maybe_none("p_number_sent") + player.group.get_player_by_id(4).in_round(C.EVAL).field_maybe_none("p_number_sent") ) - C.FIX_COST except: budget = 0 return player.round_number == C.NUM_ROUNDS and player.id_in_group == 1 def vars_for_template(player): if player.in_round(C.EVAL).p_decision == "No": budget = (player.group.get_player_by_id(2).in_round(C.EVAL).p_number_sent + player.group.get_player_by_id(3).in_round(C.EVAL).p_number_sent + player.group.get_player_by_id(4).in_round(C.EVAL).p_number_sent) * C.BONUS_SHARE else: budget = (player.group.get_player_by_id(2).in_round(C.EVAL).p_number_sent + player.group.get_player_by_id(3).in_round(C.EVAL).p_number_sent + player.group.get_player_by_id(4).in_round(C.EVAL).p_number_sent- C.FIX_COST ) * C.BONUS_SHARE b = round(budget, 2) return {"budget":b} def error_message(player, values): if player.in_round(C.EVAL).p_decision == "No": budget = (player.group.get_player_by_id(2).in_round(C.EVAL).p_number_sent + player.group.get_player_by_id(3).in_round(C.EVAL).p_number_sent + player.group.get_player_by_id(4).in_round(C.EVAL).p_number_sent) * C.BONUS_SHARE else: budget = (player.group.get_player_by_id(2).in_round(C.EVAL).p_number_sent + player.group.get_player_by_id(3).in_round(C.EVAL).p_number_sent + player.group.get_player_by_id(4).in_round(C.EVAL).p_number_sent- C.FIX_COST) * C.BONUS_SHARE b = round(budget, 2) if values['w1_bon'] + values['w2_bon'] + values['w3_bon'] != b: return f"The sum of the three numbers must be exactly {b}." class Bonus4(Page): form_model = "group" form_fields = ['w1_bon', "w2_bon", "w3_bon"] def is_displayed(player): return player.round_number == C.NUM_ROUNDS and player.id_in_group == 1 def vars_for_template(player): budget = sum(p.round_payoff for p in player.in_previous_rounds() ) + player.round_payoff b = max(round(budget * C.BONUS_SHARE,2),0) return {"budget":b} def error_message(player, values): budget = sum(p.round_payoff for p in player.in_previous_rounds()) + player.round_payoff b = max(round(budget * C.BONUS_SHARE, 2), 0) if values['w1_bon'] + values['w2_bon'] + values['w3_bon'] != b: return f"The sum of the three numbers must be exactly {b}." ## FINAL PAYOFFS class PayoffM(Page): form_model = "player" def is_displayed(self): return self.round_number == C.NUM_ROUNDS and self.id_in_group == 1 def vars_for_template(player): profit = sum(p.round_payoff for p in player.in_previous_rounds()) + player.round_payoff cost = sum(p.group.complaining_cost for p in player.in_previous_rounds()) + player.group.complaining_cost total = max(profit - cost,0) player.final_payoff = total return {"profit": profit, "cost":cost, "total" : total} pass class PayoffW(Page): form_model = "player" #form_fields = ["final_payoff"] def is_displayed(self): return self.round_number == C.NUM_ROUNDS and self.id_in_group != 1 def vars_for_template(player): if player.id_in_group == 2: payoff = player.in_round(C.EVAL).round_payoff + player.group.in_round(C.NUM_ROUNDS).w1_bon round_po = player.in_round(C.EVAL).round_payoff bonus_po = player.group.in_round(C.NUM_ROUNDS).w1_bon player.final_payoff = round(payoff,2) euro = round(payoff * C.ECUEUR,2) player.payoff = euro elif player.id_in_group == 3: payoff = player.in_round(C.EVAL).round_payoff + player.group.in_round(C.NUM_ROUNDS).w2_bon round_po = player.in_round(C.EVAL).round_payoff bonus_po = player.group.in_round(C.NUM_ROUNDS).w2_bon player.final_payoff = round(payoff,2) euro = round(payoff * C.ECUEUR, 2) player.payoff = euro #elif player.id_in_group == 4: # payoff = player.in_round(C.EVAL).round_payoff + player.group.in_round(C.NUM_ROUNDS).w3_bon # round_po = player.in_round(C.EVAL).round_payoff # bonus_po = player.group.in_round(C.NUM_ROUNDS).w3_bon # player.final_payoff = round(payoff,2) #### and add extra players else: payoff = 0.999 Round = C.EVAL Idd = player.id_in_group return {"payoff": payoff, "round":Round, "id": Idd, "bonus": bonus_po, "round_po": round_po, "eur" : euro} class PayoffW2(Page): form_model = "player" def is_displayed(self): return self.round_number == C.NUM_ROUNDS and self.id_in_group != 1 def vars_for_template(player): payoff = sum( p.round_payoff for p in player.in_previous_rounds() ) + player.p_number_sent if player.id_in_group == 2: bonus = player.group.w1_bon if player.id_in_group == 3: bonus = player.group.w2_bon if player.id_in_group == 4: bonus = player.group.w3_bon total = payoff + bonus return {"payoff": payoff, "bonus":bonus, "total":total} ### THANKS!! class ThanksPage(Page): def is_displayed(self): return self.round_number == C.NUM_ROUNDS def vars_for_template(player): #payoff = round(player.final_payoff * C.ECUEUR,2) if player.id_in_group == 1: payoff = player.final_payoff * 10 else: pay = sum( p.round_payoff for p in player.in_previous_rounds() ) + player.p_number_sent if player.id_in_group == 2: bonus = player.group.w1_bon if player.id_in_group == 3: bonus = player.group.w2_bon if player.id_in_group == 4: bonus = player.group.w3_bon payoff = (pay + bonus)*10 return {"payoff": payoff} class ThanksPage2(Page): def is_displayed(self): return self.round_number == C.NUM_ROUNDS pass class WaitPager(WaitPage): pass class IntroWait(WaitPage): def is_displayed(self): return self.round_number == 1 # change so that only in round 1!! wait_for_all_groups = True title_text = "Welcome to the experiment!" body_text = ("Please, wait in silence until all the participants are ready.") pass page_sequence = [ Welcome, InstructionsW, InstructionsM, WaitPager, S_Starter, SRound0, SRound1, SRound2, SRound3,SRound4,TaskResult,WaitPager, Complaining, MissedUnits, ComplainingChoice, MyWaitPage, RoundPO_W, WaitPager, ManagerObserves, CollectiveComplaint, IndividualComplaint1, IndividualComplaint2, IndividualComplaint3, Decision, ManagerRoundPayoff, WaitPager, ResultsM, ResultsW, Bonus4, WaitPager, PayoffM, PayoffW2,ThanksPage] ## THIS SEEMS TO BE THE FULL LIST, not checked Comprehension in detail #page_sequence = [ IntroWait, Welcome, InstructionsW, InstructionsM, Comprehension, WaitPager, S_Starter, SRound0, SRound1, SRound2, # SRound3,SRound4,TaskResult,WaitPager, Chat, Complaining, MissedUnits, ComplainingChoice, MyWaitPage, # RoundPO_W, WaitPager, ManagerObserves, CollectiveComplaint, IndividualComplaint1, # IndividualComplaint2, IndividualComplaint3, Decision, ManagerRoundPayoff, # WaitPager, ResultsM, ResultsW, Bonus4, WaitPager, # PayoffM, PayoffW2,ThanksPage] # page_sequence = [ Welcome, InstructionsW, InstructionsM, Comprehension, WaitPager, S_Starter, SRound0, SRound1, SRound2, # SRound3,SRound4,TaskResult,WaitPager, Chat, Complaining, MissedUnits, ComplainingChoice, MyWaitPage, # RoundPO_W, WaitPager, ManagerObserves, CollectiveComplaint, IndividualComplaint1, # IndividualComplaint2, IndividualComplaint3, Decision, ManagerRoundPayoff, # WaitPager, ResultsM, ResultsW, Bonus4, WaitPager, # PayoffM, PayoffW2,ThanksPage] #Welcome, InstructionsW, InstructionsM are missing now!! # OOstart, Welcome, InstructionsW, InstructionsM, Comprehension, WaitPager,