from otree.api import *
import random
import time
doc = """
Your app description
"""
class C(BaseConstants):
NAME_IN_URL = 'strategymethod'
PLAYERS_PER_GROUP = None
NUM_ROUNDS = 1
r_min = 0
N_size = 4 # this is the sample size
P_yellow = [0.60, 0.40] # yellow and green box respectively
p_yellow_Yellow = int(P_yellow[0]*100)
p_yellow_Green = int(P_yellow[1]*100)
P_Yellow_Box = 0.90
P_Yellow_Other = 0.20
prob_y = int(P_yellow[0] * 100)
prob_g = int(P_yellow[1] * 100)
class Subsession(BaseSubsession):
pass
class Group(BaseGroup):
pass
class Player(BasePlayer):
rand_box = models.FloatField()
round_yellow_n = models.IntegerField()
round_green_n = models.IntegerField()
report = models.IntegerField(min=0,
max=100)
report_other = models.IntegerField(min=0,
max=100)
round_payoff = models.IntegerField(initial=0)
payoff_final = models.CurrencyField(initial=0)
# Questions to check understanding
n_balls = models.IntegerField(
label='How many balls does each box have?',
min=0, max=100)
p1_g_Y = models.IntegerField(
label='What is the probability that one green marble is drawn '
'if the box is Yellow? '
'Answer in percentage points.',
min=0, max=100)
seq_length = models.IntegerField(
label='How many marbles will be drawn from the box at the end of the section?',
min=0, max=100)
replacement = models.BooleanField(
label='When generating a sample, is each marble returned to the Box after each draw?',
choices=[
[False, 'No'],
[True, 'Yes'],
]
)
hidden_box = models.BooleanField(
label='Will you know the probability each Box is selected for you?',
choices=[
[False, 'No'],
[True, 'Yes'],
]
)
hidden_box_other = models.BooleanField(
label='Will you know the probability each Box is selected for Participant 2?',
choices=[
[False, 'No'],
[True, 'Yes'],
]
)
## Count the number of wrong answers
wrong_answer_n_balls = models.IntegerField(initial=0)
wrong_answer_p1_g_Y = models.IntegerField(initial=0)
wrong_answer_seq_length = models.IntegerField(initial=0)
wrong_answer_replacement = models.IntegerField(initial=0)
wrong_answer_hidden_box = models.IntegerField(initial=0)
wrong_answer_hidden_box_other = models.IntegerField(initial=0)
## time
time_wait = models.IntegerField()
time_instructions = models.IntegerField()
time_test = models.IntegerField()
time_payment = models.IntegerField()
time_end_instructions = models.IntegerField()
# FUNCTIONS
def n_balls_error_message(player, value):
print('value is', value)
if value < player.session.config['n_marbles']:
player.wrong_answer_n_balls += 1
return 'There are more balls in the box.'
if value > player.session.config['n_marbles']:
player.wrong_answer_n_balls += 1
return 'There are less balls in the box.'
def p1_g_Y_error_message(player, value):
print('value is', value)
if value < (100-C.p_yellow_Yellow):
player.wrong_answer_p1_g_Y += 1
return 'The probability is larger.'
if value > (100-C.p_yellow_Yellow):
player.wrong_answer_p1_g_Y += 1
return 'The probability is smaller.'
def seq_length_error_message(player, value):
print('value is', value)
if value < C.N_size:
player.wrong_answer_seq_length += 1
return 'There will be more balls drawn.'
if value > C.N_size:
player.wrong_answer_seq_length += 1
return 'There will be less balls drawn.'
def replacement_error_message(player, value):
print('value is', value)
if value != True:
player.wrong_answer_replacement += 1
return 'The marble is returned to the original Box.'
def hidden_box_error_message(player, value):
print('value is', value)
if value != True:
player.wrong_answer_hidden_box += 1
return 'You will know the probability the Yellow box will be selected for you.'
def hidden_box_other_error_message(player, value):
print('value is', value)
if value != True:
player.wrong_answer_hidden_box_other += 1
return 'You will know the probability the Yellow box will be selected for you and Participant 2.'
# PAGES
class Wait_Instructions(Page):
@staticmethod
def before_next_page(player: Player, timeout_happened):
player.time_wait = int(time.time())
class General(Page):
pass
class BoxesMarblesSequences(Page):
form_model = 'player'
@staticmethod
def before_next_page(player: Player, timeout_happened):
player.rand_box = random.choices(C.P_yellow, k=1, weights=[C.P_Yellow_Box, 1 - C.P_Yellow_Box])[0]
marble_sample = random.choices([0, 1], k=C.N_size, weights=[1 - player.rand_box, player.rand_box])
yellow_n = sum(marble_sample)
player.round_yellow_n = yellow_n
player.round_green_n = C.N_size - yellow_n
class Sequences(Page):
form_model = 'player'
@staticmethod
def js_vars(player):
# this function generates the sequence of marbles to be pass to JS
rand_seq = [1] * player.round_yellow_n + [0] * player.round_green_n
# random.shuffle(rand_seq) # This code is if the sequence shown is random
return dict(
marble_sample=rand_seq,
N=C.N_size
)
@staticmethod
def before_next_page(player: Player, timeout_happened):
player.time_instructions = int(time.time())
class TestGral(Page):
form_model = 'player'
form_fields = [
'n_balls',
'p1_g_Y',
'seq_length',
'replacement',
'hidden_box',
'hidden_box_other',
]
@staticmethod
def before_next_page(player: Player, timeout_happened):
player.time_test = int(time.time())
class PaymentInfo(Page):
@staticmethod
def before_next_page(player: Player, timeout_happened):
player.time_payment = int(time.time())
class Summary(Page):
@staticmethod
def before_next_page(player: Player, timeout_happened):
player.time_end_instructions = int(time.time())
page_sequence = [
Wait_Instructions,
General,
BoxesMarblesSequences,
Sequences,
TestGral,
PaymentInfo,
]