from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, safe_json ) import itertools import random import numpy as np author = 'Thomas Graeber' doc = """""" class Constants(BaseConstants): name_in_url = 'beliefs_default' players_per_group = None ns = [1, 3, 5] priors = [0.01, 0.05, 0.10, 0.30, 0.50, 0.70, 0.90, 0.95, 0.99] diagnosticities = [0.65, 0.75, 0.90] bags = [2, 10] cards = 100 bagnames = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'] combinations_each = list(itertools.product(ns, priors, diagnosticities)) num_combinations_each = len(combinations_each) combinations = list(itertools.product(bags, ns, priors, diagnosticities)) num_combinations = len(combinations) print(combinations_each) print(combinations) print(num_combinations_each, num_combinations) num_rounds_each = 6 num_rounds = 2 * num_rounds_each class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: for p in self.get_players(): p.participant.vars['treat'] = -1 p.participant.vars['failed_comprehension'] = False p.participant.vars['bags_first'] = random.choice(Constants.bags) p.participant.vars['beliefs_sequence_two'] = random.sample(range(0, Constants.num_combinations_each), Constants.num_rounds_each) p.participant.vars['beliefs_sequence_ten'] = random.sample(range(Constants.num_combinations_each, 2 * Constants.num_combinations_each), Constants.num_rounds_each) if p.participant.vars['bags_first'] == 2: p.participant.vars['beliefs_sequence'] = p.participant.vars['beliefs_sequence_two'] + p.participant.vars['beliefs_sequence_ten'] else: p.participant.vars['beliefs_sequence'] = p.participant.vars['beliefs_sequence_ten'] + p.participant.vars['beliefs_sequence_two'] print("p.participant.vars['beliefs_sequence']:", p.participant.vars['beliefs_sequence']) p.participant.vars['paying_round'] = random.randint(1, Constants.num_rounds) for p in self.get_players(): p.bags = -1 p.bags_first = p.participant.vars['bags_first'] p.beliefs_sequence = str(p.participant.vars['beliefs_sequence']) p.paying_round = p.participant.vars['paying_round'] p.on_paying_round = (p.round_number == p.participant.vars['paying_round']) p.create_task() class Group(BaseGroup): pass class Player(BasePlayer): bags_first = models.IntegerField() bags = models.IntegerField() beliefs_sequence = models.StringField() paying_round = models.IntegerField() on_paying_round = models.BooleanField() task_identifier = models.StringField() task_number = models.IntegerField() on_paying_round = models.BooleanField(initial=False) prior = models.FloatField() sample_size = models.IntegerField() diagnosticity = models.FloatField() bayesian_posterior = models.FloatField() redish_urn_drawn = models.BooleanField() p_red = models.FloatField() number_reds = models.IntegerField() number_blues = models.IntegerField() draw = models.StringField() treatment_condition = models.StringField() default_condition = models.StringField() #p_win_prize = models.FloatField() #won_prize = models.FloatField() random_payoff = models.CurrencyField() expected_payoff = models.CurrencyField() squared_deviation = models.FloatField() failed_comprehension = models.BooleanField(initial=False) failed_attention = models.BooleanField(initial=False) attention_check = models.StringField() prolific_id = models.StringField() clicked_payoff_info = models.BooleanField(initial=False, blank=True) qn_draws_got_wrong = models.BooleanField(initial=False) qn_alloc_got_wrong = models.BooleanField(initial=False) qn_balls_got_wrong = models.BooleanField(initial=False) qn_confidence1 = models.IntegerField() qn_balls = models.IntegerField( choices=[ [0, "25%"], [2, "50%"], [1, "80%"], ], widget=widgets.RadioSelect, label="") qn_draws = models.IntegerField( choices=[ [0, 'The number of "Bag A" cards is the same in all tasks.'], [1, 'The exact number of cards corresponding to each bag may vary across tasks.'], ], widget=widgets.RadioSelect, blank=False, label='Which statement about the number of cards corresponding to each bag is correct?' ) qn_alloc = models.IntegerField( choices=[ [1, 'The exact fractions of red and blue balls in each bag may vary across tasks.'], [0, 'The fraction of red balls in each bag is the same in all tasks, and bag A always contains the most red balls.'], ], widget=widgets.RadioSelect, blank=False, label="Which statement about the allocation of red and blue balls in the bags is correct?" ) qn_select = models.IntegerField( choices=[ [1, 'The computer draws 1 card from a deck of 100 cards at random. Each card has the label of one of the bags written on it, ' 'e.g. "Bag A". The bag corresponding to the label on drawn card gets selected.'], [0, 'The computer selects a bag at random, but this does not depend on the cards.'] ], widget=widgets.RadioSelect, blank=False, label="Which statement about how the bag is selected is correct?" ) wtp = models.FloatField() confidence = models.FloatField() confidence_upper_bound = models.FloatField() confidence_lower_bound = models.FloatField() answer = models.FloatField( min=0, max=100, blank=False, ) def create_task(self): self.bags, self.sample_size, self.prior, self.diagnosticity = Constants.combinations[self.participant.vars['beliefs_sequence'][self.round_number - 1]] self.redish_urn_drawn = (random.random() < self.prior) if self.redish_urn_drawn: self.p_red = self.diagnosticity else: self.p_red = 1 - self.diagnosticity self.number_reds = np.random.binomial(self.sample_size, self.p_red) self.number_blues = self.sample_size - self.number_reds self.draw = 'R'*self.number_reds + 'B'*self.number_blues self.task_identifier = 'ball_urns_b{}_p{}_d{}_n{}_nr{}'.format(self.bags,self.prior,self.diagnosticity,self.sample_size,self.number_reds) print('self.task_identifier:', self.task_identifier) def current_cards(self): cc = [None] * self.bags for bag in range(self.bags): if bag == 0: bagcards = int(self.prior * Constants.cards) elif bag == self.bags - 1: bagcards = Constants.cards - int(self.prior * Constants.cards) - (self.bags - 2)*int((Constants.cards - cc[0]['bagcards']) / (self.bags - 1)) else: bagcards = int((Constants.cards - cc[0]['bagcards']) / (self.bags-1)) cc[bag] = {'bagname': Constants.bagnames[bag], 'bagcards': bagcards} print(cc) return cc def current_bags(self): cb = [None] * self.bags for bag in range(self.bags): if bag == 0: number_reds = round(self.diagnosticity * Constants.cards) number_blues = Constants.cards - number_reds else: number_reds = cb[0]['number_blues'] number_blues = cb[0]['number_reds'] cb[bag] = {'bagname': Constants.bagnames[bag], 'number_reds': number_reds, 'number_blues': number_blues} print(cb) return cb def set_payoffs(self): if self.redish_urn_drawn: p_win_prize = 1 - 0.0001 * (self.answer - 1) ** 2 else: p_win_prize = 1 - 0.0001 * (self.answer) ** 2 won_prize = random.random() < p_win_prize if self.on_paying_round: possible_payoff = self.session.config['prize'] * won_prize if 'possible_payoffs' in self.participant.vars: self.participant.vars['possible_payoffs'].append(round(possible_payoff, 2)) else: self.participant.vars['possible_payoffs'] = [round(possible_payoff, 2)]