from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'Allocation' players_per_group = None num_rounds = 15 K = 100 unit_profit_retailer1 = 10 unit_profit_retailer2 = 10 un1 = 0 up1 = 100 un2 = 80 up2 = 180 participation_payoff = 0.5 historical_demand_retailer1 = [32, 95, 56, 67, 11, 68, 61, 20, 95, 72, 37, 41, 25, 67, 31, 63, 20, 80, 5, 46, 66, 58, 30, 52, 82, 33, 96, 80, 13, 44] historical_demand_retailer2 = [127, 174, 141, 147, 125, 140, 166, 96, 83, 160, 163, 99, 152, 145, 130, 120, 106, 173, 120, 98, 84, 145, 136, 163, 111, 180, 130, 145, 146, 98] realized_demand_retailer1 = [50, 85, 5, 22, 88, 92, 3, 47, 16, 95, 47, 89, 66, 93, 16] realized_demand_retailer2 = [139, 99, 103, 86, 165, 168, 114, 147, 120, 83, 166, 177, 114, 163, 179] # 100~200: historical_demand = [189, 122, 189, 146, 153, 157, 106, 166, 107, 182, 154, 144, 199, 130, 118, 135, 199, 149, 112, 119, 179, 100, 133, 193, 187, 103, 157, 158, 142, 192] # 100~200: realized = [140, 161, 147, 176, 168, 127, 183, 126, 132, 197, 156, 101, 165, 159, 163] Instructions_template = 'Allocation/Instruction_Template.html' Instruction1_template = 'Allocation/Instruction1_Template.html' Instruction2_template = 'Allocation/Instruction2_Template.html' class Subsession(BaseSubsession): def creating_session(self): players = self.get_players() for p in players: p.new_round_number = p.round_number + 30 class Group(BaseGroup): pass class Player(BasePlayer): allocation1 = models.IntegerField() allocation2 = models.IntegerField() demand1 = models.IntegerField() demand2 = models.IntegerField() payoff1 = models.IntegerField() payoff2 = models.IntegerField() total_allocation = models.IntegerField() new_round_number = models.IntegerField() profit = models.IntegerField() q1 = models.IntegerField() def q1_error_message(self, value): if value != Constants.K: return "The total inventory you have in each period is {}.".format(Constants.K) q2 = models.IntegerField() def q2_error_message(self, value): if value != (Constants.K - 60): return "You need to allocate all of the products you have. So you can allocate {}-60 products to retail store B.".format( Constants.K) q3 = models.IntegerField( choices=[ [1, 'Customer demand at retail store A can exceed 180.'], [2, 'Customer demand at retail store A can be less than 80.'], [3, 'Customer demand at retail store A cannot be less than 80 and cannot exceed 180.'], ], widget=widgets.RadioSelect ) def q3_error_message(self, value): if value != 3: return 'The customer demand in retail store A is randomly generated between 80 and 180.' q41 = models.IntegerField() def q41_error_message(self, value): if value != 60: return "In retail store A, the realized demand (60) is lower than the allocated inventory (80). The store can sell the products as many as the demand and there will be some units left." q42 = models.IntegerField() def q42_error_message(self, value): if value != 600: return "In retail store A, the realized demand is 60, which is less than the allocated inventory of 80. Therefore, you earn revenue 10 (unit price) × 60 (minimum of demand, allocation) = 600 from Retail Store A." q43 = models.IntegerField() def q43_error_message(self, value): if value != 20: return "In retail store B, the realized demand (70) is higher than the allocated inventory (20). The store can sell the products as many as you allocated to the store." q44 = models.IntegerField() def q44_error_message(self, value): if value != 200: return "In retail store B, the allocated inventory is 20, which is less than the realized demand 70. Therefore, you earn revenue 10 (unit price) × 20 (minimum of demand, allocation) = 200 from retail store B."