from otree.api import Currency as c, currency_range from django.utils.timezone import now from ._builtin import Page, WaitPage from .models import Constants def get_participant_data(part_id): return Constants.data[part_id % Constants.num_data] #class StartPage_practice(Page): # def is_displayed(self): # return self.round_number == 1 # form_model = 'player' # form_fields = ['player_ID'] class StartPage(Page): def is_displayed(self): return self.round_number == 1 form_model = 'player' form_fields = ['age', 'sex', 'laterality', 'education','computer_number'] def before_next_page(self): self.participant.label = 'PC %s (%s%s) ID:%s' % (self.player.computer_number, self.player.age, self.player.sex, self.participant.id) class Results_practice(Page): #def vars_for_template(self): # self.player.final_payoff() # #pay_for_practice = self.participant.payoff() # pay_for_practice = self.participant.vars['payoff1'] # final_pay = pay_for_practice * 200 # # winning_player = player_in_all_rounds[winning_round] # # final_payment = self.winning_player.final # return { # 'practice_pay': pay_for_practice, # 'final_pay': final_pay # } def is_displayed(self): return self.round_number == Constants.practice_rounds def before_next_page(self): self.participant.payoff = 0. class EndBlockPage(Page): def is_displayed(self): part_data = get_participant_data(self.participant.id) return part_data['block_end'][self.round_number - 1] def vars_for_template(self): part_data = get_participant_data(self.participant.id) num = part_data['inblock_num'][self.round_number-1] block_players = self.player.in_rounds( self.round_number - num + 1, self.round_number ) outcomes_resps_and_payoffs = [(p.outcome, p.response*100, p.payoff) for p in block_players] block_payoff = sum(p.payoff for p in block_players) blocknum = part_data['num_of_block'][self.round_number-1] blocksleft = part_data['num_of_block'][-1] - blocknum is_practice = self.round_number <= Constants.practice_rounds if is_practice: blocksleft = int(Constants.practice_rounds / 5) - blocknum else: blocknum -= int(Constants.practice_rounds / 5) return {'pct': self.player.prob*100, 'outcomes_resps_and_payoffs':outcomes_resps_and_payoffs, 'block_payoff':block_payoff, 'blocknum':blocknum, 'blocksleft':blocksleft, 'is_practice':is_practice} class SliderPage(Page): form_model = 'player' form_fields = ['response', ] def vars_for_template(self): part_data = get_participant_data(self.participant.id) is_block_start = part_data['block_start'][self.round_number - 1] if is_block_start: slider_start = .5 else: slider_start = self.player.in_round(self.round_number - 1).response slider_start_pct = 100*slider_start slider_start_px = round(1000*slider_start) self.player.started = now() return {'slider_start' : slider_start, 'slider_start_pct':slider_start_pct, 'slider_start_px' : slider_start_px, 'is_block_start':is_block_start} def before_next_page(self): self.player.finished = now() # The avg squared error is (empirically) about 0.04 for a serious-enough player. # The avg squared error is 1/12 = 0.08333 for a player who only responds 0.5. # Someone "half-way" would have an avg sq error of 0.06. # We want the serious one to have $25, the half-way one to have $10. # With a basis of 200 blocks of 5 samples, i.e., 1000 samples, # that's $0.025 per sample for the first one and $0.01 for the second one. # Hence rwd = 0.01 + 0.015*(0.06-sqError)/(0.06-0.04) # i.e. rwd = 0.055 - 0.75*sqError # UPDATE subjects seem to be not that good... (two subjects: one had $18 and the other $8) # If serious one (0.04) has $35, and 1/12 one has $10, over 1000 samples, # that's $0.035 per sample for the first one and $0.01 for the second one, # hence rwd = 0.01 + 0.025*( 1/12 - sqError )/( 1/12 - 0.04 ) # i.e.: rwd = 0.058 - 0.58*sqError # we round at 0.06 - 0.6*sqError # NEW UPDATE - based on the first 5 subjects + considering there are 8 training blocks, # the following parameters give an average reward of $25 (and a minimum, for the bad performer we had, of $12.5) # intercept = 0.072, slope = 0.92 # NEW NEW UPDATE - first 9 subjects. 8 training blocks. Avg $25 and minimum of $10 # intercept = 0.065, slope = 0.85 sqError = (self.player.response - self.player.prob)**2 self.player.payoff = 100*(0.065 - 0.85*sqError) class Results_real(Page): def is_displayed(self): return self.round_number == Constants.num_rounds page_sequence = [ StartPage, #NewBlockPage, SliderPage, EndBlockPage, Results_practice, Results_real ]