from otree.api import (
models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer,
Currency as c, currency_range
)
import random
doc = """
In a lemon market of
Akerlof (1970)
, 2 buyers and 1 seller interact for 3 periods. The implementation is
based on
Holt (1999)
.
"""
class Constants(BaseConstants):
test_3 = random.randint(1, 6)
name_in_url = 'lemon_market_2'
players_per_group = 3
#original: num_rounds = 3
num_rounds=1
instructions_template = 'lemon_market/Instructions.html'
initial_endowment = c(50)
buyer_extra_value = c(5)
buy_choices = []
for i in range(1, players_per_group):
choice = [i, 'Buy from seller {}'.format(i)]
buy_choices.append(choice)
buy_choices.append([0, 'Buy nothing'])
quality_production_costs = {
# Level: ProductionCost
'High': 30,
'Medium': 20,
'Low': 10
}
quality_level_names = list(quality_production_costs.keys())
class Subsession(BaseSubsession):
def creating_session(self):
for p in self.get_players():
p.rr1=random.randint(1,2)
p.r1 = random.randint(1, 2)
if p.rr1==1:
if p.r1==1:
p.c1=1
if p.r1==2:
p.c1=2
if p.rr1==2:
if p.r1==1:
p.c1=3
if p.r1==2:
p.c1=4
# p.p1=random.randint(1,20)
#series=[]
# series.append({
# 'name': 'Test 1',
# 'data': [p.p1]
# })
#return {
# 'highcharts_series': series,
# 'round_numbers': list(range(1, Constants.num_rounds + 5))
## The list of numbers generated using the "list(range(min,max))" command will be
## min to max-1 I think, since list, by itself, starts with 0 as the beginning of the index,
## But I think if it's used in a graph, the categories at the bottom will not exceed
## the data
#}
def vars_for_admin_report(self):
group = self.get_groups()[0]
series = []
transaction_prices = [g.sale_price for g in group.in_all_rounds()]
#series.append({
# 'name': 'Transaction Price',
# 'data': transaction_prices})
for player in group.get_players():
payoffs = [p.payoff for p in player.in_all_rounds()]
# series.append(
# {'name': 'Earnings for {}'.format(player.role()),
# 'data': payoffs})
#def creating_session(self):
#r1=random.randint(1,5)
#p1=10+r1
p1=5
r2 = random.randint(2, 7)
p2 = 20 + r2
r3 = random.randint(3, 9)
p3 = 30 + r3
r4 = random.randint(4, 11)
p4 = 40 + r4
rr1 = random.randint(25, 30)
# for p in self.get_players(self):
# p.rr1=random.randint(25,30)
series.append({
'name': 'Test 1',
'data': [p1,p2,p3,p4]
})
return {
'highcharts_series': series,
'round_numbers': list(range(1, Constants.num_rounds + 3))
## The list of numbers generated using the "list(range(min,max))" command will be
## min to max-1 I think, since list, by itself, starts with 0 as the beginning of the index,
## But I think if it's used in a graph, the categories at the bottom will not exceed
## the data
}
class Group(BaseGroup):
sale_price = models.CurrencyField()
sale_quality = models.StringField()
seller_id = models.IntegerField(
choices=Constants.buy_choices,
widget=widgets.RadioSelect,
doc="""0 means no purchase made"""
)
def set_payoff(self):
for p in self.get_players():
p.payoff = Constants.initial_endowment
#p.p1=self.subsession.p1
if self.seller_id != 0:
seller = self.get_player_by_id(self.seller_id)
buyer = self.get_player_by_role('buyer')
self.sale_price = seller.seller_proposed_price
self.sale_quality = seller.seller_proposed_quality
quality_production_cost = Constants.quality_production_costs[self.sale_quality]
buyer.payoff += quality_production_cost + Constants.buyer_extra_value - self.sale_price
seller.payoff += self.sale_price - quality_production_cost
class Player(BasePlayer):
# p1 = models.IntegerField()
r1 = models.IntegerField()
rr1 = models.IntegerField()
c1 = models.IntegerField()
seller_proposed_price = models.CurrencyField(
min=0, max=Constants.initial_endowment
)
seller_proposed_quality = models.StringField(
choices=Constants.quality_level_names,
widget=widgets.RadioSelectHorizontal
)
#works: test1=models.FloatField(initial=1000)
#test1=models.IntegerField(initial=random.randint(25,999))
#def test1(self):
# return "test"
#test_1=models.FloatField(initial=500)
test_3=models.FloatField(initial=Constants.test_3)
#test_3=random.randint(1, 6)
#test_2=self.rr1
def role(self):
if self.id_in_group == Constants.players_per_group:
return 'buyer'
return 'seller {}'.format(self.id_in_group)