from statistics import correlation
from click import option
from otree.api import *
doc = """
Your app description
"""
import random, itertools, copy
def BuildLottery(pos_a, state_order, Ah, Al, Bh, Bl, correlation, pi=0):
# change correlation structure
lot0 = [[50, 50], [Ah + pi, Al + pi], [Bh, Bl]]
if correlation == "negative":
lot0 = [[50, 50], [Ah+ pi, Al+ pi], [Bl, Bh]] # change state_order
if correlation == "negative":
lot0 = [[50, 50], [Al+ pi, Ah+ pi], [Bh, Bl]] # change state_order
outcomes_a, outcomes_b = [], []
for s in state_order:
outcomes_a.append(lot0[1][s])
outcomes_b.append(lot0[2][s])
if pos_a == 0:
lot1 = [lot0[0], outcomes_b, outcomes_a]
else:
lot1 = [lot0[0], outcomes_a, outcomes_b]
return lot1
def probas(pp, N):
probas = list()
for i in pp:
probas.append(int(round((i/N)*100, 0)))
return probas
def fields(pp):
fields_to, fields_from = list(), list()
a, b = 1, 0
for i in pp:
fields_from.append(a)
a = a + i
b = b + i
fields_to.append(b)
return [fields_from, fields_to]
class C(BaseConstants):
NAME_IN_URL = 'main'
PLAYERS_PER_GROUP = None
Lotteries = dict()
Lotteries['main'], Lotteries['practice'] = dict(), dict()
Ah, Al, Bh, Bl = 99, 55, 88, 44
Lotteries['practice'][99] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
Ah, Al, Bh, Bl = 280, 80, 270, 70
Lotteries['main'][1] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
Ah, Al, Bh, Bl = 280, 80, 220, 20
Lotteries['main'][2] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
Ah, Al, Bh, Bl = 220, 120, 210, 110
Lotteries['main'][3] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
Ah, Al, Bh, Bl = 280, 180, 210, 110
Lotteries['main'][4] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
# Ah, Al, Bh, Bl = 260, 20, 180, 100
# Lotteries['main'][5] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
# Ah, Al, Bh, Bl = 280, 30, 140, 120
# Lotteries['main'][6] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
# Ah, Al, Bh, Bl = 290, 50, 110, 100
# Lotteries['main'][7] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
#
Ah, Al, Bh, Bl = 130, 130, 130, 130
Lotteries['main'][5] = {'Ah': Ah, 'Al': Al, 'Bh': Bh, 'Bl': Bl}
N_main = len(Lotteries['main'])*3 - 1
num_relevant = N_main
num_rep_learn = 4
NUM_ROUNDS = 3*len(Lotteries['main']) + num_rep_learn + 1 - 1
coarse_lower_bound = 0
coarse_upper_bound = 300
coarse_step_size = 30
fine_step_size = 3
target_value = 110
def creating_session(subsession):
if subsession.round_number == 1:
for p in subsession.get_players():
v_type, v_pos_a, v_state_order, v_lot, v_state, v_blockround, v_total, v_pos_neg = [], [], [], [], [], [], [], []
# practice rounds
realized_states = [0, 1, 0 ,1]
random.shuffle(realized_states)
pos_a_practice = random.choice([0, 1])
pos_neg_practice = random.choice([0, 1])
state_order_practice = random.choice([[0, 1], [1, 0]])
for j in range(C.num_rep_learn):
v_type.append('practice')
v_pos_a.append(pos_a_practice)
v_pos_a.append(pos_neg_practice)
v_state_order.append(state_order_practice)
v_lot.append(99)
v_state.append(realized_states[j])
v_blockround.append(j+1)
v_total.append(C.num_rep_learn)
count = 1
order_dict = dict()
for l in range(1, len(C.Lotteries['main'])):
order_dict[count] = {'nr': l, 'negative': 0, 'positive': 0}
count += 1
order_dict[count] = {'nr': l, 'negative': 10, 'positive': 0}
count += 1
order_dict[count] = {'nr': l, 'negative': 0, 'positive': 10}
count += 1
order_dict[count] = {'nr': len(C.Lotteries['main']), 'negative': 10, 'positive': 0}
count += 1
order_dict[count] = {'nr': len(C.Lotteries['main']), 'negative': 0, 'positive': 30}
count += 1
#main tasks
# v_order = list(range(1, len(C.Lotteries['main'])))
# random.shuffle(v_order)
# v_order.append(len(C.Lotteries['main']))
v_order = list(range(1, len(order_dict)+ 1 ))
random.shuffle(v_order)
order_dict[99] = {'nr': 99, 'negative': 0, 'positive': 0}
for j in range(1, len(order_dict) ):
v_type.append('main')
v_pos_a.append(random.choice([0,1]))
v_pos_neg.append(random.choice([0, 1]))
v_state_order.append(random.choice([[0, 1], [1, 0]]))
v_lot.append(v_order[j-1])
v_state.append(random.choice([0, 1]))
v_blockround.append(j)
v_total.append(C.num_relevant )
relevant_round = []
RoundDict = dict()
for r in range(1, C.NUM_ROUNDS):
RoundDict[r] = dict()
RoundDict[r]['position_a'] = v_pos_a[r - 1]
RoundDict[r]['position_neg'] = v_pos_a[r - 1]
state_order = v_state_order[r - 1]
RoundDict[r]['state_order'] = state_order
key = v_lot[r - 1]
RoundDict[r]['lottery_nr'] = order_dict[key]['nr']
RoundDict[r]['type'] = v_type[r - 1]
if v_type[r - 1] == 'practice':
RoundDict[r]['feedback'] = 1
else:
RoundDict[r]['feedback'] = 0
RoundDict[r]['type'] = v_type[r - 1]
if v_type[r - 1] == 'main':
relevant_round.append(r)
RoundDict[r]['blockround'] = v_blockround[r - 1]
RoundDict[r]['total_block'] = v_total[r - 1]
RoundDict[r]['pi_pos'] = order_dict[key]['positive']
RoundDict[r]['pi_neg'] = order_dict[key]['negative']
if v_type[r - 1] == 'practice':
pars = C.Lotteries[v_type[r - 1]][key]
else:
pars = C.Lotteries[v_type[r - 1]][order_dict[key]['nr']]
for corr in ["negative", "positive"]:
RoundDict[r][corr] = dict()
lot = BuildLottery(pos_a=v_pos_a[r - 1], state_order=v_state_order[r - 1], Ah=pars['Ah'],
Al=pars['Al'], Bh=pars['Bh'],
Bl=pars['Bl'], correlation=corr, pi=order_dict[key][corr])
RoundDict[r][corr]['lottery'] = lot
# draw random outcome etc
state0 = v_state[r - 1]
RoundDict[r][corr]['state'] = state0
state1 = state_order.index(state0)
fields_from, fields_to = fields(lot[0])[0], fields(lot[0])[1]
field_from, field_to = fields_from[state1], fields_to[state1]
population = list()
weights = list()
for i in range(field_from + 1, field_to + 1):
population.append(i)
weights.append(1 / (field_to - field_from + 1))
RoundDict[r][corr]['realized_field'] = random.choices(
population=population,
weights=weights
)[0]
# this is the outcome of A and B, wrt to the L0
RoundDict[r][corr]['outcome_a'] = lot[1][state1]
RoundDict[r][corr]['outcome_b'] = lot[2][state1]
if v_pos_a[r - 1] == 0:
RoundDict[r][corr]['outcome_a'] = lot[2][state1]
RoundDict[r][corr]['outcome_b'] = lot[1][state1]
RoundDict[r][corr]['make_choice'] = 1
relevant = random.choice(relevant_round)
RoundDict[C.NUM_ROUNDS] = copy.deepcopy(RoundDict[relevant])
RoundDict[C.NUM_ROUNDS]['make_choice'] = 0
p.participant.vars['relevant'] = relevant
p.participant.vars['RoundDict'] = RoundDict
# test vars
p.participant.vars['test_tries'] = 0
p.participant.vars['test_1'] = 0
p.participant.vars['test_2'] = 0
p.participant.vars['test_3'] = 0
p.participant.vars['test_4'] = 0
p.participant.vars['saved_eval'] = None
class Subsession(BaseSubsession):
pass
class Group(BaseGroup):
pass
class Player(BasePlayer):
test_1 = models.IntegerField(blank=True)
test_2 = models.IntegerField(blank=True)
test_3 = models.IntegerField(blank=True)
test_4 = models.IntegerField(blank=True)
test_tries = models.IntegerField()
evaluation_passed = models.IntegerField(initial=0, blank=True)
menu = models.StringField()
pi_pos = models.IntegerField()
pi_neg = models.IntegerField()
lottery_nr = models.IntegerField()
pos_a = models.IntegerField()
pos_neg = models.IntegerField()
state_order = models.StringField()
correlation = models.StringField
choice = models.StringField(blank=True)
ce_value = models.FloatField(blank=True)
type = models.StringField()
realized = models.StringField()
attention = models.IntegerField()
age = models.IntegerField(
label="Age",
min=16,
max=120,
)
gender = models.StringField(
label="Gender",
choices=[
"Female",
"Male",
"Non-binary / third gender",
"Prefer not to say",
],
widget=widgets.RadioSelect,
)
education = models.StringField(
label="Highest completed education",
choices=[
"Less than high school",
"High school / secondary school",
"Vocational training / apprenticeship",
"Some college / university (no degree yet)",
"Bachelor’s degree",
"Master’s degree",
"PhD / doctorate",
"Other",
],
)
country = models.StringField(
label="Country of residence",
blank=False,
)
employment = models.StringField(
label="Employment status",
choices=[
"Student",
"Employed full-time",
"Employed part-time",
"Self-employed",
"Unemployed",
"Retired",
"Other",
],
)
income = models.StringField(
label="Household income (optional)",
blank=False,
choices=[
"Prefer not to say",
"Under £1,000 per month",
"£1,000–£1,999 per month",
"£2,000–£2,999 per month",
"£3,000–£3,999 per month",
"£4,000–£4,999 per month",
"£5,000–£6,999 per month",
"£7,000+ per month",
],
)
Crt_barrel = models.IntegerField(
label='',
# In a lake, there is a patch of lily pads. Every day, the patch doubles in size. If it takes 48 days for the patch to cover the entire lake, how many days would it take for the patch to cover half of the lake?''',
)
Crt_student = models.IntegerField(
label='',
# In a lake, there is a patch of lily pads. Every day, the patch doubles in size. If it takes 48 days for the patch to cover the entire lake, how many days would it take for the patch to cover half of the lake?''',
)
Crt_pig = models.IntegerField(
label='',
# In a lake, there is a patch of lily pads. Every day, the patch doubles in size. If it takes 48 days for the patch to cover the entire lake, how many days would it take for the patch to cover half of the lake?''',
)
Crt_simon = models.IntegerField(
label='',
widget=widgets.RadioSelect,
choices= [
[0, "a atteint le seuil de rentabilité en bourse"],
[1, "a gagné de l'argent"],
[-1, "a perdu de l'argent"],
]
)
Know2 = models.IntegerField(
widget=widgets.RadioSelect,
choices=[
[1, "Oui"],
[0, "Non"],
],
label='',
# Have you ever seen or answered the previous set of questions?''',
# widget=widgets.RadioSelect()
)
# PAGES
class Choice(Page):
form_model = 'player'
form_fields = ['choice']
def is_displayed(player):
return player.round_number != C.NUM_ROUNDS
# def error_message(player, value):
# round_info = player.participant.vars['RoundDict'][player.round_number]
# print ("hello")
# if value['choice'] is None:
# return 'Please make a choice.'
def vars_for_template(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
L_1 = round_info['negative']['lottery']
L_2 = round_info['positive']['lottery']
left_value, right_value = "negative", "positive"
if round_info['position_neg'] == 0:
L_2 = round_info['negative']['lottery']
L_1 = round_info['positive']['lottery']
left_value, right_value = "positive", "negative"
position_a = round_info['position_a']
option_a, option_b = 0, 1
a_value, b_value = 'B', 'A'
if position_a == 1:
option_a, option_b = 1, 0
b_value, a_value = 'B', 'A'
fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1]
pp, oo_1_1, oo_2_1 = L_1[0], L_1[1], L_1[2]
pp, oo_1_2, oo_2_2 = L_2[0], L_2[1], L_2[2]
pp = probas(pp, sum(L_1[0]))
wheels_1 = ['wheels_yellow_1.png', 'wheels_yellow_2.png']
wheels_2 = ['wheels_orange_1.png', 'wheels_orange_2.png']
player.pos_a = round_info['position_a']
# player.state_order = str([oo_1, oo_2])
player.lottery_nr = round_info['lottery_nr']
player.type = round_info['type']
menu = round_info['menu']
display_left = 0
if round_info['position_neg'] == 1 and menu == "negative":
display_left = 1
if round_info['position_neg'] == 0 and menu == "positive":
display_left = 1
option_1, option_2 = "A", "B"
if display_left == 0:
option_1, option_2 = "C", "D"
return dict(
option_1=option_1,
option_2=option_2,
display_left=display_left,
fields=zip(fields_from, fields_to, pp),
fields_from=fields_from,
fields_to=fields_to,
option_a=option_a,
option_b=option_b,
position_a=position_a,
L_1=L_1,
round_number=player.round_number,
rows_1=zip(fields_from, fields_to, pp, oo_1_1, oo_2_1, wheels_1),
rows_2=zip(fields_from, fields_to, pp, oo_1_2, oo_2_2, wheels_2),
feedback=round_info['feedback'],
num_choice=player.round_number,
total_block=round_info['total_block'],
num_rep_learn=1,
blockround=round_info['blockround'],
pos_a=round_info['position_a'],
a_value=a_value,
b_value=b_value,
round_info=round_info,
disabled_b='',
table_width=60,
)
def before_next_page(player, timeout_happened):
player.participant.vars['RoundDict'][player.round_number]['choice'] = player.choice
if player.participant.vars['relevant'] == player.round_number:
player.participant.vars['RoundDict'][C.NUM_ROUNDS] = copy.deepcopy(player.participant.vars['RoundDict'][player.round_number])
player.participant.vars['RoundDict'][C.NUM_ROUNDS]['feedback'] = 1
class Menu(Page):
form_model = 'player'
form_fields = ['menu']
def is_displayed(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
return player.round_number != C.NUM_ROUNDS
def vars_for_template(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
L_1 = round_info['negative']['lottery']
L_2 = round_info['positive']['lottery']
left_value, right_value = "negative", "positive"
if round_info['position_neg'] == 0:
L_2 = round_info['negative']['lottery']
L_1 = round_info['positive']['lottery']
left_value, right_value = "positive", "negative"
position_a = round_info['position_a']
option_a, option_b = 0, 1
a_value, b_value = 'B', 'A'
if position_a == 1:
option_a, option_b = 1, 0
b_value, a_value = 'B', 'A'
fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1]
pp, oo_1_1, oo_2_1 = L_1[0], L_1[1], L_1[2]
pp, oo_1_2, oo_2_2 = L_2[0], L_2[1], L_2[2]
pp = probas(pp, sum(L_1[0]))
wheels_1 = ['wheels_yellow_1.png', 'wheels_yellow_2.png']
wheels_2 = ['wheels_orange_1.png', 'wheels_orange_2.png']
player.pos_a = round_info['position_a']
player.pos_neg = round_info['position_neg']
player.lottery_nr = round_info['lottery_nr']
player.type = round_info['type']
player.pi_pos = round_info['pi_pos']
player.pi_neg = round_info['pi_neg']
player.state_order = str([oo_1_1, oo_2_1, oo_1_2, oo_2_2])
disabled_a_1, disabled_b_1 = 'disabled', 'disabled'
disabled_a_2, disabled_b_2 = 'disabled', 'disabled'
# for screenshots
# oo_1 = [750, 750, 10, 10]
# oo_2 = [220, 220, 570, 570]
# oo_1 = [260, 260, 260, 260]
# oo_2 = [40, 40, 40, 40]
return dict(
left_value=left_value,
right_value=right_value,
fields=zip(fields_from, fields_to, pp),
fields_from=fields_from,
fields_to=fields_to,
option_a=option_a,
option_b=option_b,
position_a=position_a,
L_1=L_1,
round_number=player.round_number,
rows_1=zip(fields_from, fields_to, pp, oo_1_1, oo_2_1, wheels_1),
rows_2=zip(fields_from, fields_to, pp, oo_1_2, oo_2_2, wheels_2),
feedback=round_info['feedback'],
num_choice=player.round_number,
total_block=round_info['total_block'],
num_rep_learn=1,
blockround=round_info['blockround'],
pos_a=round_info['position_a'],
a_value=a_value,
b_value=b_value,
round_info=round_info,
disabled_a_1=disabled_a_1,
disabled_b_1=disabled_b_1,
disabled_a_2=disabled_a_2,
disabled_b_2=disabled_b_2,
table_width=80,
)
def before_next_page(player, timeout_happened):
player.participant.vars['RoundDict'][player.round_number]['menu'] = player.menu
class Feedback(Page):
def is_displayed(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
return round_info['feedback'] == 1
def vars_for_template(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
menu = round_info['menu']
L_1 = round_info['negative']['lottery']
L_2 = round_info['positive']['lottery']
left_value, right_value = "negative", "positive"
if round_info['position_neg'] == 0:
L_2 = round_info['negative']['lottery']
L_1 = round_info['positive']['lottery']
left_value, right_value = "positive", "negative"
position_a = round_info['position_a']
option_a, option_b = 0, 1
a_value, b_value = 'B', 'A'
if position_a == 1:
option_a, option_b = 1, 0
b_value, a_value = 'B', 'A'
fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1]
pp, oo_1_1, oo_2_1 = L_1[0], L_1[1], L_1[2]
pp, oo_1_2, oo_2_2 = L_2[0], L_2[1], L_2[2]
pp = probas(pp, sum(L_1[0]))
wheels_1 = ['wheels_yellow_1.png', 'wheels_yellow_2.png']
wheels_2 = ['wheels_orange_1.png', 'wheels_orange_2.png']
color_wheel = 'yellow'
menu = round_info['menu']
display_left = 0
if round_info['position_neg'] == 1 and menu == "negative":
display_left = 1
if round_info['position_neg'] == 0 and menu == "positive":
display_left = 1
color_1, color_2 = "green", "purple"
rows = zip(fields_from, fields_to, pp, oo_1_1, oo_2_1, wheels_1)
option_1, option_2 = "A", "B"
if display_left == 0:
color_wheel = 'orange'
option_1, option_2 = "C", "D"
color_1, color_2 = "blue", "darkred"
rows = zip(fields_from, fields_to, pp, oo_1_2, oo_2_2, wheels_2)
# # for hack
realized_field = round_info[menu]['realized_field']
if position_a == 1:
payoff_A = round_info[menu]['outcome_a']
payoff_B = round_info[menu]['outcome_b']
if position_a == 0:
payoff_B = round_info[menu]['outcome_a']
payoff_A = round_info[menu]['outcome_b']
player.realized = str([payoff_A, payoff_B])
choiceA = 0
P_choice = round_info['choice']
if P_choice == 'A':
choiceA = 1
if position_a == choiceA:
implemented_option = ' Option A'
checked_A = 'checked'
checked_B = ''
if position_a != choiceA:
implemented_option = ' Option B'
checked_B = 'checked'
checked_A = ''
choice = round_info['choice']
chosen_option = ' Option A'
if choice == "A" and position_a == 0:
chosen_option = ' Option B'
if choice == "B" and position_a == 1:
chosen_option = ' Option B'
if choice == "B"and position_a == 0:
chosen_option = ' Option A'
if display_left == 0:
if position_a == choiceA:
implemented_option = ' Option C'
checked_A = 'checked'
checked_B = ''
if position_a != choiceA:
implemented_option = ' Option D'
checked_B = 'checked'
checked_A = ''
choice = round_info['choice']
chosen_option = ' Option C'
if choice == "A" and position_a == 0:
chosen_option = ' Option D'
if choice == "B" and position_a == 1:
chosen_option = ' Option D'
if choice == "B" and position_a == 0:
chosen_option = ' Option C'
menu = round_info['menu']
payoff = 0
if player.round_number == C.NUM_ROUNDS:
if P_choice == 'A':
player.participant.vars['RoundDict'][C.NUM_ROUNDS]['payoff'] = round_info[menu]['outcome_a']
if P_choice == 'B':
player.participant.vars['RoundDict'][C.NUM_ROUNDS]['payoff'] = round_info[menu]['outcome_b']
player.payoff = player.participant.vars['RoundDict'][C.NUM_ROUNDS]['payoff']
payoff = player.participant.vars['RoundDict'][C.NUM_ROUNDS]['payoff']
return dict(
color_wheel=color_wheel,
color_1=color_1,
color_2=color_2,
option_1=option_1,
option_2=option_2,
round_info=round_info,
payoff=payoff,
L_1=L_1,
pp=pp,
fields=zip(fields_from, fields_to, pp),
fields_from=fields_from,
fields_to=fields_to,
chosen_option=chosen_option,
realized_field=realized_field,
checked_A=checked_A,
checked_B=checked_B,
payoff_A=payoff_A,
payoff_B=payoff_B,
round_number=player.round_number,
rows=rows,
)
class CE(Page):
form_model = 'player'
form_fields = ['ce_value']
def is_displayed(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
if player.round_number == C.NUM_ROUNDS:
return False
if player.round_number != C.NUM_ROUNDS:
return round_info['type'] == 'main'
def vars_for_template(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
L_1 = round_info['lottery']
position_a = round_info['position_a']
option_a, option_b = 0, 1
a_value, b_value = 'B', 'A'
if position_a == 1:
option_a, option_b = 1, 0
b_value, a_value = 'B', 'A'
fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1]
pp, oo_1, oo_2 = L_1[0], L_1[1], L_1[2]
pp = probas(pp, sum(L_1[0]))
wheels = ['wheels1v5.png', 'wheels2v5.png', 'wheels3v5.png', 'wheels4v5.png']
if len(oo_2) < 4:
wheels = ['wheels50_1.png', 'wheels50_2.png']
player.pos_a = round_info['position_a']
player.state_order = str([oo_1, oo_2])
player.lottery_nr = round_info['lottery_nr']
player.type = round_info['type']
# for screenshots
# oo_1 = [750, 750, 10, 10]
# oo_2 = [220, 220, 570, 570]
# oo_1 = [260, 260, 260, 260]
# oo_2 = [40, 40, 40, 40]
return dict(
oo_1=oo_1,
oo_2=oo_2,
fields=zip(fields_from, fields_to, pp),
fields_from=fields_from,
fields_to=fields_to,
option_a=option_a,
option_b=option_b,
position_a=position_a,
L_1=L_1,
round_number=player.round_number,
rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
feedback=round_info['feedback'],
num_choice=player.round_number,
total_block=round_info['total_block'],
num_rep_learn=1,
blockround=round_info['blockround'],
pos_a=round_info['position_a'],
a_value=a_value,
b_value=b_value,
round_info=round_info,
)
@staticmethod
def js_vars(player: Player):
return dict(
coarse_lower_bound=C.coarse_lower_bound,
coarse_upper_bound=C.coarse_upper_bound,
coarse_step_size=C.coarse_step_size,
fine_step_size=C.fine_step_size,
)
def before_next_page(player, timeout_happened):
player.participant.vars['RoundDict'][player.round_number]['CE'] = player.ce_value
if player.participant.vars['relevant'] == player.round_number:
player.participant.vars['RoundDict'][C.NUM_ROUNDS] = copy.deepcopy(player.participant.vars['RoundDict'][player.round_number])
grid = list(range(C.coarse_lower_bound, C.coarse_upper_bound + 1, C.fine_step_size))
random_value = random.choice(grid)
player.participant.vars['RoundDict'][C.NUM_ROUNDS]['random_value'] = random_value
if player.ce_value >= random_value:
player.participant.vars['RoundDict'][C.NUM_ROUNDS]['make_choice'] = 1
player.participant.vars['RoundDict'][C.NUM_ROUNDS]['feedback'] = 1
else:
player.participant.vars['RoundDict'][C.NUM_ROUNDS]['make_choice'] = 0
player.participant.vars['RoundDict'][C.NUM_ROUNDS]['feedback'] = 0
class Attention(Page):
form_model = 'player'
form_fields = ['attention']
def is_displayed(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
if player.round_number == C.NUM_ROUNDS:
return False
if round_info['blockround'] == C.N_main:
return True
def vars_for_template(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
L_1 = round_info['lottery']
position_a = round_info['position_a']
option_a, option_b = 0, 1
a_value, b_value = 'B', 'A'
if position_a == 1:
option_a, option_b = 1, 0
b_value, a_value = 'B', 'A'
fields_from, fields_to = fields(L_1[0])[0], fields(L_1[0])[1]
pp, oo_1, oo_2 = L_1[0], ["ML", "JZ"], ["SD", "FR"]
pp = probas(pp, sum(L_1[0]))
wheels = ['wheels1v5.png', 'wheels2v5.png', 'wheels3v5.png', 'wheels4v5.png']
if len(oo_2) < 4:
wheels = ['wheels50_1.png', 'wheels50_2.png']
# for screenshots
# oo_1 = [750, 750, 10, 10]
# oo_2 = [220, 220, 570, 570]
# oo_1 = [260, 260, 260, 260]
# oo_2 = [40, 40, 40, 40]
return dict(
oo_1=oo_1,
oo_2=oo_2,
fields=zip(fields_from, fields_to, pp),
fields_from=fields_from,
fields_to=fields_to,
option_a=option_a,
option_b=option_b,
position_a=position_a,
L_1=L_1,
round_number=player.round_number,
rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
feedback=round_info['feedback'],
num_choice=player.round_number,
total_block=round_info['total_block'],
num_rep_learn=1,
blockround=round_info['blockround'],
pos_a=round_info['position_a'],
a_value=a_value,
b_value=b_value,
round_info=round_info,
)
@staticmethod
def js_vars(player: Player):
return dict(
coarse_lower_bound=C.coarse_lower_bound,
coarse_upper_bound=C.coarse_upper_bound,
coarse_step_size=C.coarse_step_size,
fine_step_size=C.fine_step_size,
)
class onlyCE(Page):
form_model = 'player'
form_fields = ['ce_value']
@staticmethod
def js_vars(player: Player):
return dict(
coarse_lower_bound=C.coarse_lower_bound,
coarse_upper_bound=C.coarse_upper_bound,
coarse_step_size=C.coarse_step_size,
fine_step_size=C.fine_step_size,
)
class Instructions(Page):
form_model = 'player'
form_fields = ['test_1', 'test_2', 'test_3', 'test_4', 'evaluation_passed', 'ce_value']
def is_displayed(player):
return player.round_number == 1
def error_message(player, value):
if player.round_number != 1:
return None
if player.test_tries >= 2:
return None
if value['evaluation_passed'] == 1:
player.participant.vars['saved_eval'] = value['ce_value']
else:
player.participant.vars['saved_eval'] = None
if value['evaluation_passed'] != 1:
player.participant.vars['test_1'] = value['test_1']
player.participant.vars['test_2'] = value['test_2']
player.participant.vars['test_3'] = value['test_3']
player.participant.vars['test_4'] = value['test_4']
return 'You can proceed only after submitting a correct evaluation.'
if value['test_1'] is None or value['test_2'] is None or value['test_3'] is None or value['test_4'] is None:
player.participant.vars['errorX'] = 1
return 'Please answer all comprehension questions.'
# to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2"
else:
bb = value['test_1'] + value['test_2'] + value['test_3'] + value['test_4']
if bb != 4:
player.participant.vars['test_tries'] = player.participant.vars['test_tries'] + 1
player.test_tries = player.participant.vars['test_tries']
player.participant.vars['test_1'] = value['test_1']
player.participant.vars['test_2'] = value['test_2']
player.participant.vars['test_3'] = value['test_3']
player.participant.vars['test_4'] = value['test_4']
return "You answered at least one of the questions incorrectly. Please read the hints below and make sure you " \
"understand the task well."
def vars_for_template(player):
pp = (50, 50)
oo_1 = (40, 60)
oo_2 = (70, 150)
fields_from, fields_to = fields(pp)[0], fields(pp)[1]
wheels = ['wheels50_1.png', 'wheels50_2.png']
pp_2 = (50, 50)
oo_1_2 = (150, 30)
oo_2_2 = (50, 90)
fields_from_2, fields_to_2 = fields(pp_2)[0], fields(pp_2)[1]
error = 0
if player.participant.vars['test_tries'] > 0:
error = 1
if 'errorX' in player.participant.vars:
error = 1
player.test_tries = player.participant.vars['test_tries']
q2_pa_1, q2_pb_1 = oo_1_2[0], oo_2_2[0]
q2_pa_2, q2_pb_2 = oo_1_2[1], oo_2_2[1]
round_info = player.participant.vars['RoundDict'][player.round_number]
type = round_info['type']
pp_c = (50, 50)
oo_c_1 = (200, 40)
oo_c_2 = (70, 80)
oo_c_2_1 = oo_1_2
oo_c_2_2 = oo_2_2
return dict(
explain=zip(fields_from, fields_to, pp, oo_1, oo_2),
explain2=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2),
explain_c=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2),
explain_c2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2),
N_fields=sum(pp),
rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
rows2=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
rows4=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2, wheels),
rows_c_1=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2, wheels),
rows_c_2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2, wheels),
rows5=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
proba_A=50,
proba_B=50,
proba_A_2=50,
test_1=player.participant.vars['test_1'],
test_2=player.participant.vars['test_2'],
test_3=player.participant.vars['test_3'],
test_4=player.participant.vars['test_4'],
error=error,
type=type,
round_info=round_info,
total_block=player.participant.vars['RoundDict'][player.round_number+4]['total_block'],
a_value="disabled",
b_value="disabled",
)
@staticmethod
def js_vars(player: Player):
return dict(
coarse_lower_bound=C.coarse_lower_bound,
coarse_upper_bound=C.coarse_upper_bound,
coarse_step_size=C.coarse_step_size,
fine_step_size=C.fine_step_size,
target_value=C.target_value,
round_number=player.round_number,
saved_eval=player.participant.vars['saved_eval'],
)
class InstructionsCE(Page):
form_model = 'player'
form_fields = ['test_4', 'evaluation_passed', 'ce_value']
def is_displayed(player):
return player.round_number == 1
def error_message(player, value):
if player.round_number != 1:
return None
if player.test_tries >= 2:
return None
if value['evaluation_passed'] == 1:
player.participant.vars['saved_eval'] = value['ce_value']
else:
player.participant.vars['saved_eval'] = None
if value['evaluation_passed'] != 1:
player.participant.vars['test_4'] = value['test_4']
return 'You can proceed only after submitting a correct evaluation.'
if value['test_4'] is None:
player.participant.vars['errorX'] = 1
return 'Please answer all comprehension questions.'
# to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2"
else:
bb = value['test_4']
if bb != 1:
player.participant.vars['test_tries'] = player.participant.vars['test_tries'] + 1
player.test_tries = player.participant.vars['test_tries']
player.participant.vars['test_4'] = value['test_4']
return "You answered at least one of the questions incorrectly. Please read the hints below and make sure you " \
"understand the task well."
def vars_for_template(player):
pp = (50, 50)
oo_1 = (40, 60)
oo_2 = (70, 150)
fields_from, fields_to = fields(pp)[0], fields(pp)[1]
wheels = ['wheels50_1.png', 'wheels50_2.png']
pp_2 = (50, 50)
oo_1_2 = (150, 30)
oo_2_2 = (50, 90)
fields_from_2, fields_to_2 = fields(pp_2)[0], fields(pp_2)[1]
error = 0
if 'errorX' in player.participant.vars:
if player.participant.vars['errorX'] > 0:
error = 1
player.test_tries = player.participant.vars['test_tries']
q2_pa_1, q2_pb_1 = oo_1_2[0], oo_2_2[0]
q2_pa_2, q2_pb_2 = oo_1_2[1], oo_2_2[1]
round_info = player.participant.vars['RoundDict'][player.round_number]
type = round_info['type']
pp_c = (50, 50)
oo_c_1 = (200, 40)
oo_c_2 = (70, 80)
oo_c_2_1 = oo_1_2
oo_c_2_2 = oo_2_2
return dict(
explain=zip(fields_from, fields_to, pp, oo_1, oo_2),
explain2=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2),
explain_c=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2),
explain_c2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2),
N_fields=sum(pp),
rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
rows2=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
rows4=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2, wheels),
rows_c_1=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2, wheels),
rows_c_2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2, wheels),
rows5=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
proba_A=50,
proba_B=50,
proba_A_2=50,
test_1=player.participant.vars['test_1'],
test_2=player.participant.vars['test_2'],
test_3=player.participant.vars['test_3'],
test_4=player.participant.vars['test_4'],
error=error,
type=type,
round_info=round_info,
total_block=player.participant.vars['RoundDict'][player.round_number+4]['total_block'],
a_value="disabled",
b_value="disabled",
)
@staticmethod
def js_vars(player: Player):
return dict(
coarse_lower_bound=C.coarse_lower_bound,
coarse_upper_bound=C.coarse_upper_bound,
coarse_step_size=C.coarse_step_size,
fine_step_size=C.fine_step_size,
target_value=C.target_value,
round_number=player.round_number,
saved_eval=player.participant.vars['saved_eval'],
)
class InstructionsChoice(Page):
form_model = 'player'
form_fields = ['test_1', 'test_2', 'test_3']
def is_displayed(player):
return player.round_number == 1
def error_message(player, value):
if player.round_number != 1:
return None
if player.test_tries >= 2:
return None
if value['test_1'] is None or value['test_2'] is None or value['test_3'] is None:
player.participant.vars['errorX'] = 1
return 'Please answer all comprehension questions.'
# to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2"
else:
bb = value['test_1'] + value['test_2'] + value['test_3']
if bb != 3:
player.participant.vars['test_tries'] = player.participant.vars['test_tries'] + 1
player.test_tries = player.participant.vars['test_tries']
player.participant.vars['test_1'] = value['test_1']
player.participant.vars['test_2'] = value['test_2']
player.participant.vars['test_3'] = value['test_3']
return "You answered at least one of the questions incorrectly. Please read the hints below and make sure you " \
"understand the task well."
def vars_for_template(player):
pp = (50, 50)
oo_1 = (40, 60)
oo_2 = (70, 150)
fields_from, fields_to = fields(pp)[0], fields(pp)[1]
wheels = ['wheels_yellow_1.png', 'wheels_yellow_2.png']
pp_2 = (50, 50)
oo_1_2 = (150, 30)
oo_2_2 = (50, 90)
fields_from_2, fields_to_2 = fields(pp_2)[0], fields(pp_2)[1]
error = 0
if player.participant.vars['test_tries'] > 0:
error = 1
if 'errorX' in player.participant.vars:
error = 1
player.test_tries = player.participant.vars['test_tries']
q2_pa_1, q2_pb_1 = oo_1_2[0], oo_2_2[0]
q2_pa_2, q2_pb_2 = oo_1_2[1], oo_2_2[1]
round_info = player.participant.vars['RoundDict'][player.round_number]
type = round_info['type']
pp_c = (50, 50)
oo_c_1 = (200, 40)
oo_c_2 = (70, 80)
oo_c_2_1 = oo_1_2
oo_c_2_2 = oo_2_2
return dict(
explain=zip(fields_from, fields_to, pp, oo_1, oo_2),
explain2=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2),
explain_c=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2),
explain_c2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2),
N_fields=sum(pp),
rows=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
rows2=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
rows4=zip(fields_from_2, fields_to_2, pp_2, oo_1_2, oo_2_2, wheels),
rows_c_1=zip(fields_from, fields_to, pp_c, oo_c_1, oo_c_2, wheels),
rows_c_2=zip(fields_from, fields_to, pp_c, oo_c_2_1, oo_c_2_2, wheels),
rows5=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels),
proba_A=50,
proba_B=50,
proba_A_2=50,
test_1=player.participant.vars['test_1'],
test_2=player.participant.vars['test_2'],
test_3=player.participant.vars['test_3'],
test_4=player.participant.vars['test_4'],
error=error,
type=type,
round_info=round_info,
total_block=player.participant.vars['RoundDict'][player.round_number+4]['total_block'],
a_value="disabled",
b_value="disabled",
)
def before_next_page(player, timeout_happened):
player.participant.vars['errorX'] = 0
class InstructionsMenu(Page):
form_model = 'player'
form_fields = ['test_4']
def is_displayed(player):
if player.round_number==1:
if player.field_maybe_none("test_tries") >= 2:
return False
else:
return True
def error_message(player, value):
if player.round_number != 1:
return None
if player.test_tries >= 2:
return None
if value['test_4'] is None:
player.participant.vars['errorX'] = 1
return 'Please answer all comprehension questions.'
# to kick out people answering wrong more than 3 times add to conditions "and player.test_tries == 2"
bb = value['test_4']
if bb != 1:
player.participant.vars['test_tries'] = player.participant.vars['test_tries'] + 1
player.test_tries = player.participant.vars['test_tries']
player.participant.vars['errorX'] = 1
player.participant.vars['test_4'] = value['test_4']
return "You answered at least one of the questions incorrectly. Please read the hints below and make sure you " \
"understand the task well."
def vars_for_template(player):
pp = (50, 50)
oo_1 = (40, 60)
oo_2 = (70, 150)
fields_from, fields_to = fields(pp)[0], fields(pp)[1]
wheels_1 = ['wheels_yellow_1.png', 'wheels_yellow_2.png']
wheels_2 = ['wheels_orange_1.png', 'wheels_orange_2.png']
pp_2 = (50, 50)
oo_1_2 = (150, 30)
oo_2_2 = (50, 90)
fields_from_2, fields_to_2 = fields(pp_2)[0], fields(pp_2)[1]
error = 0
if 'errorX' in player.participant.vars:
if player.participant.vars['errorX'] > 0:
error = 1
player.test_tries = player.participant.vars['test_tries']
return dict(
table_width=80,
N_fields=sum(pp),
rows_1=zip(fields_from, fields_to, pp, oo_1, oo_2, wheels_1),
rows_2=zip(fields_from, fields_to, pp, oo_1_2, oo_2_2, wheels_2),
left_value="negative",
right_value="positive",
test_4=player.participant.vars['test_4'],
error=error,
)
class instructions_empty(Page):
def is_displayed(player):
return player.round_number == 1
class NewBlock(Page):
def is_displayed(player):
if player.round_number != 1 and player.round_number != C.NUM_ROUNDS:
round_info = player.participant.vars['RoundDict'][player.round_number]
return round_info['type'] == 'practice' and player.participant.vars['RoundDict'][player.round_number-1]['type'] == 'main'
else:
return False
class PayoffRelevant(Page):
def is_displayed(player):
if player.round_number != 1 and player.round_number != C.NUM_ROUNDS:
round_info = player.participant.vars['RoundDict'][player.round_number]
return round_info['type'] == 'main' and player.participant.vars['RoundDict'][player.round_number-1]['type'] == 'practice'
else:
return False
def vars_for_template(player):
image= "progress_choice.png"
return dict(
image=image,
N_blocks=2,
N_practive=4,
)
class kicked(Page):
def is_displayed(player: Player):
if player.round_number == 1 and player.field_maybe_none("test_tries") is not None:
return player.test_tries >= 2
else:
return False
class StartTask(Page):
def is_displayed(player):
return player.round_number == 1
def vars_for_template(player):
return dict(
image="progress_practice.png",
N_blocks=2,
N_practive=4,
)
class Transition2(Page):
timeout_seconds = 0.5
@staticmethod
def is_displayed(player):
round_info = player.participant.vars['RoundDict'][player.round_number]
if player.round_number == C.NUM_ROUNDS:
return False
else:
return round_info['type'] == 'main' and player.participant.vars['RoundDict'][player.round_number + 1]['type'] != 'practice' and player.round_number != C.NUM_ROUNDS-1
@staticmethod
def vars_for_template(player):
return dict(
message="Next evaluation task starting..."
)
class Transition(Page):
@staticmethod
def is_displayed(player):
if player.round_number >= C.NUM_ROUNDS:
return False
round_dict = player.participant.vars['RoundDict']
current_type = round_dict[player.round_number]['type']
next_type = round_dict[player.round_number + 1]['type']
return current_type == 'main' and next_type != 'practice'
@staticmethod
def vars_for_template(player):
return dict(
message="Next evaluation task starting..."
)
class Demographics(Page):
form_model = "player"
form_fields = [
"age",
"gender",
"education",
"country",
"employment",
"income",
]
def is_displayed(player):
return player.round_number == C.NUM_ROUNDS
class Cognitive2(Page):
form_model = 'player'
form_fields = ['Crt_barrel', 'Crt_student', 'Crt_pig', 'Crt_simon', 'Know2']
def is_displayed(player):
return player.round_number == C.NUM_ROUNDS
class Introduction(Page):
def is_displayed(player: Player):
return player.round_number == 1
class End(Page):
def is_displayed(player: Player):
return player.round_number == C.NUM_ROUNDS
class StartSurvey(Page):
def is_displayed(player: Player):
return player.round_number == C.NUM_ROUNDS
page_sequence = [StartSurvey, Cognitive2, Demographics, Introduction, InstructionsChoice, InstructionsMenu, kicked, StartTask, PayoffRelevant, Menu, Choice, Feedback, End]