from otree.api import Currency as c, currency_range from ._builtin import Page from . import models from .models import Constants import math class Agreement(Page): form_model = 'player' form_fields = ['acceptance'] def acceptance_error_message(self, value): is_correct = True if value != is_correct: return 'You cannot proceed without accepting the Participation Agreement.' class Introduction(Page): def vars_for_template(self): return { 'treatment': self.player.treatment, } class Introduction_quest(Page): form_model = 'player' form_fields = ['check1', 'check2', 'check3', 'check4', 'check5'] def vars_for_template(self): return { 'treatment': self.player.treatment, } class Introduction_ans(Page): def vars_for_template(self): return { 'treatment': self.player.treatment, 'ans1': self.player.check1, 'ans2': self.player.check2, 'ans3': self.player.check3, 'ans4': self.player.check4, 'ans5': self.player.check5 } class Earning_Pre(Page): def vars_for_template(self): return { 'treatment': self.player.treatment, } class Earning_Trial(Page): pass class Earning_Trial1(Page): form_model = 'player' form_fields = ['task0m'] timeout_seconds = Constants.q_timeout class Earning_Trial2(Page): form_model = 'player' form_fields = ['task0c'] timeout_seconds = Constants.q_timeout class Earning_Trial3(Page): form_model = 'player' form_fields = ['task0a'] timeout_seconds = Constants.q_timeout class Earning_Trial_Result(Page): def vars_for_template(self): return { 'task0m': self.player.task0m, 'task0c': self.player.task0c.upper(), 'task0a': self.player.task0a.upper(), 'correct': (self.player.task0m==86)+(self.player.task0c.upper()=="CHINA")+(self.player.task0a.upper()=="DOG"), 'income': Constants.q_points * ((self.player.task0m==86)+(self.player.task0c.upper()=="CHINA")+(self.player.task0a.upper()=="DOG")) } class Earning_Real(Page): def vars_for_template(self): return { 'treatment': self.player.treatment, } class Earning_Real1(Page): form_model = 'player' form_fields = ['task1m'] timeout_seconds = Constants.q_timeout class Earning_Real2(Page): form_model = 'player' form_fields = ['task1c'] timeout_seconds = Constants.q_timeout class Earning_Real3(Page): form_model = 'player' form_fields = ['task1a'] timeout_seconds = Constants.q_timeout class Earning_Real4(Page): form_model = 'player' form_fields = ['task2m'] timeout_seconds = Constants.q_timeout class Earning_Real5(Page): form_model = 'player' form_fields = ['task2c'] timeout_seconds = Constants.q_timeout class Earning_Real6(Page): form_model = 'player' form_fields = ['task2a'] timeout_seconds = Constants.q_timeout class Earning_Real7(Page): form_model = 'player' form_fields = ['task3m'] timeout_seconds = Constants.q_timeout class Earning_Real8(Page): form_model = 'player' form_fields = ['task3c'] timeout_seconds = Constants.q_timeout class Earning_Real9(Page): form_model = 'player' form_fields = ['task3a'] timeout_seconds = Constants.q_timeout class Earning_Real13(Page): form_model = 'player' form_fields = ['task5m'] timeout_seconds = Constants.q_timeout class Earning_Real14(Page): form_model = 'player' form_fields = ['task5c'] timeout_seconds = Constants.q_timeout class Earning_Real15(Page): form_model = 'player' form_fields = ['task5a'] timeout_seconds = Constants.q_timeout def before_next_page(self): self.player.correct_answers = (self.player.task1m == 111) + (self.player.task1c.upper() == 'INDIA') + (self.player.task1a.upper() == 'ELEPHANT') + \ (self.player.task2m == 194) + (self.player.task2c.upper() == 'ITALY') + (self.player.task2a.upper() == 'EAGLE') + \ (self.player.task3m == 43) + (self.player.task3c.upper() == 'JAPAN') + (self.player.task3a.upper() == 'CROCODILE') + \ (self.player.task5m == 392) + (self.player.task5c.upper() == 'TANZANIA') + (self.player.task5a.upper() == 'OCTOPUS') class Earning_Result(Page): def vars_for_template(self): return{ 'task1m': self.player.task1m, 'task2m': self.player.task2m, 'task3m': self.player.task3m, 'task5m': self.player.task5m, 'task1c': self.player.task1c.upper(), 'task2c': self.player.task2c.upper(), 'task3c': self.player.task3c.upper(), 'task5c': self.player.task5c.upper(), 'task1a': self.player.task1a.upper(), 'task2a': self.player.task2a.upper(), 'task3a': self.player.task3a.upper(), 'task5a': self.player.task5a.upper(), 'correct': self.player.correct_answers, 'income': Constants.q_points * self.player.correct_answers } def before_next_page(self): self.player.taxdue = \ (self.player.treatment==1) * (self.player.correct_answers * Constants.q_points) * .15 + \ (self.player.treatment>1) * (max(0, (self.player.correct_answers * Constants.q_points) - 40000) * .45) class Sumstats(Page) : def is_displayed(self): return self.player.treatment == 3 def vars_for_template(self): return{ 'matchgroup': self.player.matchgroup, 'correct': self.player.correct_answers, 'income': Constants.q_points * self.player.correct_answers, 'treatment': self.player.treatment, } class Sumstats2(Page) : def is_displayed(self): return self.player.treatment != 3 def vars_for_template(self): return{ 'matchgroup': self.player.matchgroup, 'correct': self.player.correct_answers, 'income': Constants.q_points * self.player.correct_answers, 'treatment': self.player.treatment, } class AttentionCheck(Page): form_model = 'player' form_fields = ['check6', 'check7', 'check8', 'check9'] def is_displayed(self): return self.player.treatment == 4 def vars_for_template(self): return{ 'income': self.player.correct_answers * Constants.q_points, 'treatment': self.player.treatment } def check6_error_message(self, value): is_correct = self.player.correct_answers * Constants.q_points self.player.att_attempts += 1 if value != is_correct: return 'Incorrect. Introduce the correct number.' def check7_error_message(self, value): is_correct = 40000 if value != is_correct: return 'Incorrect. Introduce the correct number.' def check8_error_message(self, value): is_correct = 10000*(self.player.correct_answers < 3) + 40000*(self.player.correct_answers > 2) if value != is_correct: return 'Incorrect. Introduce the correct number.' def check9_error_message(self, value): is_correct = 100 / self.player.correct_answers if self.player.correct_answers else 0 if value != math.floor(is_correct) and value != math.ceil(is_correct) and self.player.correct_answers > 0: return 'Incorrect. You can calculate it dividing 10,000 by your Income, then multiplying by 100 (and rounding). For example if your income was 40,000 ECU, the answer would be 25.' elif value!= math.floor(is_correct) and self.player.correct_answers == 0: return 'Since your income was 0 ECU, just write 0 to be allowed to proceed.' class TaxScheme(Page): form_model = 'player' form_fields = ['tax_q1', 'tax_q2', 'tax_q3', 'tax_q4'] def is_displayed(self): return self.player.treatment < 3 def vars_for_template(self): return{ 'income': self.player.correct_answers * Constants.q_points, 'treatment': self.player.treatment, 'taxdue': self.player.taxdue } def tax_q1_error_message(self, value): is_correct = self.player.correct_answers * Constants.q_points self.player.tax_attempts += 1 if value != is_correct: return 'Incorrect. Please revise the amount.' def tax_q2_error_message(self, value): is_correct = self.player.taxdue if value != is_correct: return 'Incorrect. Please revise the amount.' def tax_q3_error_message(self, value): is_correct = self.player.taxdue * 100 / (self.player.correct_answers * Constants.q_points) if self.player.correct_answers else 0 if value != math.floor(is_correct) and value != math.ceil(is_correct) and self.player.correct_answers > 0: return 'Incorrect. You can calculate it dividing Taxes by Income, then multiplying by 100 (and rounding).' elif value!= math.floor(is_correct) and self.player.correct_answers == 0: return 'Since your income was 0 ECU, just write 0 to be allowed to proceed.' def tax_q4_error_message(self, value): is_correct = 0 + (self.player.treatment == 1)*6000 if value != is_correct: return 'Incorrect. You can calculate it by multiplying 40,000 ECU times the tax rate that applies.' class TaxScheme2(Page): form_model = 'player' form_fields = ['tax_q1', 'tax_q2', 'tax_q3', 'tax_q4'] def is_displayed(self): return self.player.treatment == 3 def vars_for_template(self): return{ 'income': self.player.correct_answers * Constants.q_points, 'treatment': self.player.treatment, 'taxdue': self.player.taxdue } def tax_q1_error_message(self, value): is_correct = self.player.correct_answers * Constants.q_points self.player.tax_attempts += 1 if value != is_correct: return 'Incorrect. Please revise the amount.' def tax_q2_error_message(self, value): is_correct = self.player.taxdue if value != is_correct: return 'Incorrect. Please revise the amount.' def tax_q3_error_message(self, value): is_correct = self.player.taxdue * 100 / (self.player.correct_answers * Constants.q_points) if self.player.correct_answers else 0 if value != math.floor(is_correct) and value != math.ceil(is_correct) and self.player.correct_answers > 0: return 'Incorrect. You can calculate it dividing Taxes by Income, then multiplying by 100 (and rounding).' elif value!= math.floor(is_correct) and self.player.correct_answers == 0: return 'Since your income was 0 ECU, just write 0 to be allowed to proceed.' def tax_q4_error_message(self, value): is_correct = 0 + (self.player.treatment == 1)*6000 if value != is_correct: return 'Incorrect. You can calculate it by multiplying 40,000 ECU times the tax rate that applies.' class TaxScheme3(Page): def is_displayed(self): return self.player.treatment == 4 def vars_for_template(self): return{ 'income': self.player.correct_answers * Constants.q_points, 'treatment': self.player.treatment, 'taxdue': self.player.taxdue } class Qbonus_pre(Page) : pass class Qbonus(Page) : form_model = 'player' form_fields = ['selfrank', 'meaninc', 'abovemean'] def vars_for_template(self): return{ 'earnings': self.player.correct_answers * Constants.q_points, 'treatment': self.player.treatment, 'taxdue': self.player.taxdue } def before_next_page(self): self.player.selfrank_r = self.player.selfrank self.player.meaninc_r = self.player.meaninc self.player.abovemean_r = self.player.abovemean class Qbonus_r(Page): form_model = 'player' form_fields = ['selfrank_r', 'meaninc_r', 'abovemean_r'] def vars_for_template(self): return { 'earnings': self.player.correct_answers * Constants.q_points, 'treatment': self.player.treatment, 'prob': self.player.abovemean, 'taxdue': self.player.taxdue } def before_next_page(self): #Earned bonus: self.player.bonuspre = Constants.b_points * ( (self.player.matchgroup == 0) * ( (self.player.payquest == 2) * (self.player.meaninc_r == 10) + (self.player.payquest == 3) * (self.player.correct_answers > 4) + (self.player.payquest == 1)*( (self.player.correct_answers == 0 and self.player.selfrank_r == 20) + (self.player.correct_answers == 1 and self.player.selfrank_r >= 18 ) + (self.player.correct_answers == 2 and self.player.selfrank_r >= 16 and self.player.selfrank_r <= 18) + (self.player.correct_answers == 3 and self.player.selfrank_r >= 14 and self.player.selfrank_r <= 16) + (self.player.correct_answers == 4 and self.player.selfrank_r >= 11 and self.player.selfrank_r <= 14) + (self.player.correct_answers == 5 and self.player.selfrank_r >= 9 and self.player.selfrank_r <= 10) + (self.player.correct_answers == 6 and self.player.selfrank_r >= 5 and self.player.selfrank_r <= 8) + (self.player.correct_answers == 7 and self.player.selfrank_r >= 4 and self.player.selfrank_r <= 5) + (self.player.correct_answers == 8 and self.player.selfrank_r >= 3 and self.player.selfrank_r <= 4) + (self.player.correct_answers == 9 and self.player.selfrank_r >= 2 and self.player.selfrank_r <= 3) + (self.player.correct_answers == 10 and self.player.selfrank_r <= 2) + (self.player.correct_answers >= 11 and self.player.selfrank_r == 1) ) ) + (self.player.matchgroup == 1) * ( (self.player.payquest == 2) * (self.player.meaninc_r == 12) + (self.player.payquest == 3) * (self.player.correct_answers > 5) + (self.player.payquest == 1) * ( (self.player.correct_answers <= 1 and self.player.selfrank_r == 20) + (self.player.correct_answers == 2 and self.player.selfrank_r >= 18 and self.player.selfrank_r <= 19) + (self.player.correct_answers == 3 and self.player.selfrank_r >= 17 and self.player.selfrank_r <= 18) + (self.player.correct_answers == 4 and self.player.selfrank_r >= 15 and self.player.selfrank_r <= 17) + (self.player.correct_answers == 5 and self.player.selfrank_r >= 11 and self.player.selfrank_r <= 15) + (self.player.correct_answers == 6 and self.player.selfrank_r >= 8 and self.player.selfrank_r <= 11) + (self.player.correct_answers == 7 and self.player.selfrank_r >= 5 and self.player.selfrank_r <= 8) + (self.player.correct_answers == 8 and self.player.selfrank_r >= 3 and self.player.selfrank_r <= 5) + (self.player.correct_answers == 9 and self.player.selfrank_r >= 2 and self.player.selfrank_r <= 3) + (self.player.correct_answers == 10 and self.player.selfrank_r <= 2) + (self.player.correct_answers >= 11 and self.player.selfrank_r == 1) ) ) ) self.player.bonus = \ (self.player.payquest == 1) * self.player.bonuspre + (self.player.payquest == 2) * self.player.bonuspre + \ (self.player.payquest == 3) * (self.player.bonuspre * (self.player.threshold <= self.player.abovemean_r) + Constants.b_points * (self.player.abovemean_r < self.player.threshold) * (self.player.threshold > self.player.draw)) self.player.payoff = self.player.correct_answers*Constants.q_points - self.player.taxdue + self.player.bonus class Demographics(Page): form_model = 'player' form_fields = ['age', 'gender', 'education', 'status', 'taxSA', 'realincome', 'realtaxes', 'quintile'] class Results(Page): def vars_for_template(self): return{ 'payquest': self.player.payquest, 'correct': self.player.correct_answers, 'income': self.player.correct_answers * Constants.q_points, 'taxdue': self.player.taxdue, 'bonus': self.player.bonus, 'payoff': self.player.payoff, 'real': (int(self.player.payoff *100 / Constants.equivalency))/100, 'matchgroup': self.player.matchgroup, 'selfrank': (self.player.selfrank_r==1)*"highest 5 earners" + (self.player.selfrank_r==2)*"between 6th to 10th" + (self.player.selfrank_r==3)*"between 11th to 15th" + (self.player.selfrank_r==4)*"between 16th to 20th" + (self.player.selfrank_r==5)*"between 21st to 25th" + (self.player.selfrank_r==6)*"between 26th to 30th" + (self.player.selfrank_r==7)*"between 31st to 35th" + (self.player.selfrank_r==8)*"between 36th to 40th" + (self.player.selfrank_r==9)*"between 41st to 45th" + (self.player.selfrank_r==10)*"between 46th to 50th" + (self.player.selfrank_r==11)*"between 51st to 55th" + (self.player.selfrank_r==12)*"between 56th to 60th" + (self.player.selfrank_r==13)*"between 61st to 65th" + (self.player.selfrank_r==14)*"between 66th to 70th" + (self.player.selfrank_r==15)*"between 71st to 75th" + (self.player.selfrank_r==16)*"between 76th to 80th" + (self.player.selfrank_r==17)*"between 81st to 85th" + (self.player.selfrank_r==18)*"between 86th to 90th" + (self.player.selfrank_r==19)*"between 91st to 95th" + (self.player.selfrank_r==20)*"lowest 5 earners", 'meaninc': (self.player.meaninc_r==1)*"within 0 - 5,000 ECU" + (self.player.meaninc_r==2)*"within 5,001 - 10,000 ECU" + (self.player.meaninc_r==3)*"within 10,001 - 15,000 ECU" + (self.player.meaninc_r==4)*"within 15,001 - 20,000 ECU" + (self.player.meaninc_r==5)*"within 20,001 - 25,000 ECU" + (self.player.meaninc_r==6)*"within 25,001 - 30,000 ECU" + (self.player.meaninc_r==7)*"within 30,001 - 35,000 ECU" + (self.player.meaninc_r==8)*"within 35,001 - 40,000 ECU" + (self.player.meaninc_r==9)*"within 40,001 - 45,000 ECU" + (self.player.meaninc_r==10)*"within 45,001 - 50,000 ECU" + (self.player.meaninc_r==11)*"within 50,001 - 55,000 ECU" + (self.player.meaninc_r==12)*"within 55,001 - 60,000 ECU" + (self.player.meaninc_r==13)*"within 60,001 - 65,000 ECU" +(self.player.meaninc_r==14)*"within 65,001 - 70,000 ECU" + (self.player.meaninc_r==15)*"within 70,001 - 75,000 ECU" + (self.player.meaninc_r==16)*"within 75,001 - 80,000 ECU" + (self.player.meaninc_r==17)*"within 80,001 - 85,000 ECU" + (self.player.meaninc_r==18)*"within 85,001 - 90,000 ECU" + (self.player.meaninc_r==19)*"within 90,001 - 95,000 ECU" + (self.player.meaninc_r==20)*"within 95,001 - 100,000 ECU" + (self.player.meaninc_r==21)*"within 100,001 - 105,000 ECU" + (self.player.meaninc_r==22)*"within 105,001 - 110,000 ECU" + (self.player.meaninc_r==23)*"within 110,001 - 115,000 ECU" + (self.player.meaninc_r==24)*"within 115,001 - 120,000 ECU", 'abovemean': self.player.abovemean_r, 'threshold': self.player.threshold, 'orange': (self.player.threshold <= self.player.draw), 'box': (self.player.payquest == 3) * (self.player.threshold > self.player.abovemean_r), 'jackpot': (self.player.bonus > 0) } class Feedback(Page): form_model = 'player' form_fields = ['feedback'] def vars_for_template(self): return{ 'code': self.participant.code } page_sequence = [ Agreement, Introduction, Introduction_quest, Introduction_ans, Earning_Pre, Earning_Trial, Earning_Trial1, Earning_Trial2, Earning_Trial3, Earning_Trial_Result, Earning_Real, Earning_Real1, Earning_Real2, Earning_Real3, Earning_Real4, Earning_Real5, Earning_Real6, Earning_Real7, Earning_Real8, Earning_Real9, Earning_Real13, Earning_Real14, Earning_Real15, Earning_Result, Sumstats, TaxScheme, AttentionCheck, Qbonus_pre, Qbonus, #TaxScheme2, Sumstats2, Qbonus_r, TaxScheme3, Demographics, Results, Feedback ]