from otree.api import *
from django.utils.safestring import mark_safe
from math import ceil
import random
import html
doc = """
Second opinion game with big group
"""
class C(BaseConstants):
NAME_IN_URL = 'mainexperiment'
PLAYERS_PER_GROUP = 12
NUM_PRACTICE_ROUNDS = 4
NUM_REAL_ROUNDS = 16
NUM_ROUNDS = NUM_PRACTICE_ROUNDS + NUM_REAL_ROUNDS
Problem = {1: 'Major', 2: 'Minor'}
Role = {1: 'Seller', 2: 'Buyer'}
Expert = {1: 'Seller 1', 2: 'Seller 2'}
Percentage = {0: "rarely: 0%-20%",
1: "not often: 21%-40%",
2: "often: 41%-60%",
3: "very often: 61%-80%",
4: "almost always: 81%-100%"}
random.seed(30)
Real_Problem = [[random.randint(1, 2) for _ in range(20)] for _ in range(6)]
# they dont allow to use c.num_rounds in this for some reason, the first num in range is the num
# rounds and the second is num of buyer
# Real_Problem = [[1, 2], [2, 1]]
# first row is the problem of consumer 1 and the second row is the problem of consumer 2
round_change_k = [NUM_PRACTICE_ROUNDS + 9]
#round_change_V = [NUM_PRACTICE_ROUNDS + 9]
#round_change_k = [NUM_PRACTICE_ROUNDS + 5, NUM_PRACTICE_ROUNDS + 9, NUM_PRACTICE_ROUNDS + 13]
V = [6, 12]
Price = [6, 2]
Cost = [3.5, 0]
k = [0.1, 1.1]
lottery = 3.0
multiplier = 2
con_endowment = 0
exp_endowment = 0
Total_con_endowment = 13
Total_exp_endowment = 13
def roundup(x, u=0.50):
return ceil(x / u) * u
def make_expert_field(label):
a = mark_safe("Major treatment")
b = mark_safe("Minor treatment")
return models.BooleanField(
choices=[[True, a], [False, b]],
label=label,
html_labels=True
)
def make_consumer_field(label):
a = mark_safe("Reject the offer and buy from Seller 2 ")
return models.BooleanField(
choices=[[True, "Accept the offer"], [False, a]],
label=label,
)
def make_percentage_field(label):
return models.IntegerField(
choices=[[0, "Rarely: 0%-20%"],
[1, "Not often: 21%-40%"],
[2, "Often: 41%-60%"],
[3, "Very often: 61%-80%"],
[4, "Almost always: 81%-100%"]],
label=label,
)
def make_guess_field(label):
return models.IntegerField(
choices=[[0, "0"],
[1, "1"],
[2, "2"],
[3, "3"],
[4, "4"],
[5, "5"],
[6, "6"]],
label=label,
)
class Group(BaseGroup):
pvalue = models.IntegerField()
pk = models.FloatField()
numacceptH = models.IntegerField()
numacceptL = models.IntegerField()
numovertreat = models.IntegerField()
numhonestoffer = models.IntegerField()
numhonestexp = models.IntegerField(initial=0)
honoff_ch = models.IntegerField()
#def pvalue(group):
#if group.round_number < C.round_change_V[1]:
#return C.V[0]
#else:
#return C.V[1]
#def pk(group):
#if group.round_number < C.round_change_k[1] or group.round_number >= C.round_change_k[3]:
#return C.k[0]
#else:
#return C.k[1]
class Subsession(BaseSubsession):
is_practice_round = models.BooleanField()
real_round_number = models.IntegerField()
def creating_session(subsession: Subsession):
subsession.is_practice_round = (
subsession.round_number <= C.NUM_PRACTICE_ROUNDS
)
if not subsession.is_practice_round:
subsession.real_round_number = (
subsession.round_number - C.NUM_PRACTICE_ROUNDS
)
import itertools
if subsession.round_number == 1:
subsession.group_randomly(fixed_id_in_group=True)
else:
subsession.group_like_round(1)
if subsession.round_number == 1:
if subsession.session.config['within'] == 1:
value = [6, 0.1]
elif subsession.session.config['within'] == 2:
value = [12, 0.1]
elif subsession.session.config['within'] == 3:
value = [6, 1.1]
else:
value = [12, 1.1]
for group in subsession.get_groups():
group.pvalue = value[0]
group.pk = value[1]
player = group.get_player_by_id(1)
player.participant.pvalue = group.pvalue
player.participant.pk = group.pk
elif subsession.round_number in C.round_change_k:
for group in subsession.get_groups():
player = group.get_player_by_id(1)
#if player.participant.pvalue == 6:
# group.pvalue = 12
#else:
# group.pvalue = 6
if player.participant.pk == 0.1:
group.pk = 1.1
else:
group.pk = 0.1
group.pvalue = player.participant.pvalue
player.participant.pk = group.pk
else:
for group in subsession.get_groups():
player = group.get_player_by_id(1)
group.pvalue = player.participant.pvalue
group.pk = player.participant.pk
class Player(BasePlayer):
def role(player):
if player.round_number == 1:
if player.id_in_group <= C.PLAYERS_PER_GROUP // 2:
player.participant.type = 1
else:
player.participant.type = 2
return player.participant.type
else:
return player.participant.type
# def problem(player):
# if player.id_in_group > 2:
# return C.Real_Problem[player.id_in_group - 3][player.round_number - 1]
# else:
# return 'No problem'
# def obsproblem(player):
# if player.id_in_group <= 2:
# n = C.PLAYERS_PER_GROUP // 2
# obsproblem = [[0, 0], [0, 0]]
# for i in range(n):
# for j in range(C.NUM_ROUNDS):
# if random.randrange(100) < player.session.config['beta']:
# obsproblem[i][j] = C.Real_Problem[i][j]
# else:
# if C.Real_Problem[i][j] == 1:
# obsproblem[i][j] = 2
# else:
# obsproblem[i][j] = 1
# return obsproblem
# else:
# return 'I am a consumer.'
# problem
problem = models.IntegerField()
obsproblem = models.IntegerField()
# Overtreament decision
overtreat1 = make_expert_field(mark_safe('Buyer 1'))
overtreat2 = make_expert_field(mark_safe('Buyer 2'))
overtreat3 = make_expert_field(mark_safe('Buyer 3'))
overtreat4 = make_expert_field(mark_safe('Buyer 4'))
overtreat5 = make_expert_field(mark_safe('Buyer 5'))
overtreat6 = make_expert_field(mark_safe('Buyer 6'))
# Search decision
acceptH = make_consumer_field(mark_safe('If Seller 1 offers you a major treatment, would you like to accept or reject?'))
acceptL = make_consumer_field(mark_safe('If Seller 1 offers you a minor treatment, would you like to accept or reject?'))
# Expert guess
conacceptH = make_guess_field(mark_safe("Out of 6 buyers, how many of them will accept a major treatment?"))
conacceptL = make_guess_field(mark_safe("Out of 6 buyers, how many of them will accept a minor treatment?"))
opponentOvertreat = make_percentage_field(
mark_safe("How often would the other sellers offer a minor treatment?")
)
# Consumer guess
honestOffer = make_percentage_field(mark_safe("How often would the sellers offer a minor treatment?"))
honestExp = make_guess_field(mark_safe("Out of 6 sellers, how many of them offer(s) a minor treatment to all buyer(s) with a minor problem?"))
numofconsumer = models.IntegerField(initial=0)
numcon11 = models.IntegerField(initial=0)
numcon12 = models.IntegerField(initial=0)
numcon21 = models.IntegerField(initial=0)
numcon22 = models.IntegerField(initial=0)
numofrej = models.IntegerField(initial=0)
numrej11 = models.IntegerField(initial=0)
numrej12 = models.IntegerField(initial=0)
numrej21 = models.IntegerField(initial=0)
numrej22 = models.IntegerField(initial=0)
#buy from which expert
buyfrom = models.IntegerField(initial=0)
#the purchased treatment
acceptoffer = models.IntegerField()
#the problem is solved or not
problemissolved = models.IntegerField()
#result of quess question
opponenthon_ch = models.IntegerField()
honoff_ch_result = models.IntegerField()
numaccepth_prac = models.IntegerField()
numacceptl_prac = models.IntegerField()
numhonest_exp_prac = models.IntegerField(initial=0)
#password to new section
password = models.IntegerField()
#risk preference
risk = models.FloatField(min=0, max=3, decimal_palce=2,
label="")
# function for the expert offer
#def offer(player):
# offer = [[0, 0], [0, 0]]
# n = player.round_number - 1
# if player.obsproblem()[0][n] == 1 or player.overtreat1:
# offer[0][n] = 1
#else:
# offer[0][n] = 2
# if player.obsproblem()[1][n] == 1 or player.overtreat2:
# offer[1][n] = 1
#else:
# offer[1][n] = 2
# return offer
guesspoint1 = models.FloatField()
guesspoint2 = models.FloatField()
guesspoint3 = models.FloatField()
total_guesspoints = models.FloatField()
real_round_number = models.IntegerField(initial=0)
# function for the consumer acceptance
def accept(player):
if player.acceptH and player.acceptL:
return 3
elif player.acceptH and not player.acceptL:
return 1
elif not player.acceptH and player.acceptL:
return 2
else:
return 0
# Function
def obsproblem(player: Player):
n = C.PLAYERS_PER_GROUP // 2
rows, cols = n, C.NUM_ROUNDS
obsproblem = [([0] * cols) for i in range(rows)]
#obsproblem = [0] * n
if player.id_in_group <= n:
for i in range(n):
for j in range(C.NUM_ROUNDS):
if random.randrange(100) < player.session.config['beta']:
obsproblem[i][j] = C.Real_Problem[i][j]
else:
if C.Real_Problem[i][j] == 1:
obsproblem[i][j] = 2
else:
obsproblem[i][j] = 1
player.participant.obsprob = obsproblem
else:
player.participant.obsprob = obsproblem
#print('real problem is here', C.Real_Problem)
#print('obs problem is here', obsproblem)
return player.participant.obsprob
def problem(player: Player):
if player.id_in_group > C.PLAYERS_PER_GROUP // 2:
player.problem = C.Real_Problem[player.id_in_group - C.PLAYERS_PER_GROUP // 2 - 1][
player.round_number - 1]
else:
player.problem = 0
return player.problem
def get_real_round_num(player: Player):
if player.round_number > C.NUM_PRACTICE_ROUNDS:
player.real_round_number = player.round_number - C.NUM_PRACTICE_ROUNDS
return player.real_round_number
def offer(player: Player):
if player.id_in_group <= C.PLAYERS_PER_GROUP // 2:
offer = [0] * (C.PLAYERS_PER_GROUP // 2)
overtreat = [player.overtreat1, player.overtreat2, player.overtreat3, player.overtreat4, player.overtreat5, player.overtreat6]
random.shuffle(overtreat)
player.participant.overtreatdec = overtreat
#print(player.participant.overtreatdec)
for i in range(C.PLAYERS_PER_GROUP // 2):
r = player.round_number-1
if player.participant.obsprob[i][r] == 1 or overtreat[i]:
offer[i] = 1
else:
offer[i] = 2
#print('offer is here',offer)
player.participant.offer = offer
return player.participant.offer
def is_displayed_con(player: Player):
return player.id_in_group > C.PLAYERS_PER_GROUP // 2
def is_displayed_exp(player: Player):
return player.id_in_group <= C.PLAYERS_PER_GROUP // 2
def before_next_page_exp(player: Player, timeout_happened): #practice round payoff
if player.round_number <= C.NUM_PRACTICE_ROUNDS:
# pre-made other players parameters
random_con = random.randint(0, C.PLAYERS_PER_GROUP // 2 - 1) # pick one of six consumer's problem
#print(random_con)
group = player.group
pC = group.get_player_by_id(random_con + C.PLAYERS_PER_GROUP // 2 +1)
id = pC.id_in_group
#print('con',id)
para_set = [random.randint(1, 2) for _ in range(2)] # other expert_off, order
# guess question3
fake_opponent_offer = [random.randint(1, 2) for _ in range(6 * ((C.PLAYERS_PER_GROUP // 2) - 1))]
numophonest = fake_opponent_offer.count(2)
#print(para_set, numophonest)
totalopoffer = ((C.PLAYERS_PER_GROUP // 2) * 6) - 6
opponenthon = numophonest * 100 // totalopoffer
if 0 <= opponenthon <= 20:
opponenthon_ch = 0
elif 21 <= opponenthon <= 40:
opponenthon_ch = 1
elif 41 <= opponenthon <= 60:
opponenthon_ch = 2
elif 61 <= opponenthon <= 80:
opponenthon_ch = 3
elif 81 <= opponenthon <= 100:
opponenthon_ch = 4
else:
opponenthon_ch = -2
print('Some things were wrong in counting the honest offer (ex q3)')
player.opponenthon_ch = opponenthon_ch
if opponenthon_ch == player.opponentOvertreat:
player.guesspoint3 = 1
else:
player.guesspoint3 = 0
fake_con_acc = [random.randint(0, 3) for _ in
range(C.PLAYERS_PER_GROUP // 2)] # pre-made consumer's acceptance
# guess question 1 and 2
player.numaccepth_prac = fake_con_acc.count(1) + fake_con_acc.count(3)
player.numacceptl_prac = fake_con_acc.count(2) + fake_con_acc.count(3)
# question1
if player.conacceptH == player.numaccepth_prac:
player.guesspoint1 = 1
else:
player.guesspoint1 = 0
# question2
if player.conacceptL == player.numacceptl_prac:
player.guesspoint2 = 1
else:
player.guesspoint2 = 0
player.total_guesspoints = player.guesspoint1 + player.guesspoint2 + player.guesspoint3
con_acc = fake_con_acc[0]
#print(con_acc)
if random.randrange(100) < player.session.config['beta']:
otherex_obs = pC.problem
else:
if pC.problem == 1:
otherex_obs = 2
else:
otherex_obs = 1
if otherex_obs == 1:
otherex_off = 1
else:
otherex_off = fake_opponent_offer[0] # chosen offer of the other expert
#print(otherex_off)
offer = player.participant.offer[random_con]
#print(offer)
if para_set[1] == 1: # be the first visit
player.participant.matchedoffer = [offer]
if offer == con_acc or con_acc == 3:
player.payoff = C.exp_endowment + C.Price[offer - 1] - C.Cost[offer - 1]
player.numofconsumer = 1
if offer != pC.problem and offer == 2: # the problem is not solved
player.numcon12 = 1 # row: have problem 1 column: purchased 2
else: # the problem is solved
if offer == 1 and pC.problem == 1:
player.numcon11 = 1
elif offer == 2 and pC.problem == 2:
player.numcon22 = 1
else:
player.numcon21 = 1
else: # the expert is rejected
player.payoff = C.exp_endowment
player.numofrej = 1
if offer != pC.problem and offer == 2:
player.numrej12 = 1 # row: have problem 1 column: reject 2
else:
if offer == 1 and pC.problem == 1:
player.numrej11 = 1
elif offer == 2 and pC.problem == 2:
player.numrej22 = 1
else:
player.numrej21 = 1
elif para_set[1] == 2: # be the second visit
if otherex_off == con_acc or con_acc == 3:
player.payoff = C.exp_endowment
player.participant.matchedoffer = []
else: # another expert is rejected
player.participant.matchedoffer = [offer]
player.payoff = C.exp_endowment + C.Price[offer - 1] - C.Cost[offer - 1]
player.numofconsumer = 1
if offer != pC.problem and offer == 2: # the problem is not solved
player.numcon12 = 1 # row: have problem 1 column: purchased 2
else: # the problem is solved
if offer == 1 and pC.problem == 1:
player.numcon11 = 1
elif offer == 2 and pC.problem == 2:
player.numcon22 = 1
else:
player.numcon21 = 1
else:
pass
def before_next_page_con(player: Player, timeout_happened): #practice round payoff
if player.round_number <= C.NUM_PRACTICE_ROUNDS:
fake_offer = [random.randint(1, 2) for _ in range(6 * C.PLAYERS_PER_GROUP // 2)]
#print('alloffer', fake_offer)
# fake_offer = [[random.randint(1, 2) for _ in range(6)] for _ in range(C.PLAYERS_PER_GROUP//2)]
# guess question 1
numhonest = fake_offer.count(2)
totaloffer = (C.PLAYERS_PER_GROUP // 2 * 6)
honoff = (numhonest * 100) // totaloffer
if 0 <= honoff <= 20:
honoff_ch = 0
elif 21 <= honoff <= 40:
honoff_ch = 1
elif 41 <= honoff <= 60:
honoff_ch = 2
elif 61 <= honoff <= 80:
honoff_ch = 3
elif 81 <= honoff <= 100:
honoff_ch = 4
else:
honoff_ch = -2
print('Some things were wrong in counting the honest offer (co q1)')
player.honoff_ch_result = honoff_ch
if honoff_ch == player.honestOffer:
player.guesspoint1 = 1
else:
player.guesspoint1 = 0
# guess question 2
col = 6 # number of choices each expert made
fake_offer_m = [fake_offer[i:i + col] for i in range(0, len(fake_offer), col)]
#print(fake_offer_m)
for i in range(len(fake_offer_m)): # range num of row (row is the number of expert)
expert_offer = fake_offer_m[i]
honest = expert_offer.count(0)
if honest == len(fake_offer_m): # always honest all zeros in all fields
player.numhonest_exp_prac = player.numhonest_exp_prac + 1
# if player.honestExp == player.numhonest_exp_prac:
# player.guesspoint2 = 3
# else:
# player.guesspoint2 = 0
player.total_guesspoints = player.guesspoint1 # + player.guesspoint2
para_set = [fake_offer[0], fake_offer[6]] # offers of 2 experts are the first 2
ex_obs = [0, 0]
ex_off = [0, 0]
prob = player.problem
for i in range(2):
if random.randrange(100) < player.session.config['beta']:
ex_obs[i] = prob
else:
if prob == 1:
ex_obs[i] = 2
else:
ex_obs[i] = 1
if ex_obs[i] == 1:
ex_off[i] = 1
else:
ex_off[i] = para_set[i]
#print(prob)
#print(ex_off)
#print(player.accept())
if ex_off[0] == player.accept() or player.accept() == 3:
player.acceptoffer = ex_off[0]
player.buyfrom = 1
if ex_off[0] != prob and ex_off[0] == 2: # the problem is not solved
player.problemissolved = 0
player.payoff = C.con_endowment - C.Price[ex_off[0] - 1] # row: have problem 1 column: purchased 2
else: # the problem is solved
player.payoff = C.con_endowment + player.group.pvalue - C.Price[ex_off[0] - 1]
player.problemissolved = 1
else: # consumer search
player.acceptoffer = ex_off[1]
player.buyfrom = 2
if ex_off[1] != prob and ex_off[1] == 2: # the problem is not solved
player.problemissolved = 0
player.payoff = C.con_endowment - C.Price[ex_off[1] - 1] - player.group.pk # row: have problem 1 column: purchased 2
else: # the problem is solved
player.problemissolved = 1
player.payoff = C.con_endowment + player.group.pvalue - C.Price[ex_off[1] - 1] - player.group.pk
else:
pass
def set_payoffs_prac(group: Group): #not use
players = group.get_players()
for player in players:
if player.id_in_group <= C.PLAYERS_PER_GROUP // 2:
#pre-made other players parameters
random_con = random.randint(0, C.PLAYERS_PER_GROUP // 2 -1) # pick one of six consumer's problem
pC = group.get_player_by_id(random_con + C.PLAYERS_PER_GROUP // 2)
para_set = [random.randint(1, 2) for _ in range(2)] #other expert_off, order
#guess question3
fake_opponent_offer = [random.randint(1, 2) for _ in range(6 * ((C.PLAYERS_PER_GROUP // 2) - 1))]
numophonest = fake_opponent_offer.count(2)
#print(para_set, numophonest)
totalopoffer = ((C.PLAYERS_PER_GROUP // 2) * 6) - 6
opponenthon = numophonest * 100 // totalopoffer
if 0 <= opponenthon <= 20:
opponenthon_ch = 0
elif 21 <= opponenthon <= 40:
opponenthon_ch = 1
elif 41 <= opponenthon <= 60:
opponenthon_ch = 2
elif 61 <= opponenthon <= 80:
opponenthon_ch = 3
elif 81 <= opponenthon <= 100:
opponenthon_ch = 4
else:
opponenthon_ch = -2
print('Some things were wrong in counting the honest offer (ex q3)')
player.opponenthon_ch = opponenthon_ch
if opponenthon_ch == player.opponentOvertreat:
player.guesspoint3 = 1
else:
player.guesspoint3 = 0
fake_con_acc = [random.randint(0, 3) for _ in range(C.PLAYERS_PER_GROUP // 2)] # pre-made consumer's acceptance
#guess question 1 and 2
player.numaccepth_prac = fake_con_acc.count(1) + fake_con_acc.count(3)
player.numacceptl_prac = fake_con_acc.count(2) + fake_con_acc.count(3)
# question1
if player.conacceptH == player.numaccepth_prac:
player.guesspoint1 = 1
else:
player.guesspoint1 = 0
# question2
if player.conacceptL == player.numacceptl_prac:
player.guesspoint2 = 1
else:
player.guesspoint2 = 0
player.total_guesspoints = player.guesspoint1 + player.guesspoint2 + player.guesspoint3
con_acc = fake_con_acc[0]
#print(con_acc)
if random.randrange(100) < group.session.config['beta']:
otherex_obs = pC.problem
else:
if pC.problem == 1:
otherex_obs = 2
else:
otherex_obs = 1
if otherex_obs == 1:
otherex_off = 1
else:
otherex_off = fake_opponent_offer[0] #chosen offer of the other expert
#print(otherex_off)
offer = player.participant.offer[random_con]
#print(offer)
if para_set[1] == 1: #be the first visit
player.participant.matchedoffer = [offer]
if offer == con_acc or con_acc == 3:
player.payoff = C.exp_endowment + C.Price[offer - 1] - C.Cost[offer - 1]
player.numofconsumer = 1
if offer != pC.problem and offer == 2: # the problem is not solved
player.numcon12 = 1 # row: have problem 1 column: purchased 2
else: # the problem is solved
if offer == 1 and pC.problem == 1:
player.numcon11 = 1
elif offer == 2 and pC.problem == 2:
player.numcon22 = 1
else:
player.numcon21 = 1
else: # the expert is rejected
player.payoff = C.exp_endowment
player.numofrej = 1
if offer != pC.problem and offer == 2:
player.numrej12 = 1 # row: have problem 1 column: reject 2
else:
if offer == 1 and pC.problem == 1:
player.numrej11 = 1
elif offer == 2 and pC.problem == 2:
player.numrej22 = 1
else:
player.numrej21 = 1
elif para_set[1] == 2: #be the second visit
if otherex_off == con_acc or con_acc == 3:
player.payoff = C.exp_endowment
player.participant.matchedoffer = []
else: # another expert is rejected
player.participant.matchedoffer = [offer]
player.payoff = C.exp_endowment + C.Price[offer - 1] - C.Cost[offer - 1]
player.numofconsumer = 1
if offer != pC.problem and offer == 2: # the problem is not solved
player.numcon12 = 1 # row: have problem 1 column: purchased 2
else: # the problem is solved
if offer == 1 and pC.problem == 1:
player.numcon11 = 1
elif offer == 2 and pC.problem == 2:
player.numcon22 = 1
else:
player.numcon21 = 1
else: #be the consumer
fake_offer = [random.randint(1, 2) for _ in range(6 * C.PLAYERS_PER_GROUP//2)]
#print('alloffer', fake_offer)
#fake_offer = [[random.randint(1, 2) for _ in range(6)] for _ in range(C.PLAYERS_PER_GROUP//2)]
#guess question 1
numhonest = fake_offer.count(2)
totaloffer = (C.PLAYERS_PER_GROUP // 2 * 6)
honoff = (numhonest * 100) // totaloffer
if 0 <= honoff <= 20:
honoff_ch = 0
elif 21 <= honoff <= 40:
honoff_ch = 1
elif 41 <= honoff <= 60:
honoff_ch = 2
elif 61 <= honoff <= 80:
honoff_ch = 3
elif 81 <= honoff <= 100:
honoff_ch = 4
else:
honoff_ch = -2
print('Some things were wrong in counting the honest offer (co q1)')
player.honoff_ch_result = honoff_ch
if honoff_ch == player.honestOffer:
player.guesspoint1 = 1
else:
player.guesspoint1 = 0
#guess question 2
col = 6 #number of choices each expert made
fake_offer_m = [fake_offer[i:i+col] for i in range(0, len(fake_offer), col)]
#print(fake_offer_m)
for i in range(len(fake_offer_m)): # range num of row (row is the number of expert)
expert_offer = fake_offer_m[i]
honest = expert_offer.count(0)
if honest == len(fake_offer_m): # always honest all zeros in all fields
player.numhonest_exp_prac = player.numhonest_exp_prac + 1
#if player.honestExp == player.numhonest_exp_prac:
# player.guesspoint2 = 3
#else:
# player.guesspoint2 = 0
player.total_guesspoints = player.guesspoint1 #+ player.guesspoint2
para_set = [fake_offer[0], fake_offer[6]] #offers of 2 experts are the first 2
ex_obs = [0,0]
ex_off = [0,0]
prob = player.problem
for i in range(2):
if random.randrange(100) < player.session.config['beta']:
ex_obs[i] = prob
else:
if prob == 1:
ex_obs[i] = 2
else:
ex_obs[i] = 1
if ex_obs[i] == 1:
ex_off[i] = 1
else:
ex_off[i] = para_set[i]
#print(prob)
#print(ex_off)
#print(player.accept())
if ex_off[0] == player.accept() or player.accept() == 3:
player.acceptoffer = ex_off[0]
player.buyfrom = 1
if ex_off[0] != prob and ex_off[0] == 2: # the problem is not solved
player.problemissolved = 0
player.payoff = C.con_endowment - C.Price[ex_off[0]-1] # row: have problem 1 column: purchased 2
else: # the problem is solved
player.problemissolved = 1
player.payoff = C.con_endowment + group.pvalue - C.Price[ex_off[0]-1]
else: #consumer search
player.acceptoffer = ex_off[1]
player.buyfrom = 2
if ex_off[1] != prob and ex_off[1] == 2: # the problem is not solved
player.problemissolved = 0
player.payoff = C.con_endowment - C.Price[ex_off[1]-1] - group.pk # row: have problem 1 column: purchased 2
else: # the problem is solved
player.problemissolved = 1
player.payoff = C.con_endowment + group.pvalue - C.Price[ex_off[1]-1] - group.pk
def display(x):
return C.Problem[x]
def set_payoffs(group: Group):
expert = list(range(1, C.PLAYERS_PER_GROUP // 2 + 1))
n = 2 # number of experts drawn
exp1offer = [0] * (C.PLAYERS_PER_GROUP // 2) # initial list of selected expert's offer
exp2offer = [0] * (C.PLAYERS_PER_GROUP // 2)
r = group.round_number - 1
for i in range(C.PLAYERS_PER_GROUP // 2):
pC = group.get_player_by_id(C.PLAYERS_PER_GROUP // 2 + i + 1) # choose the consumer ordered by id
matchedexp = random.sample(expert, n) # choose 2 experts for that consumer
#print('2 experts for con',matchedexp)
pE1 = group.get_player_by_id(matchedexp[0]) # the first visited expert
pE2 = group.get_player_by_id(matchedexp[1]) # the second opinion
conproblem = pC.problem
conacc = pC.accept()
exp1offer[i] = pE1.participant.offer[i] # the first expert's offer for buyer id C.PLAYERS_PER_GROUP // 2 + i + 1
exp2offer[i] = pE2.participant.offer[i] # the first expert's offer for buyer id C.PLAYERS_PER_GROUP // 2 + i + 1
past1matched = pE1.participant.matchedoffer
past1matched.append(exp1offer[i])
pE1.participant.matchedoffer = past1matched
if conacc == exp1offer[i] or conacc == 3: # consumer purchases from the first expert
addpayoff1 = C.exp_endowment + C.Price[exp1offer[i] - 1] - C.Cost[exp1offer[i] - 1]
addpayoff2 = C.exp_endowment
numreject1 = 0
numcon1 = 1
numcon2 = 0
numcon2mat = [[0, 0], [0, 0]]
numrej1mat = [[0, 0], [0, 0]]
pC.acceptoffer = exp1offer[i] # the offer accepted from the first expert
pC.buyfrom = 1
#print('f',i)
if exp1offer[i] != conproblem and exp1offer[i] == 2: # the problem is not solved
pC.problemissolved = 0
pC.payoff = C.con_endowment - C.Price[exp1offer[i] - 1]
numcon1mat = [[0, 1], [0, 0]] # row: have problem 1 column: purchased 2
else: # the problem is solved
pC.problemissolved = 1
pC.payoff = C.con_endowment + group.pvalue - C.Price[exp1offer[i] - 1]
if exp1offer[i] == 1 and conproblem == 1:
numcon1mat = [[1, 0], [0, 0]]
elif exp1offer[i] == 2 and conproblem == 2:
numcon1mat = [[0, 0], [0, 1]]
else:
numcon1mat = [[0, 0], [1, 0]]
else: #consumer purchased from the second expert
addpayoff1 = C.exp_endowment
addpayoff2 = C.exp_endowment + C.Price[exp2offer[i] - 1] - C.Cost[exp2offer[i] - 1]
numreject1 = 1
numcon1 = 0
numcon2 = 1
numcon1mat = [[0, 0], [0, 0]]
pC.acceptoffer = exp2offer[i]
pC.buyfrom = 2
past2matched = pE2.participant.matchedoffer
past2matched.append(exp2offer[i])
pE2.participant.matchedoffer = past2matched
#print('consumer num', i)
if exp2offer[i] != conproblem and exp2offer[i] == 2: # the problem is not solved
pC.problemissolved = 0
pC.payoff = C.con_endowment - C.Price[exp2offer[i] - 1] - group.pk
numcon2mat = [[0, 1], [0, 0]]
else: # the problem is solved
pC.problemissolved = 1
pC.payoff = C.con_endowment + group.pvalue - C.Price[exp2offer[i] - 1] - group.pk
if exp2offer[i] == 1 and conproblem == 1:
numcon2mat = [[1, 0], [0, 0]]
elif exp2offer[i] == 2 and conproblem == 2:
numcon2mat = [[0, 0], [0, 1]]
else:
numcon2mat = [[0, 0], [1, 0]]
if exp1offer[i] == 1 and conproblem == 1:
numrej1mat = [[1, 0], [0, 0]]
elif exp1offer[i] == 1 and conproblem == 2:
numrej1mat = [[0, 0], [1, 0]]
elif exp1offer[i] == 2 and conproblem == 1:
numrej1mat = [[0, 1], [0, 0]]
else:
numrej1mat = [[0, 0], [0, 1]]
pE1.payoff = pE1.payoff + addpayoff1
pE2.payoff = pE2.payoff + addpayoff2
# number of consumer who accepted for each expert
pE1.numofconsumer = pE1.numofconsumer + numcon1
pE2.numofconsumer = pE2.numofconsumer + numcon2
# number of consumer who rejected for each expert
pE1.numofrej = pE1.numofrej + numreject1
# number of consumer who accepted for each expert (detailed)
pE1.numcon11 = pE1.numcon11 + numcon1mat[0][0]
pE1.numcon12 = pE1.numcon12 + numcon1mat[0][1]
pE1.numcon21 = pE1.numcon21 + numcon1mat[1][0]
pE1.numcon22 = pE1.numcon22 + numcon1mat[1][1]
pE2.numcon11 = pE2.numcon11 + numcon2mat[0][0]
pE2.numcon12 = pE2.numcon12 + numcon2mat[1][0]
pE2.numcon21 = pE2.numcon21 + numcon2mat[0][1]
pE2.numcon22 = pE2.numcon22 + numcon2mat[1][1]
# number of consumer who rejected for each expert (detailed)
pE1.numrej11 = pE1.numrej11 + numrej1mat[0][0]
pE1.numrej12 = pE1.numrej12 + numrej1mat[0][1]
pE1.numrej21 = pE1.numrej21 + numrej1mat[1][0]
pE1.numrej22 = pE1.numrej22 + numrej1mat[1][1]
#count decision
players = group.get_players()
sumAcceptH = [p.field_maybe_none('acceptH') for p in players]
sumAcceptL = [p.field_maybe_none('acceptL') for p in players]
sumovertreat1 = [p.field_maybe_none('overtreat1') for p in players]
sumovertreat2 = [p.field_maybe_none('overtreat2') for p in players]
sumovertreat3 = [p.field_maybe_none('overtreat3') for p in players]
sumovertreat4 = [p.field_maybe_none('overtreat4') for p in players]
sumovertreat5 = [p.field_maybe_none('overtreat5') for p in players]
sumovertreat6 = [p.field_maybe_none('overtreat6') for p in players]
sumovertreat = sumovertreat1 + sumovertreat2 + sumovertreat3 + sumovertreat4 + sumovertreat5 + sumovertreat6
sumovertreat_mat = [sumovertreat1, sumovertreat2, sumovertreat3, sumovertreat4, sumovertreat5, sumovertreat6]
totalhon = []
for i in range(len(sumovertreat_mat[0])): #range num of column
ind_overtreat = [row[i] for row in sumovertreat_mat] #call columns
honest = ind_overtreat.count(0)
totalhon.append(honest)
if honest == len(sumovertreat_mat): #always honest all zeros in all fields
group.numhonestexp = group.numhonestexp + 1
group.numacceptH = sum(filter(None, sumAcceptH))
group.numacceptL = sum(filter(None, sumAcceptL))
group.numovertreat = sum(filter(None, sumovertreat))
group.numhonestoffer = (C.PLAYERS_PER_GROUP // 2)*6 - group.numovertreat
for p in players:
if p.id_in_group <= C.PLAYERS_PER_GROUP //2:
# question1
if p.conacceptH == group.numacceptH:
p.guesspoint1 = 1
else:
p.guesspoint1 = 0
# question2
if p.conacceptL == group.numacceptL:
p.guesspoint2 = 1
else:
p.guesspoint2 = 0
# question3
totalopoffer = ((C.PLAYERS_PER_GROUP //2 ) * 6) - 6
opponenthon = (group.numhonestoffer - totalhon[p.id_in_group-1])*100 // totalopoffer
if 0 <= opponenthon <= 20:
opponenthon_ch = 0
elif 21 <= opponenthon <= 40:
opponenthon_ch = 1
elif 41 <= opponenthon <= 60:
opponenthon_ch = 2
elif 61 <= opponenthon <= 80:
opponenthon_ch = 3
elif 81 <= opponenthon <= 100:
opponenthon_ch = 4
else:
opponenthon_ch = -2
print('Some things were wrong in counting the honest offer (ex q3)')
p.opponenthon_ch = opponenthon_ch
if opponenthon_ch == p.opponentOvertreat:
p.guesspoint3 = 1
else:
p.guesspoint3 = 0
p.total_guesspoints = p.guesspoint1 + p.guesspoint2 + p.guesspoint3
else:
# question1
totaloffer = (C.PLAYERS_PER_GROUP // 2 * 6)
honoff = (group.numhonestoffer * 100) // totaloffer
if 0 <= honoff <= 20:
honoff_ch = 0
elif 21 <= honoff <= 40:
honoff_ch = 1
elif 41 <= honoff <= 60:
honoff_ch = 2
elif 61 <= honoff <= 80:
honoff_ch = 3
elif 81 <= honoff <= 100:
honoff_ch = 4
else:
honoff_ch = -2
print('Some things were wrong in counting the honest offer (co q1)')
group.honoff_ch = honoff_ch
p.honoff_ch_result = honoff_ch #save the group variable in player class
if honoff_ch == p.honestOffer:
p.guesspoint1 = 1
else:
p.guesspoint1 = 0
# question2
#if p.honestExp == group.numhonestexp:
# p.guesspoint2 = 3
#else:
# p.guesspoint2 = 0
p.total_guesspoints = p.guesspoint1 #+ p.guesspoint2
def before_next_page1(player: Player, timeout_happened):
participant = player.participant
# if it's the last round
if player.round_number == C.NUM_ROUNDS:
b = 4 #number of blocks
random_round_mat = [random.sample(range(C.NUM_PRACTICE_ROUNDS + 1,
C.NUM_PRACTICE_ROUNDS + C.NUM_REAL_ROUNDS // b + 1), 2),
random.sample(range(C.NUM_PRACTICE_ROUNDS + C.NUM_REAL_ROUNDS // b + 1,
C.NUM_PRACTICE_ROUNDS + 2*(C.NUM_REAL_ROUNDS // b) + 1), 2),
random.sample(range(C.NUM_PRACTICE_ROUNDS + 2*(C.NUM_REAL_ROUNDS // b) + 1,
C.NUM_PRACTICE_ROUNDS + 3 * (C.NUM_REAL_ROUNDS // b) + 1),2),
random.sample(range(C.NUM_PRACTICE_ROUNDS + 3*(C.NUM_REAL_ROUNDS // b) + 1,
C.NUM_ROUNDS + 1), 2)]
#print(random_round_mat)
selected_around = [row[0] for row in random_round_mat]
selected_ground = [row[1] for row in random_round_mat]
pick_rounds = selected_around + selected_ground
participant.selected_round = pick_rounds
#print(participant.selected_round)
participant.task2_payoff = 0
for i in range(2 * C.NUM_REAL_ROUNDS // b):
player_in_selected_round = player.in_round(pick_rounds[i])
if i == 0: #add only task1 payoffs
addpayoff = player_in_selected_round.payoff
participant.payoff = addpayoff
participant.task1_payoff = addpayoff
#print(addpayoff)
#print('h')
elif i >= C.NUM_REAL_ROUNDS // b: #add only task2 payoffs
addpayoff = player_in_selected_round.total_guesspoints
participant.payoff = participant.payoff + addpayoff
participant.task2_payoff = participant.task2_payoff + addpayoff
#print(addpayoff)
#print('hh')
else:
addpayoff = player_in_selected_round.payoff
participant.payoff = participant.payoff + addpayoff
participant.task1_payoff = participant.task1_payoff + addpayoff
#print(addpayoff)
#print('hhh')
if player.id_in_group <= C.PLAYERS_PER_GROUP // 2:
participant.payoff = participant.payoff + C.Total_exp_endowment
else:
participant.payoff = participant.payoff + C.Total_con_endowment
#lottery
r = random.uniform(0, 1)
participant.savings = C.lottery - player.risk
if r >= 0.5:
participant.win_lottery = True
participant.bonus = C.multiplier * player.risk
else:
participant.win_lottery = False
participant.bonus = 0.0
participant.payoff = roundup(participant.payoff + participant.bonus + participant.savings)
participant.risk = player.risk
#all_rounds = player.in_all_rounds()
#participant.round_players = all_rounds[4:]
# PAGES
class Passtonewsec(Page):
form_model = 'player'
form_fields = ['password']
@staticmethod
def is_displayed(player):
return player.round_number in [C.NUM_PRACTICE_ROUNDS + 8]
@staticmethod
def error_message(player: Player, values):
solution = dict(password=695)
if values != solution:
return "Your password is incorrect. Please try again"
class Intro(Page):
@staticmethod
def vars_for_template(player):
a = C.Role[player.role()]
b = player.session.config['within']
c1 = C.NUM_PRACTICE_ROUNDS + 1
c2 = C.NUM_PRACTICE_ROUNDS + 9
#c3 = C.NUM_PRACTICE_ROUNDS + 9
#c4 = C.NUM_PRACTICE_ROUNDS + 13
return dict(
a=a,
b=b,
c1=c1,
c2=c2
)
@staticmethod
def before_next_page(player: Player, timeout_happened):
get_real_round_num(player)
problem(player)
obsproblem(player)
class ExpDe(Page):
form_model = 'player'
form_fields = ['overtreat1', 'overtreat2', 'overtreat3', 'overtreat4', 'overtreat5', 'overtreat6']
is_displayed = is_displayed_exp
@staticmethod
def vars_for_template(player):
a = player.session.config['beta']
return dict(
a=a,
)
@staticmethod
def before_next_page(player: Player, timeout_happened):
offer(player)
player.participant.matchedoffer = []
#print('empty:', player.participant.matchedoffer)
class ExpGuess(Page):
form_model = 'player'
form_fields = ['conacceptH', 'conacceptL', 'opponentOvertreat']
is_displayed = is_displayed_exp
before_next_page = before_next_page_exp
class ConDe(Page):
form_model = 'player'
form_fields = ['acceptH', 'acceptL']
is_displayed = is_displayed_con
@staticmethod
def vars_for_template(player):
a = player.session.config['beta']
return dict(
a=a,
)
class ConGuess(Page):
form_model = 'player'
form_fields = ['honestOffer']
is_displayed = is_displayed_con
before_next_page = before_next_page_con
class ResultsWaitPage(WaitPage):
@staticmethod
def is_displayed(player):
return player.round_number > C.NUM_PRACTICE_ROUNDS
@staticmethod
def after_all_players_arrive(group: Group):
#if group.subsession.is_practice_round:
# print('hehe')
# set_payoffs_prac(group)
# else:
# print('ho')
set_payoffs(group)
class ExpResults(Page):
is_displayed = is_displayed_exp
#before_next_page = before_next_page1
@staticmethod
def vars_for_template(player):
a = len(player.participant.matchedoffer)
b = player.participant.matchedoffer.count(1)
c = player.participant.matchedoffer.count(2)
if player.guesspoint1 > 0:
d = 'correct'
else:
d = 'incorrect'
if player.guesspoint2 > 0:
e = 'correct'
else:
e = 'incorrect'
f = C.Percentage[player.opponenthon_ch]
if player.guesspoint3 > 0:
g = 'correct'
else:
g = 'incorrect'
h = player.total_guesspoints
return dict(
a=a,
b=b,
c=c,
d=d,
e=e,
f=f,
g=g,
h=h
)
class ConResults(Page):
is_displayed = is_displayed_con
#before_next_page = before_next_page1
@staticmethod
def vars_for_template(player):
a = C.Problem[player.problem]
b = C.Problem[player.acceptoffer]
c = C.Expert[player.buyfrom]
d = C.Percentage[player.honoff_ch_result]
if player.guesspoint1 > 0:
e = 'correct'
else:
e = 'incorrect'
#if player.guesspoint2 > 0:
# f = 'correct'
#else:
# f = 'incorrect'
g = player.total_guesspoints
return dict(
a=a,
b=b,
c=c,
d=d,
e=e,
#f=f,
g=g
)
class NewGameWaitPage(WaitPage):
wait_for_all_groups = True
title_text = 'Waiting for other players to begin the game'
body_text = " "
@staticmethod
def is_displayed(player):
return player.round_number == 1
class SectionWaitPage(WaitPage):
wait_for_all_groups = True
title_text = 'Waiting for other players to begin the new section'
body_text = "The experimenter will hand in the new section instructions."
@staticmethod
def is_displayed(player):
return player.round_number in [C.NUM_PRACTICE_ROUNDS, C.NUM_PRACTICE_ROUNDS + 8]
class NewpartWaitPage(WaitPage):
wait_for_all_groups = True
title_text = 'Waiting for other players to begin Part 2'
body_text = "Part 2 and 3 instructions will show on your screen."
@staticmethod
def is_displayed(player):
return player.round_number == C.NUM_ROUNDS
class Risk(Page):
form_model = 'player'
form_fields = ['risk']
before_next_page = before_next_page1
@staticmethod
def is_displayed(player):
return player.round_number == C.NUM_ROUNDS
class EndgameWaitPage(WaitPage):
wait_for_all_groups = True
title_text = 'Waiting for other players'
body_text = " "
@staticmethod
def is_displayed(player):
return player.round_number == C.NUM_PRACTICE_ROUNDS + 16
class Endgame(Page):
@staticmethod
def vars_for_template(player):
all_rounds = player.in_all_rounds()
round_players = all_rounds[4:]
return dict(
round_players=round_players
)
@staticmethod
def is_displayed(player):
return player.round_number == C.NUM_ROUNDS
page_sequence = [NewGameWaitPage, Intro, ExpDe, ExpGuess, ConDe, ConGuess, ResultsWaitPage, ExpResults, ConResults,
SectionWaitPage, Passtonewsec, Endgame, NewpartWaitPage, Risk]