from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random #from numpy.random import choice import itertools from django import forms doc = """ This is an adaptation of a simultaneous 100-player game """ class Constants(BaseConstants): name_in_url = 'experiment' players_per_group = 3 num_rounds = 1 instructions_template = 'experiment/Instructions.html' payment_template = 'experiment/Payment.html' payment_template2 = 'experiment/Payment2.html' # Necessary amounts: q_time = 5 q_timeout = 5.5 q_points = 10000 equivalency = 50000 b_points = 20000 class Player(BasePlayer): # Predefined variables: treatment = models.PositiveIntegerField() matchgroup = models.BooleanField() payquest = models.PositiveIntegerField() threshold = models.PositiveIntegerField() draw = models.PositiveIntegerField() # Understanding instructions questions: acceptance = models.BooleanField(widget=widgets.CheckboxInput()) check1 = models.BooleanField() check2 = models.BooleanField() check3 = models.BooleanField() check4 = models.BooleanField() check5 = models.BooleanField() # Earning Task Fields task0m = models.PositiveIntegerField(widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # 43 × 2 = 86 task0c = models.StringField(max_length=5, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # CHINA (CIHAN) task0a = models.StringField(max_length=3, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # DOG (GOD) task1m = models.PositiveIntegerField(widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # 72 + 39 = 111 task1c = models.StringField(max_length=5, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # INDIA (DANII) task1a = models.StringField(max_length=8, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # ELEPHANT (HETPLANE) task2m = models.PositiveIntegerField(widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # (74 + 23) × 2 = 194 task2c = models.StringField(max_length=5, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # ITALY (LATYI) task2a = models.StringField(max_length=5, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # EAGLE (LEAGE) task3m = models.PositiveIntegerField(widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # 172 / 4 = 43 task3c = models.StringField(max_length=5, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # JAPAN (PNAAJ) task3a = models.StringField(max_length=9, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # *CROCODILE (CLIORODCE) task5m = models.PositiveIntegerField(widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # 56 × 7 = 392 task5c = models.StringField(max_length=8, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # TANZANIA (TINAANAZ) task5a = models.StringField(max_length=7, widget=forms.TextInput(attrs={'autofocus': 'autofocus'})) # OCTOPUS (USCOPTO) # Distribution Choice Fields selfrank = models.PositiveIntegerField(choices=[(1,"Highest 5 earners"), (2,"Between 6th to 10th"), (3,"Between 11th to 15th"), (4,"Between 16th to 20th"), (5,"Between 21st to 25th"), (6,"Between 26th to 30th"), (7,"Between 31st to 35th"), (8,"Between 36th to 40th"), (9,"Between 41st to 45th"), (10,"Between 46th to 50th"), (11,"Between 51st to 55th"), (12,"Between 56th to 60th"), (13,"Between 61st to 65th"), (14,"Between 66th to 70th"), (15,"Between 71st to 75th"), (16,"Between 76th to 80th"), (17,"Between 81st to 85th"), (18,"Between 86th to 90th"), (19,"Between 91st to 95th"), (20,"Lowest 5 earners")]) meaninc = models.PositiveIntegerField(choices=[(1,"0 - 5,000 ECU"), (2,"5,001 - 10,000 ECU"), (3,"10,001 - 15,000 ECU"), (4,"15,001 - 20,000 ECU"), (5, "20,001 - 25,000 ECU"), (6,"25,001 - 30,000 ECU"), (7,"30,001 - 35,000 ECU"), (8,"35,001 - 40,000 ECU"), (9,"40,001 - 45,000 ECU"), (10,"45,001 - 50,000 ECU"), (11,"50,001 - 55,000 ECU"), (12,"55,001 - 60,000 ECU"), (13,"60,001 - 65,000 ECU"),(14,"65,001 - 70,000 ECU"), (15,"70,001 - 75,000 ECU"), (16,"75,001 - 80,000 ECU"), (17,"80,001 - 85,000 ECU"), (18,"85,001 - 90,000 ECU"), (19,"90,001 - 95,000 ECU"), (20, "95,001 - 100,000 ECU"), (21,"100,001 - 105,000 ECU"), (22,"105,001 - 110,000 ECU"), (23,"110,001 - 115,000 ECU"), (24,"115,001 - 120,000 ECU")]) abovemean = models.PositiveIntegerField(min=1, max=100) # Perceived probability of being above the mean selfrank_r = models.PositiveIntegerField(choices=[(1,"Highest 5 earners"), (2,"Between 6th to 10th"), (3,"11th to 15th"), (4,"16th to 20th"), (5,"21st to 25th"), (6,"26th to 30th"), (7,"31st to 35th"), (8,"36th to 40th"), (9,"41st to 45th"), (10,"46th to 50th"), (11,"51st to 55th"), (12,"56th to 60th"), (13,"61st to 65th"), (14,"66th to 70th"), (15,"71st to 75th"), (16,"76th to 80th"), (17,"81st to 85th"), (18,"86th to 90th"), (19,"91st to 95th"), (20,"Lowest 5 earners")]) meaninc_r = models.PositiveIntegerField(choices=[(1,"0 - 5,000 ECU"), (2,"5,001 - 10,000 ECU"), (3,"10,001 - 15,000 ECU"), (4,"15,001 - 20,000 ECU"), (5, "20,001 - 25,000 ECU"), (6,"25,001 - 30,000 ECU"), (7,"30,001 - 35,000 ECU"), (8,"35,001 - 40,000 ECU"), (9,"40,001 - 45,000 ECU"), (10,"45,001 - 50,000 ECU"), (11,"50,001 - 55,000 ECU"), (12,"55,001 - 60,000 ECU"), (13,"60,001 - 65,000 ECU"),(14,"65,001 - 70,000 ECU"), (15,"70,001 - 75,000 ECU"), (16,"75,001 - 80,000 ECU"), (17,"80,001 - 85,000 ECU"), (18,"85,001 - 90,000 ECU"), (19,"90,001 - 95,000 ECU"), (20, "95,001 - 100,000 ECU"), (21,"100,001 - 105,000 ECU"), (22,"105,001 - 110,000 ECU"), (23,"110,001 - 115,000 ECU"), (24,"115,001 - 120,000 ECU")]) abovemean_r = models.PositiveIntegerField(min=1, max=100) # Tax Scheme Fields tax_q1 = models.CurrencyField(max=999999) # Your earnings (ECU) tax_q2 = models.CurrencyField(max=999999) # Your taxes (ECU) tax_q3 = models.PositiveIntegerField(max=100) # Your taxes (%) tax_q4 = models.CurrencyField(max=999999) # Taxes on 10,000 (ECU) tax_attempts = models.PositiveIntegerField(initial=0) # Attention check for placebo check6 = models.CurrencyField(max=999999) check7 = models.PositiveIntegerField() check8 = models.PositiveIntegerField() check9 = models.PositiveIntegerField() att_attempts = models.PositiveIntegerField(initial=0) # Fields for calculation correct_answers = models.PositiveIntegerField() bonuspre = models.PositiveIntegerField() bonus = models.CurrencyField() taxdue = models.CurrencyField() # Socio-Demographic variables: realincome = models.PositiveIntegerField(max=99999999, blank=True, null=True) realtaxes = models.PositiveIntegerField(max=99999999, blank=True, null=True) quintile = models.PositiveIntegerField(choices=[(1,"Top Quintile (highest 20%)"), (2, "Second Quintile"), (3, "Median Quintile"), (4, "Fourth Quintile"), (5, "Bottom Quintile (lowest 20%)")], blank=True, null=True) age = models.PositiveIntegerField(max=99) gender = models.StringField(max_length=2, choices=[("M", 'Male'), ("F",'Female'), ("O", 'Other'), ("NA", 'Prefer not to say')]) education = models.PositiveIntegerField(choices=[ (0, 'None'), (1, 'High/Secondary School'), (3, 'Vocational Training'), (4, 'Bachelor'), (5, 'Master'), (6, 'PhD')]) status = models.StringField(max_length=13, choices=[ 'Student', 'Unemployed', 'Employed', 'Self-employed', 'Retired', 'Other']) taxSA = models.BooleanField(choices=[(True, 'Yes'), (False, 'No')]) feedback = models.StringField(max_length=100, blank=True) class Subsession(BaseSubsession): def creating_session(self): treatments = itertools.cycle([1, 2, 4,]) # Groups 1 and 2 see tax systems, 3 sees comparison group, 4 orders numbers for p in self.get_players(): p.treatment = next(treatments) p.matchgroup = bool(random.getrandbits(1)) # there are 2 potential distributions of players p.payquest = random.randint(1,3) # Randomization of paying question p.threshold = random.randint(1,100) # Proportion of orange balls p.draw = random.randint(1,100) # Ball number drawn (orange if <=threshold) class Group(BaseGroup): pass