from otree.api import Currency as c, currency_range, safe_json from ._builtin import WaitPage, Page as oTreePage from .models import Constants import numpy as np import random import string import re import json total_page_count = 59 decision_type_arr = ["Baseline", "Extreme", "EI_only", "EP_only", "Inbetween", "ShiftedBaseline"] #Control outside of array p1_Baseline = np.array([3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.0]) p2_Baseline = np.array([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]) p1_Baseline2 = 2*p1_Baseline p2_Baseline2 = 2*p2_Baseline p1_Extreme = np.array([7.5, 7.0, 6.5, 6.0, 5.5, 5.0, 4.5])/2 p2_Extreme = np.array([1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5])/2 p1_Extreme2 = p1_Extreme/2 p2_Extreme2 = p2_Extreme/2 p1_Control = p1_Baseline p2_Control = p2_Baseline p1_EI_Extreme = np.array([6.0, 5.5, 5.0, 4.5, 4.0, 3.5, 3.0]) p2_EI_Extreme = np.array([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0]) p1_EP_Extreme = np.array([5.0, 4.5, 4.0, 3.5, 3.0, 2.5, 2.0]) p2_EP_Extreme = np.array([1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0]) p1_EI_only = np.array([4.0, 3.75, 3.5, 3.25, 3.0, 2.75, 2.5]) p2_EI_only = np.array([2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5]) p1_EP_only = np.array([5.5, 5.25, 5.0, 4.75, 4.5, 4.25, 4.0]) p2_EP_only = np.array([0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0]) p1_Inbetween = 0.5*np.array([9.5, 9.0, 8.5, 8.0, 7.5, 7.0, 6.5]) p2_Inbetween = 0.5*np.array([2.5, 3.0, 3.5, 4.0, 3.5, 5.0, 5.5]) p1_EP_only = np.array([9.0, 8.5, 8.0, 7.5, 7.0, 6.5, 6.0])/2 p2_EP_only = np.array([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0])/2 p1_EI_only = np.array([4.0, 3.75, 3.5, 3.25, 3.0, 2.75, 2.5]) p2_EI_only = np.array([2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5]) p1_ShiftedBaseline = np.array([3.0, 2.5, 2.0, 1.5, 1.0, 0.5, 0.0])+0.5 p2_ShiftedBaseline = np.array([0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0])+0.25 p1_dict = {"Baseline": p1_Baseline, "Baseline2": p1_Baseline2, "Extreme": p1_Extreme, "Extreme2": p1_Extreme2, "Control": p1_Control, "EI_Extreme": p1_EI_Extreme, "EP_Extreme": p1_EP_Extreme, "EI_only": p1_EI_only, "EP_only": p1_EP_only, "Inbetween": p1_Inbetween, "ShiftedBaseline" : p1_ShiftedBaseline} p2_dict = {"Baseline": p2_Baseline, "Baseline2": p2_Baseline2, "Extreme": p2_Extreme, "Extreme2": p2_Extreme2, "Control": p2_Control, "EI_Extreme": p2_EI_Extreme, "EP_Extreme": p2_EP_Extreme, "EI_only": p2_EI_only, "EP_only": p2_EP_only, "Inbetween": p2_Inbetween, "ShiftedBaseline" : p2_ShiftedBaseline} p1_prize_dict = {"Baseline": 5.0, "Baseline2": 5.0, "Extreme": 5.0, "Extreme2": 5.0, "Control": 3.0, "EI_Extreme": 5.0, "EP_Extreme": 5.0, "EI_only": 5.0, "EP_only": 5.0, "Inbetween": 5.0, "ShiftedBaseline": 5.0} p2_prize_dict = {"Baseline": 1.0, "Baseline2": 1.0, "Extreme": 1.0, "Extreme2": 1.0, "Control": 3.0, "EI_Extreme": 1.0, "EP_Extreme": 1.0, "EI_only": 1.0, "EP_only": 1.0, "Inbetween": 1.0, "ShiftedBaseline": 1.0} #round helping variables num_decisions = 7 calibration_round = num_decisions + 1 all_rounds = list(range(1, calibration_round + 1)) decision_rounds = list(range(1, num_decisions + 1)) class Page(oTreePage): def get_progress(self): totpages = self.participant._max_page_index curpage = self.participant._index_in_pages return f"{curpage / totpages * 100:.0f}" class Beginning(Page): form_model = 'player' def is_displayed(self): return (self.player.round_number == 1) def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 #EDIT THIS SO WELCOME PAGE IN LATER ROUNDS BECOMES OBSOLETE #SET ALL VARIABLES FOR ALL ROUNDS IN THE FIRST ROUND self.player.debug_follows_type = np.random.binomial(n=1, p=0.25) p = self.player #prize_1_array = np.array([5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0]) #prize_2_array = np.array([1.0, 1.0, 1.0, #2.0, 2.0, 2.0, #1.0, 1.0, 1.0, #0.5, 0.5, 0.5]) #preis für spieler 1 muss etweder doppelt oder 5 mal so hoch sein wie für spieler 2 indices = np.array([0,1,2,3,4,5]) random.shuffle(indices) #prize_1_array = prize_1_array[indices] #prize_2_array = prize_2_array[indices] #add_sum_array = add_sum_array[indices] for r in decision_rounds: #assign treatments if p.id_in_group % 2 == 0: p.in_round(r).treatment = "Relative" if p.id_in_group % 2 == 1: p.in_round(r).treatment = "Absolute" if (p.id_in_group - 1) % 4 <= 1: p.in_round(r).sorting = "p1_ascending" if (p.id_in_group - 1) % 4 >= 2: p.in_round(r).sorting = "p1_descending" if r == 7: p.in_round(r).decision_type = "Control" p.in_round(r).p1_prize = p1_prize_dict["Control"] p.in_round(r).p2_prize = p2_prize_dict["Control"] else: index = indices[r-1] p.in_round(r).decision_type = decision_type_arr[index] p.in_round(r).p1_prize = p1_prize_dict[decision_type_arr[index]] p.in_round(r).p2_prize = p2_prize_dict[decision_type_arr[index]] if p.id_in_group % 2 == 0: p.in_round(8).treatment = "Relative" if p.id_in_group % 2 == 1: p.in_round(8).treatment = "Absolute" if (p.id_in_group - 1) % 4 <= 1: p.in_round(8).sorting = "p1_ascending" if (p.id_in_group - 1) % 4 >= 2: p.in_round(8).sorting = "p1_descending" p.in_round(8).p1_prize = 5.0 p.in_round(8).p2_prize = 1.0 p.in_round(8).decision_type = "Baseline" p.in_round(8).implemented_decision_number = random.choice([1,2,3,4,5,6,7]) p.in_round(8).implemented_decision_type = p.in_round(p.in_round(8).implemented_decision_number).decision_type class Introduction_Calibration(Page): def is_displayed(self): return (self.player.round_number == calibration_round) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Introduction_Decision(Page): form_model = 'player' def is_displayed(self): return (self.player.round_number == 1) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Introduction_Decision_1(Page): form_model = 'player' def is_displayed(self): return (self.player.round_number == 1) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Introduction_Decision_2(Page): form_model = 'player' def is_displayed(self): return (self.player.round_number == 1) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Comprehension(Page): form_model = 'player' form_fields = ['comprehension_tries_1', 'comprehension_tries_2', 'comprehension_tries_3', 'comprehension_tries_4'] def is_displayed(self): return (self.player.round_number == 1) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count)), 'treatment': safe_json(self.player.treatment)} class Before_Decision(Page): form_model = 'player' def is_displayed(self): return (self.player.round_number in [1,7]) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Decision_slim(Page): form_model = 'player' form_fields = ['p1_wealth', 'p2_wealth', 'option_chosen'] def is_displayed(self): return (self.player.round_number in decision_rounds) def vars_for_template(self): p1_arr = list(p1_dict[self.player.decision_type]) p2_arr = list(p2_dict[self.player.decision_type]) return {'p1_prize': safe_json(self.player.p1_prize), 'p2_prize': safe_json(self.player.p2_prize), 'p1_arr': json.dumps(p1_arr), 'p2_arr': json.dumps(p2_arr), 'decision_type': safe_json(self.player.decision_type), "sorting": safe_json(self.player.sorting), 'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 p = self.player p.p1_income = p.p1_wealth - p.p1_prize p.p2_income = p.p2_wealth - p.p2_prize p.p1_percentage = (p.p1_wealth / p.p1_prize - 1)*100 p.p2_percentage = (p.p2_wealth / p.p2_prize - 1)*100 p.equal_income_dummy = (np.abs(p.p1_income - p.p2_income) < 0.05) p.equal_percentage_dummy = (np.abs(p.p1_percentage - p.p2_percentage) < 3) if p.decision_type == "Baseline": p.in_round(7).p1_correct_guess = p.p1_wealth p.in_round(7).p2_correct_guess = p.p2_wealth class Guess(Page): form_model = 'player' form_fields = ['guess'] def is_displayed(self): return (self.player.round_number == 7) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 index1 = [0,1,2] random.shuffle(index1) index2 = [0,1,2] random.shuffle(index2) if self.player.treatment == "Relative": self.player.q_text_1 = question_texts_rel[index1[0]] self.player.q_text_2 = question_texts_rel[index1[1]] self.player.q_text_3 = question_texts_rel[index1[2]] self.player.q_text_4 = question_texts_abs[index2[0]] self.player.q_text_5 = question_texts_abs[index2[1]] self.player.q_text_6 = question_texts_abs[index2[2]] if self.player.treatment == "Absolute": self.player.q_text_1 = question_texts_abs[index1[0]] self.player.q_text_2 = question_texts_abs[index1[1]] self.player.q_text_3 = question_texts_abs[index1[2]] self.player.q_text_4 = question_texts_rel[index2[0]] self.player.q_text_5 = question_texts_rel[index2[1]] self.player.q_text_6 = question_texts_rel[index2[2]] def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Guess_2(Page): form_model = 'player' form_fields = ['p1_guess', 'p2_guess'] def is_displayed(self): return (self.player.round_number == 7) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 if (self.player.p1_guess - self.player.p1_correct_guess <=0.5 and self.player.p2_guess - self.player.p2_correct_guess <=0.5): self.player.guess_bonus = True else: self.player.guess_bonus = False def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Questions(Page): form_model = 'player' form_fields = ['fairness_answer'] def is_displayed(self): return (self.player.round_number == 7) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Motive(Page): form_model = 'player' form_fields = ['motive'] def is_displayed(self): return (self.player.round_number == 7) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Meritocracy(Page): form_model = 'player' form_fields = ['meritocracy_answer'] def is_displayed(self): return (self.player.round_number == 7) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Advantage(Page): form_model = 'player' form_fields = ['advantage_answer'] def is_displayed(self): return (self.player.round_number == 7) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Questions_2(Page): form_model = 'player' form_fields = ['q_answer_1', 'q_answer_2', 'q_answer_3'] def is_displayed(self): return (self.player.round_number == 7) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count)), 'q_text_1': safe_json(self.player.q_text_1), 'q_text_2': safe_json(self.player.q_text_2), 'q_text_3': safe_json(self.player.q_text_3),} class Questions_3(Page): form_model = 'player' form_fields = ['q_answer_4', 'q_answer_5', 'q_answer_6'] def is_displayed(self): return (self.player.round_number == 7) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count)), 'q_text_4': safe_json(self.player.q_text_4), 'q_text_5': safe_json(self.player.q_text_5), 'q_text_6': safe_json(self.player.q_text_6),} class AttentionCheck(Page): form_model = 'player' form_fields = ['attention_check_answer', 'attention_slider_touched'] def is_displayed(self): return (self.player.round_number == 3) def error_message(player, values): if values["attention_slider_touched"] == 0: return "Bitte berühren Sie den Slider, um eine Umverteilungsentscheidung zu treffen." def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 p = self.player if p.attention_check_answer == -100: p.attention_check_passed = 1; else: p.attention_check_passed = 0; def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Comprehension_Calibration(Page): form_model = 'player' form_fields = ['comprehension_tries_calibration_1'] def is_displayed(self): return (self.player.round_number == calibration_round) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count)), 'treatment': safe_json(self.player.treatment)} class Calibration_1(Page): form_model = 'player' form_fields = ['calibration_1_p1_wealth', 'calibration_1_p2_wealth'] def vars_for_template(self): p1_arr = list(p1_dict["Baseline"]) p2_arr = list(p2_dict["Baseline"]) return {'p1_prize': safe_json(self.player.p1_prize), 'p2_prize': safe_json(self.player.p2_prize), 'p1_arr': json.dumps(p1_arr), 'p2_arr': json.dumps(p2_arr), "sorting": safe_json(self.player.sorting), 'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 p1_income = self.player.calibration_1_p1_wealth - self.player.p1_prize p2_income = self.player.calibration_1_p2_wealth - self.player.p2_prize self.player.calibration_1_correct = (np.abs(p1_income - p2_income) < 0.05) def is_displayed(self): return (self.player.round_number == calibration_round) class Calibration_2(Page): form_model = 'player' form_fields = ['calibration_2_p1_wealth', 'calibration_2_p2_wealth'] def vars_for_template(self): p1_arr = list(p1_dict["Baseline"]) p2_arr = list(p2_dict["Baseline"]) return {'p1_prize': safe_json(self.player.p1_prize), 'p2_prize': safe_json(self.player.p2_prize), 'p1_arr': json.dumps(p1_arr), 'p2_arr': json.dumps(p2_arr), "sorting": safe_json(self.player.sorting), 'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 p1_income = self.player.calibration_2_p1_wealth - self.player.p1_prize p2_income = self.player.calibration_2_p2_wealth - self.player.p2_prize p1_percentage = 100*p1_income/self.player.p1_prize p2_percentage = 100*p2_income/self.player.p2_prize self.player.calibration_2_correct = (np.abs(p1_percentage - p2_percentage) < 3) def is_displayed(self): return (self.player.round_number == calibration_round) class Final_Questions(Page): form_model = 'player' form_fields = ['knew_difference', 'would_change', 'final_comments'] def is_displayed(self): return (self.player.round_number == calibration_round) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Reconsider_1(Page): form_model = 'player' def is_displayed(self): return (self.player.round_number == calibration_round) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): return {'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Reconsider_2(Page): form_model = 'player' form_fields = ['wants_to_change'] def is_displayed(self): return (self.player.round_number == calibration_round) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 def vars_for_template(self): r = self.player.implemented_decision_number p1_arr = list(p1_dict[self.player.in_round(r).decision_type]) p2_arr = list(p2_dict[self.player.in_round(r).decision_type]) return {'p1_prize': safe_json(self.player.in_round(r).p1_prize), 'p2_prize': safe_json(self.player.in_round(r).p2_prize), 'p1_arr': json.dumps(p1_arr), 'p2_arr': json.dumps(p2_arr), 'decision_type': safe_json(self.player.in_round(r).decision_type), "sorting": safe_json(self.player.in_round(r).sorting), "initial_decision": safe_json(self.player.in_round(r).option_chosen), 'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} class Reconsider_3(Page): form_model = 'player' form_fields = ["implemented_p1_wealth", "implemented_p2_wealth", "implemented_option_chosen"] def is_displayed(self): return (self.player.round_number == calibration_round) def before_next_page(self): for r in all_rounds: self.player.in_round(r).progress = np.int(100*self.participant._index_in_pages / self.participant._max_page_index) self.participant.vars['page_count'] = self.participant.vars['page_count'] + 1 if self.player.implemented_option_chosen == -1: i = self.player.implemented_decision_number self.player.implemented_option_chosen = self.player.in_round(i).option_chosen self.player.implemented_p1_wealth = self.player.in_round(i).p1_wealth self.player.implemented_p2_wealth = self.player.in_round(i).p2_wealth def vars_for_template(self): r = self.player.implemented_decision_number p1_arr = list(p1_dict[self.player.in_round(r).decision_type]) p2_arr = list(p2_dict[self.player.in_round(r).decision_type]) return {'p1_prize': safe_json(self.player.in_round(r).p1_prize), 'p2_prize': safe_json(self.player.in_round(r).p2_prize), 'p1_arr': json.dumps(p1_arr), 'p2_arr': json.dumps(p2_arr), 'decision_type': safe_json(self.player.in_round(r).decision_type), "sorting": safe_json(self.player.in_round(r).sorting), "initial_decision": safe_json(self.player.in_round(r).option_chosen), 'progress': np.int(100*(self.participant.vars['page_count'] / total_page_count))} page_sequence = [Beginning, Introduction_Decision, Comprehension, Before_Decision, Decision_slim, Motive, Guess_2, Advantage, Meritocracy, Introduction_Calibration, Comprehension_Calibration, Calibration_1, Calibration_2, Final_Questions, Reconsider_1, Reconsider_2, Reconsider_3]