from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, safe_json ) #import pandas as pd #import numpy as np #import statsmodels.formula.api as sm author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): instructions_template = 'gift_exchange_strategy/Instructions.html' name_in_url = 'gift_exchange_strategy' players_per_group = 2 num_rounds = 3 min_wage = 0 max_wage = 9 # Effort * 1.5 EFFORT_TO_RETURN = { 0: 0, 1: 1.5, 2: 3, 3: 4.5, 4: 6, 5: 7.5, 6: 9, 7: 10.5, 8: 12, 9: 13.5} # Effort² * 0.13 EFFORT_TO_COST = { 0: 0, 1: 0.13, 2: 0.52, 3: 1.17, 4: 2.08, 5: 3.25, 6: 4.68, 7: 6.37, 8: 8.32, 9: 10.53} def cost_from_effort(effort): return c(Constants.EFFORT_TO_COST[effort]) def return_from_effort(effort): return c(Constants.EFFORT_TO_RETURN[effort]) class Subsession(BaseSubsession): #pass def vars_for_admin_report(self): #Effort = list([p.effort_agent for p in self.get_groups()]) #Wages = list([p.principal_wage_offer for p in self.get_groups()]) #df = pd.DataFrame({'Effort': Effort, 'Wages': Wages}) #results = sm.ols(formula="Effort ~ Wages", data=df).fit() #return {'Effort':Effort} #df = pd.DataFrame({'A': [10, 20, 30, 40, 50], # 'B': [20, 30, 10, 40, 50], # 'C': [32, 234, 23, 23, 42523]}) #result = sm.ols(formula="A ~ B + C", data=df).fit() #return {'result':result} df_init = [] data = [] for group in self.get_groups(): for p in group.in_all_rounds(): for i in range(0,9+1,1): data.append([i,getattr(p,'agent_effort_{}'.format(int(i)))]) #df_init[str(i)]= getattr(p,'agent_effort_{}'.format(int(i))) #df_init.append({str(i): getattr(p,'agent_effort_{}'.format(int(i)))}) series = [{'name':'Effort', 'data': data}] highcharts_series_new = safe_json(series) #df_init2 = dict(df_init) #df = pd.DataFrame(df_init) return { 'highcharts_series_new': highcharts_series_new } def question(amount): return 'How much effort would you return for a wage offer of {}?'.format(c(amount)) class Group(BaseGroup): total_return = models.CurrencyField( doc="""Total return from agent's effort = [Return for single unit of agent's work effort] * [Agent's work effort]""" ) principal_wage_offer = models.PositiveIntegerField( doc="""Amount offered as fixed pay to agent""", min=Constants.min_wage, max=Constants.max_wage, verbose_name='Fixed Payment (from {} to {})'.format( Constants.min_wage, Constants.max_wage) ) effort_agent = models.PositiveIntegerField( doc="""Effort returned for offered wage""") # for strategy method agent_effort_0 = models.PositiveIntegerField( choices=range(0,9+1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(0)) agent_effort_1 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(1)) agent_effort_2 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(2)) agent_effort_3 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(3)) agent_effort_4 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(4)) agent_effort_5 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(5)) agent_effort_6 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(6)) agent_effort_7 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(7)) agent_effort_8 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(8)) agent_effort_9 = models.PositiveIntegerField( choices=range(0, 9 + 1), doc="""Agent's work effort, [0, 9]""", widget=widgets.RadioSelectHorizontal(), verbose_name=question(9)) cost_agent = models.CurrencyField( doc="""Agent's cost of work effort""" ) money_agent = models.CurrencyField( doc="""Agent's wage""" ) money_principal = models.CurrencyField( doc="""Agent's effort level to principal""" ) def set_payoffs(self): principal = self.get_player_by_role('principal') agent = self.get_player_by_role('agent') self.effort_agent = getattr(self,'agent_effort_{}'.format(self.principal_wage_offer)) self.money_agent = c(self.principal_wage_offer) self.total_return = c(return_from_effort(self.effort_agent)) self.cost_agent = c(0.13*(getattr(self,'agent_effort_{}'.format(int(self.principal_wage_offer))))**2) self.money_principal = c(return_from_effort(getattr(self,'agent_effort_{}'.format(self.principal_wage_offer)))) agent.payoff = c(self.money_agent - self.cost_agent) principal.payoff = c(self.money_principal - self.principal_wage_offer) class Player(BasePlayer): def role(self): if self.id_in_group == 1: return 'principal' if self.id_in_group == 2: return 'agent'