from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random import itertools doc = """ This is a taxation experiment """ class Constants(BaseConstants): name_in_url = 'Anto' num_rounds = 1 players_per_group = 10 instructions_template = 'Anto/Instructions.html' instructions2_template = 'Anto/Instructions2.html' instructions2bis_template = 'Anto/Instructions2bis.html' instructions3_template = 'Anto/Instructions3.html' instructions4_template = 'Anto/Instructions4.html' survey_corruption_survey1 = 'Bad' survey_corruption_survey2 = 'Good' survey_corruption_survey3 = 'Indifferent' multiplier = 1.5 # Right answers to count zeroes grid1 = c(13) grid2 = c(11) grid3 = c(13) grid4 = c(12) grid5 = c(15) grid6 = c(11) grid7 = c(12) grid8 = c(11) grid9 = c(13) grid10 = c(14) grid11 = c(13) grid12 = c(18) class Subsession(BaseSubsession): def creating_session(self): corruptions = itertools.cycle([0, 0.40]) for p in self.get_players(): p.corruption = next(corruptions) class Group(BaseGroup): pass class Player(BasePlayer): agreement = models.IntegerField(label="", choices=[ [1, 'I voluntarily consent to participate in this study']], widget=widgets.RadioSelect ) corruption = models.FloatField() corruption_statement = models.StringField() income = models.IntegerField() tax_rate = models.FloatField() tax_rate_percent = models.FloatField() fine_tax_rate = models.FloatField() taxes = models.FloatField() due_taxes = models.FloatField() taxes_max = models.FloatField() taxes_min = models.FloatField() stolen_tax_max = models.FloatField() stolen_tax_min = models.FloatField() evasion_abs = models.FloatField() evasion_inc = models.FloatField() evasion = models.FloatField() detection_prob = models.FloatField() integer_prob = models.IntegerField() detection_prob_percent = models.FloatField() detection = models.StringField() fine = models.FloatField() total = models.IntegerField() citizen_payoff = models.FloatField() fake_prob = models.FloatField() election_prob = models.FloatField() is_politician = models.FloatField() stolen_taxes = models.FloatField() politician_payoff = models.FloatField() corruption_politician = models.StringField() redistribution_share = models.FloatField() CQ1_max = models.FloatField() CQ1_min = models.FloatField() CQ2_max = models.FloatField() CQ2_min = models.FloatField() def treatments(self): self.tax_rate = random.choice([0.15, 0.30]) self.tax_rate_percent = self.tax_rate*100 if self.corruption == 0: self.corruption_statement = "there is NO corruption. All tax revenues are multiplied by 1.5 and then redistributed equally" else: self.corruption_statement = "there is corruption. The selected politician can steal up to 40% of tax revenues before multiplying by 1.5 and redistributing equally" if self.corruption == 0: self.corruption_politician = "In your group there is NO corruption. You cannot steal any taxes. All tax revenues are multiplied by 1.5 and then redistributed equally" else: self.corruption_politician = "In your group there is corruption. You can decide to steal up to 40% of tax revenues before tax revenues are multiplied by 1.5 and then redistributed equally" self.due_taxes = self.income * self.tax_rate def elections(self): self.election_prob = random.uniform(0, 1) if self.election_prob < 0.2: self.is_politician = 1 else: self.is_politician = 0 def fake_probability(self): self.fake_prob = random.uniform(0, 1) def income_group(self): if self.total < 2: self.income = 50 else: self.income = 100 def taxes_max(self): return self.income*self.tax_rate def taxes_min(self): return 0 def stolen_taxes_max(self): return 40 def stolen_taxes_min(self): return 0 def evasions(self): self.evasion_abs = (self.income*self.tax_rate) - self.taxes self.evasion_inc = self.income - (self.taxes/self.tax_rate) self.evasion = self.evasion_inc/self.income def probability(self): if self.evasion_abs == 0: self.detection_prob = 0 else: self.detection_prob = min(self.evasion_abs*0.5/self.due_taxes, 0.40) self.detection_prob_percent = self.detection_prob*100 self.integer_prob = round(self.detection_prob_percent) def detections(self): if self.evasion_abs == 0: self.detection = "No" else: if self.fake_prob < self.detection_prob: self.detection = "Yes" else: self.detection = "No" def fines(self): self.fine_tax_rate = self.tax_rate_percent + 10 if self.detection == "Yes": self.fine = self.evasion_abs*1.2 else: self.fine = 0 def CQ1_max(self): return self.due_taxes def CQ1_min(self): return 0 def CQ2_max(self): return self.corruption + 1000 # return self.player.corruption*100 def CQ2_min(self): return 0 def set_citizen_payoffs(self): if self.corruption == 0.4: self.redistribution_share = 0.6*(self.income * self.tax_rate) * Constants.multiplier else: self.redistribution_share = self.income * self.tax_rate * Constants.multiplier if self.detection == "No": self.citizen_payoff = self.income - self.taxes + self.redistribution_share else: self.citizen_payoff = self.income - self.taxes + self.redistribution_share - self.fine def set_politician_payoff(self): if self.corruption == 0.4: self.redistribution_share = self.stolen_taxes/100*(self.income * self.tax_rate) * Constants.multiplier else: self.redistribution_share = self.income * self.tax_rate * Constants.multiplier if self.is_politician == 1: if self.corruption == 0.4: self.politician_payoff = self.income + self.stolen_taxes/100 * self.tax_rate * self.income * 10 + self.redistribution_share else: self.politician_payoff = self.income + self.redistribution_share CQ1 = models.FloatField() CQ2 = models.FloatField() CQ3 = models.IntegerField(label="", choices=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], widget=widgets.RadioSelectHorizontal) CQ4 = models.IntegerField( label="", choices=[ [1, 'Left'], [2, 'Centre'], [3, 'Right'], [4, 'Prefer not to say']], widget=widgets.RadioSelect) CQ5 = models.IntegerField( label='', choices=[ [1, 'Not at all'], [2, 'A little'], [3, 'Somewhat spread'], [4, 'A lot'], [5, "It's everywhere"]], widget=widgets.RadioSelectHorizontal) CQ6 = models.IntegerField( label='', choices=[ [1, 'Not at all'], [2, 'A little'], [3, 'Somehow trust it'], [4, 'A lot'], [5, 'Totally']], widget=widgets.RadioSelectHorizontal) SQ1 = models.IntegerField( label="Considering all your previous occupations, have you ever had to pay income taxes?", choices=[ [1, 'Yes'], [0, 'No']], widget=widgets.RadioSelect) SQ2_1 = models.BooleanField(label="Because they perceive taxation as unfair", widget=widgets.CheckboxInput, blank=True) SQ2_2 = models.BooleanField(label="Simply for the sake of ending up with more money", widget=widgets.CheckboxInput, blank=True) SQ2_3 = models.BooleanField(label="Because they are not willing to contribute to the public good", widget=widgets.CheckboxInput, blank=True) SQ2_4 = models.BooleanField(label="They think keeping the money is very important for them, while it changes nothing for the community", widget=widgets.CheckboxInput, blank=True) SQ3 = models.IntegerField(choices=[ [1, 'Bad'], [0, 'Indifferent'], [2, 'Good']], widget=widgets.RadioSelect) SQ3_bad1 = models.BooleanField(label="I payed taxes, so she/he is stealing from me", widget=widgets.CheckboxInput, blank=True) SQ3_bad2 = models.BooleanField(label="Politicians are stealing/diverting public resources, damaging everyone for their benefit", widget=widgets.CheckboxInput, blank=True) SQ3_bad3 = models.BooleanField(label="The cost of corruption, for the community, is larger than the private benefit of corrupt politicians", widget=widgets.CheckboxInput, blank=True) SQ3_bad4 = models.BooleanField(label="I envy her/him, I would like to be in her/his place", widget=widgets.CheckboxInput, blank=True) SQ3_indiff1 = models.BooleanField(label="I don't care about politics and governance", widget=widgets.CheckboxInput, blank=True) SQ3_indiff2 = models.BooleanField(label="I don't care because I didn't pay taxes", widget=widgets.CheckboxInput, blank=True) SQ3_indiff3 = models.BooleanField(label="I am not surprised, nobody cares about redistribution", widget=widgets.CheckboxInput, blank=True) SQ3_indiff4 = models.BooleanField(label="I'm used to it, I gave up caring", widget=widgets.CheckboxInput, blank=True) SQ3_good1 = models.BooleanField(label="I'm happy that the system does not work", widget=widgets.CheckboxInput, blank=True) SQ3_good2 = models.BooleanField(label="I would have done the same in their position", widget=widgets.CheckboxInput, blank=True) SQ3_good3 = models.BooleanField(label="It is just part of politicians' remuneration", widget=widgets.CheckboxInput, blank=True) SQ3_good4 = models.BooleanField(label="It makes me feel less responsible towards society", widget=widgets.CheckboxInput, blank=True) Q1_correct = models.BooleanField() Q2_correct = models.BooleanField() Q3_correct = models.BooleanField() Q4_correct = models.BooleanField() Q5_correct = models.BooleanField() Q6_correct = models.BooleanField() Q7_correct = models.BooleanField() Q8_correct = models.BooleanField() Q9_correct = models.BooleanField() Q10_correct = models.BooleanField() Q11_correct = models.BooleanField() Q12_correct = models.BooleanField() Grid1 = models.IntegerField() Grid2 = models.IntegerField() Grid3 = models.IntegerField() Grid4 = models.IntegerField() Grid5 = models.IntegerField() Grid6 = models.IntegerField() Grid7 = models.IntegerField() Grid8 = models.IntegerField() Grid9 = models.IntegerField() Grid10 = models.IntegerField() Grid11 = models.IntegerField() Grid12 = models.IntegerField() def set_grid_results(self): if self.Grid1 == Constants.grid1: self.Q1_correct = 1 * 1 if not self.Grid1 == Constants.grid1: self.Q1_correct = 0 * 0 if self.Grid2 == Constants.grid2: self.Q2_correct = 1 * 1 if not self.Grid2 == Constants.grid2: self.Q2_correct = 0 * 0 if self.Grid3 == Constants.grid3: self.Q3_correct = 1 * 1 if not self.Grid3 == Constants.grid3: self.Q3_correct = 0 * 0 if self.Grid4 == Constants.grid4: self.Q4_correct = 1 * 1 if not self.Grid4 == Constants.grid4: self.Q4_correct = 0 * 0 if self.Grid5 == Constants.grid5: self.Q5_correct = 1 * 1 if not self.Grid5 == Constants.grid5: self.Q5_correct = 0 * 0 if self.Grid6 == Constants.grid6: self.Q6_correct = 1 * 1 if not self.Grid6 == Constants.grid6: self.Q6_correct = 0 * 0 if self.Grid7 == Constants.grid7: self.Q7_correct = 1 * 1 if not self.Grid7 == Constants.grid7: self.Q7_correct = 0 * 0 if self.Grid8 == Constants.grid8: self.Q8_correct = 1 * 1 if not self.Grid8 == Constants.grid8: self.Q8_correct = 0 * 0 if self.Grid9 == Constants.grid9: self.Q9_correct = 1 * 1 if not self.Grid9 == Constants.grid9: self.Q9_correct = 0 * 0 if self.Grid10 == Constants.grid10: self.Q10_correct = 1 * 1 if not self.Grid10 == Constants.grid10: self.Q10_correct = 0 * 0 if self.Grid11 == Constants.grid11: self.Q11_correct = 1 * 1 if not self.Grid11 == Constants.grid11: self.Q11_correct = 0 * 0 if self.Grid12 == Constants.grid12: self.Q12_correct = 1 * 1 if not self.Grid12 == Constants.grid12: self.Q12_correct = 0 * 0 def set_grid_results_total(self): if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 12: self.total = 12 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 11: self.total = 11 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 10: self.total = 10 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 9: self.total = 9 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 8: self.total = 8 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 7: self.total = 7 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 6: self.total = 6 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 5: self.total = 5 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 4: self.total = 4 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 3: self.total = 3 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 2: self.total = 2 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 1: self.total = 1 if self.Q1_correct + self.Q2_correct + self.Q3_correct + self.Q4_correct + self.Q5_correct + self.Q6_correct + self.Q7_correct + self.Q8_correct + self.Q9_correct + self.Q10_correct + self.Q11_correct + self.Q12_correct == 0: self.total = 0