from otree.api import Currency as c, currency_range from ._builtin import Page, WaitPage from .models import Constants import numpy as np class BasePage(Page): def vars_for_template(self): all_players = self.player.in_all_rounds() all_players.reverse() v = { # 'treatment': self.session.config['treatment'], 'num_rounds': Constants.interaction_length[self.player.interaction_number-1], 'all_players': all_players, } v.update(self.extra_vars_for_template()) return v def extra_vars_for_template(self): return {} class BaseWaitPage(WaitPage): def vars_for_template(self): all_players = self.player.in_all_rounds() all_players.reverse() v = { # 'treatment': self.session.config['treatment'], 'num_rounds': Constants.interaction_length[self.player.interaction_number-1], 'all_players': all_players, } v.update(self.extra_vars_for_template()) return v def extra_vars_for_template(self): return {} class Introduction(BasePage): # timeout_seconds = 30 def is_displayed(self): if self.player.interaction_number == 1: print('This is the start of new match') return self.player.round_in_interaction == 1 # return self.player.round_in_interaction == 1 and (not self.session.config['debug']) class Decision(BasePage): timeout_seconds = 20 form_model = 'player' form_fields = ['choice'] def before_next_page(self): p = self.player if p.round_in_interaction==1: p.participant.vars['num0'] = 0 p.participant.vars['num1'] = 0 p.participant.vars['num2'] = 0 p.participant.vars['num3'] = 0 p.participant.vars['num4'] = 0 p.participant.vars['payoff0'] = 0 p.participant.vars['payoff1'] = 0 p.participant.vars['payoff2'] = 0 p.participant.vars['payoff3'] = 0 p.participant.vars['payoff4'] = 0 if not self.timeout_happened: p.timed_out = 0 choice = p.choice p.participant.vars['num%d'%p.choice] += 1 p.payoff = p.participant.vars['returns'][p.interaction_number-1][p.choice][p.round_in_interaction-1] print('participants returns',p.participant.vars['returns']) if p.treatment==1: print('learning cost', Constants.cost*0.8**(np.log(p.participant.vars['num%d'%p.choice])/np.log(2))) p.payoff -= Constants.cost*0.8**(np.log(p.participant.vars['num%d'%p.choice])/np.log(2)) - Constants.cost/2 p.participant.vars['payoff%d'%p.choice] += p.payoff else: p.timed_out = 1 p.choice = -1 p.payoff = 0 p.cum_payoff = sum([p0.payoff for p0 in p.in_all_rounds() if p0.interaction_number == p.interaction_number]) p.num_decisions = sum([1-p0.timed_out for p0 in p.in_all_rounds() if p0.interaction_number == p.interaction_number]) if p.num_decisions == 0: p.avg_payoff = 0 else: p.avg_payoff = np.around(float(p.cum_payoff) / p.num_decisions, decimals=1) def extra_vars_for_template(self): p = self.player avg_payoffs = [0,0,0,0,0] nums = [0,0,0,0,0] if p.round_in_interaction != 1: nums = [p.participant.vars['num0'], p.participant.vars['num1'], p.participant.vars['num2'], p.participant.vars['num3'], p.participant.vars['num4'],] for choice in range(5): if p.participant.vars['num%d'%choice] !=0: avg_payoffs[choice] = p.participant.vars['payoff%d'%choice]/nums[choice] else: avg_payoffs[choice] = '' return { 'avg_payoffs': avg_payoffs, 'nums': nums, } class DecisionWaitPage(BaseWaitPage): template_name = Constants.name_in_url+'/DecisionWaitPage.html' def is_displayed(self): return (self.player.interaction_number == 3) # return (self.player.interaction_number == 3 and # self.player.round_in_interaction > Constants.info_round) def after_all_players_arrive(self): # it only gets executed once payoffs = [p.payoff for p in self.group.get_players() if p.timed_out == 0] for p in self.group.get_players(): if len(payoffs) > 0: p.max_pay = np.around(float(max(payoffs)), decimals=0) p.average_pay = np.around(float(sum(payoffs))/len(payoffs), decimals=1) else: p.max_pay = 0 p.average_pay = 0 def extra_vars_for_template(self): p = self.player avg_payoffs = [0,0,0,0,0] nums = [0,0,0,0,0] if p.round_in_interaction != 1: nums = [p.participant.vars['num0'], p.participant.vars['num1'], p.participant.vars['num2'], p.participant.vars['num3'], p.participant.vars['num4'],] for choice in range(5): if p.participant.vars['num%d'%choice] !=0: avg_payoffs[choice] = p.participant.vars['payoff%d'%choice]/nums[choice] else: avg_payoffs[choice] = '' return { 'avg_payoffs': avg_payoffs, 'nums': nums, } class Results(BasePage): def extra_vars_for_template(self): p = self.player avg_payoffs = [0,0,0,0,0] nums = [0,0,0,0,0] nums = [p.participant.vars['num0'], p.participant.vars['num1'], p.participant.vars['num2'], p.participant.vars['num3'], p.participant.vars['num4'],] for choice in range(5): if p.participant.vars['num%d'%choice] !=0: avg_payoffs[choice] = p.participant.vars['payoff%d'%choice]/nums[choice] else: avg_payoffs[choice] = '' # it only gets executed once payoffs = np.array([p.payoff for p in self.group.get_players() if p.timed_out == 0]) choices = np.array([p.choice for p in self.group.get_players() if p.timed_out == 0]) if len(payoffs) > 0: max_pay = np.around(float(max(payoffs)), decimals=0) average_pay = np.around(float(sum(payoffs))/len(payoffs), decimals=1) max_choice = ['A','B','C','D','E'][choices[np.argmax(payoffs)]] else: max_pay = 0 average_pay = 0 max_choice = None return { 'avg_payoffs': avg_payoffs, 'nums': nums, 'max_pay': max_pay, 'average_pay': average_pay, 'max_choice': max_choice, 'choices': {'A': np.sum(choices==0), 'B': np.sum(choices==1) , 'C': np.sum(choices==2) , 'D': np.sum(choices==3) , 'E': np.sum(choices==4) } } def get_timeout_seconds(self): if self.player.timed_out: return 2 else: return 8 class NewInfo(BasePage): timeout_seconds = 36 def is_displayed(self): return (self.player.interaction_number == 3 and self.player.round_in_interaction == Constants.info_round) class NewInfoWaitPage(BaseWaitPage): template_name = Constants.name_in_url+'/NewInfoWaitPage.html' wait_for_all_groups = True def is_displayed(self): return (self.player.interaction_number == 3 and self.player.round_in_interaction == Constants.info_round) class InteractionResultsPage(BasePage): timeout_seconds = 20 def is_displayed(self): return self.player.round_in_interaction == Constants.interaction_length[self.player.interaction_number-1] class InteractionWaitPage(BaseWaitPage): template_name = Constants.name_in_url+'/InteractionWaitPage.html' wait_for_all_groups = True def is_displayed(self): return self.player.round_in_interaction == Constants.interaction_length[self.player.interaction_number-1] page_sequence = [ Introduction, Decision, # DecisionWaitPage, # Results, # NewInfo, # NewInfoWaitPage, InteractionResultsPage, # InteractionWaitPage, ]