first commit
This commit is contained in:
commit
73fc2121bf
30 changed files with 13308 additions and 0 deletions
313
Task1/__init__.py
Normal file
313
Task1/__init__.py
Normal file
|
|
@ -0,0 +1,313 @@
|
|||
from otree.api import *
|
||||
import random
|
||||
import math
|
||||
import json
|
||||
import numpy as np
|
||||
import random
|
||||
import itertools
|
||||
|
||||
|
||||
doc = """Template"""
|
||||
|
||||
class C(BaseConstants):
|
||||
NAME_IN_URL = 'Decision'
|
||||
PLAYERS_PER_GROUP = None
|
||||
|
||||
# Rounds
|
||||
NUM_PRACTICE_ROUNDS = 2
|
||||
NUM_PAYMENT_ROUNDS = 3
|
||||
NUM_ROUNDS = NUM_PRACTICE_ROUNDS + NUM_PAYMENT_ROUNDS
|
||||
|
||||
# Captchas
|
||||
max_captcha_time = 60
|
||||
captcha_rounds = [1, 2, ] # The rounds in which captchas occur
|
||||
captcha_text = ["bonus", "payment", ] # The text the participants need to input (can use upper or lowercase)
|
||||
|
||||
treatments_between_list = [0, 1]
|
||||
cost_list = [5, 15, 25, 35, 45, 55, 65, 75, 85, 95]
|
||||
value_list = [10, 30, 50, 70, 90]
|
||||
payoffs_list = []
|
||||
for cost in cost_list:
|
||||
for value in value_list:
|
||||
payoffs_list.append([value, cost])
|
||||
|
||||
|
||||
|
||||
|
||||
class Subsession(BaseSubsession):
|
||||
pass
|
||||
|
||||
|
||||
class Group(BaseGroup):
|
||||
pass
|
||||
|
||||
|
||||
class Player(BasePlayer):
|
||||
practice = models.IntegerField()
|
||||
player_round = models.IntegerField()
|
||||
|
||||
decision = models.IntegerField()
|
||||
belief_1 = models.FloatField(min=0, max=100)
|
||||
|
||||
# Between-Participant Treatment
|
||||
treatment_between = models.IntegerField()
|
||||
|
||||
# Within-Participant Treatment
|
||||
treatment_index_within = models.IntegerField()
|
||||
value = models.FloatField()
|
||||
cost = models.FloatField()
|
||||
|
||||
# Time fields
|
||||
time_spent = models.IntegerField()
|
||||
time_spent_instructions = models.IntegerField()
|
||||
|
||||
# Captcha
|
||||
captcha_attempt_1 = models.StringField(label="", initial="")
|
||||
captcha_attempt_2 = models.StringField(label="", initial="")
|
||||
captcha_attempt_3 = models.StringField(label="", initial="")
|
||||
|
||||
# Instructions
|
||||
incorrect_instruction_answers = models.StringField(blank=True)
|
||||
errors_quiz = models.IntegerField()
|
||||
|
||||
instructions_clicked = models.BooleanField()
|
||||
|
||||
prolific_id = models.StringField(default=str(" "))
|
||||
|
||||
|
||||
|
||||
# FUNCTIONS
|
||||
def creating_session(subsession: Subsession):
|
||||
# Between-participant treatment
|
||||
# Extend between treatment list * Total participants in session /2 /Nr Between treatments and shuffle
|
||||
total_number_participants = 10 # max([1,math.floor(len(player.session.get_participants())/2/len(C.treatments_between_list))])
|
||||
between_treatment_list_shuffled = C.treatments_between_list * total_number_participants
|
||||
random.shuffle(between_treatment_list_shuffled)
|
||||
|
||||
# Within-participant treatment
|
||||
reps = len(C.payoffs_list) // C.NUM_PAYMENT_ROUNDS
|
||||
remainder = len(C.payoffs_list) % C.NUM_PAYMENT_ROUNDS
|
||||
|
||||
for player in subsession.get_players():
|
||||
|
||||
player.prolific_id = player.participant.label
|
||||
player.player_round = player.round_number
|
||||
|
||||
player.participant.vars['failed_captcha'] = False
|
||||
|
||||
# Between-participant treatment assignment
|
||||
player.treatment_between = between_treatment_list_shuffled[len(between_treatment_list_shuffled) % player.participant.id_in_session-1]
|
||||
|
||||
if player.round_number == 1:
|
||||
# Within-participant treatment assignment
|
||||
treatments_indices_within = list(range(len(C.payoffs_list))) * reps
|
||||
remaining_treatments = list(range(len(C.payoffs_list)))
|
||||
random.shuffle(remaining_treatments)
|
||||
treatments_indices_within = treatments_indices_within + remaining_treatments[:remainder]
|
||||
random.shuffle(treatments_indices_within)
|
||||
for r in range(C.NUM_PAYMENT_ROUNDS):
|
||||
player.in_round(C.NUM_PRACTICE_ROUNDS+1+r).treatment_index_within = treatments_indices_within[r]
|
||||
|
||||
if player.player_round <= C.NUM_PRACTICE_ROUNDS:
|
||||
player.practice = 1
|
||||
player.value = random.choice(C.value_list)
|
||||
player.cost = np.round(random.choice(C.cost_list)+10*(random.random()-.5),1)
|
||||
if player.player_round > C.NUM_PRACTICE_ROUNDS:
|
||||
player.practice = 0
|
||||
player.value = C.payoffs_list[player.treatment_index_within][0]
|
||||
player.cost = np.round(C.payoffs_list[player.treatment_index_within][1]+10*(random.random()-.5),1)
|
||||
|
||||
|
||||
|
||||
# PAGES
|
||||
class Instructions(Page):
|
||||
form_model = 'player'
|
||||
form_fields = ['incorrect_instruction_answers', 'errors_quiz', 'time_spent_instructions',]
|
||||
|
||||
@staticmethod
|
||||
def is_displayed(player):
|
||||
return player.round_number == 1
|
||||
|
||||
@staticmethod
|
||||
def vars_for_template(player: Player):
|
||||
return dict(
|
||||
participation_fee=player.session.config['participation_fee'],
|
||||
min_bonus_payment=player.session.config['min_bonus_payment'],
|
||||
max_bonus_payment=player.session.config['max_bonus_payment'],
|
||||
min_payment=player.session.config['min_payment'],
|
||||
max_payment=player.session.config['max_payment'],
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def before_next_page(player, timeout_happened):
|
||||
player.incorrect_instruction_answers = player.field_maybe_none('incorrect_instruction_answers')
|
||||
|
||||
|
||||
class TaskIntro(Page):
|
||||
@staticmethod
|
||||
def is_displayed(player):
|
||||
return (
|
||||
player.round_number in [1,C.NUM_PRACTICE_ROUNDS+1] and
|
||||
not player.participant.vars.get('failed_captcha', False)
|
||||
)
|
||||
|
||||
|
||||
class Task(Page):
|
||||
form_model = 'player'
|
||||
form_fields = ['decision','belief_1','time_spent',]
|
||||
|
||||
@staticmethod
|
||||
def is_displayed(player):
|
||||
return (
|
||||
not player.participant.vars.get('failed_captcha', False)
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def vars_for_template(player):
|
||||
return dict(
|
||||
payment_round_number = player.round_number-C.NUM_PRACTICE_ROUNDS,
|
||||
practice_round_number = player.round_number,
|
||||
round_number = player.round_number,
|
||||
)
|
||||
|
||||
class TaskFeedback(Page):
|
||||
@staticmethod
|
||||
def is_displayed(player):
|
||||
return (
|
||||
player.round_number <= C.NUM_PRACTICE_ROUNDS and
|
||||
not player.participant.vars.get('failed_captcha', False)
|
||||
)
|
||||
@staticmethod
|
||||
def vars_for_template(player):
|
||||
return dict(
|
||||
payment_round_number = player.round_number-C.NUM_PRACTICE_ROUNDS,
|
||||
practice_round_number = player.round_number,
|
||||
round_number = player.round_number,
|
||||
belief_A = player.belief_1,
|
||||
belief_B = 100-player.belief_1,
|
||||
paymentbelief_A = 2*player.belief_1-player.belief_1**2/100,
|
||||
paymentbelief_B = 100-player.belief_1**2/100,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def js_vars(player):
|
||||
return dict(
|
||||
decision = player.decision,
|
||||
belief_1 = player.belief_1,
|
||||
)
|
||||
|
||||
|
||||
|
||||
class CaptchaFailed(Page):
|
||||
@staticmethod
|
||||
def is_displayed(player):
|
||||
return (
|
||||
player.participant.vars.get('failed_captcha', True)
|
||||
)
|
||||
|
||||
class Captcha1(Page):
|
||||
template_name = 'Task1/Captcha.html'
|
||||
form_model = 'player'
|
||||
form_fields = ['captcha_attempt_1']
|
||||
|
||||
@staticmethod
|
||||
def is_displayed(player):
|
||||
if not (
|
||||
player.round_number in C.captcha_rounds
|
||||
and not player.participant.vars.get('failed_captcha', False)
|
||||
and player.subsession.session.config['use_captchas'] == 1
|
||||
):
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def vars_for_template(player):
|
||||
max_captcha_time = C.max_captcha_time
|
||||
return {
|
||||
'image_path': "images/captchas/captcha{}.png".format(C.captcha_rounds.index(player.round_number) + 1),
|
||||
'attempt': 1,
|
||||
'max_captcha_time': max_captcha_time,
|
||||
}
|
||||
|
||||
|
||||
class Captcha2(Page):
|
||||
template_name = 'Task1/Captcha.html'
|
||||
form_model = 'player'
|
||||
form_fields = ['captcha_attempt_2']
|
||||
|
||||
@staticmethod
|
||||
def is_displayed(player):
|
||||
if not (
|
||||
player.round_number in C.captcha_rounds
|
||||
and not player.participant.vars.get('failed_captcha', False)
|
||||
and player.subsession.session.config['use_captchas'] == 1
|
||||
):
|
||||
return False
|
||||
else:
|
||||
return player.captcha_attempt_1.lower() != C.captcha_text[C.captcha_rounds.index(player.round_number)].lower()
|
||||
|
||||
@staticmethod
|
||||
def vars_for_template(player):
|
||||
max_captcha_time = C.max_captcha_time
|
||||
return {
|
||||
'image_path': "images/captchas/captcha{}.png".format(C.captcha_rounds.index(player.round_number) + 1),
|
||||
'attempt': 2,
|
||||
'max_captcha_time': max_captcha_time,
|
||||
}
|
||||
|
||||
|
||||
class Captcha3(Page):
|
||||
template_name = 'Task1/Captcha.html'
|
||||
form_model = 'player'
|
||||
form_fields = ['captcha_attempt_3']
|
||||
|
||||
@staticmethod
|
||||
def is_displayed(player):
|
||||
if not (
|
||||
player.round_number in C.captcha_rounds
|
||||
and not player.participant.vars.get('failed_captcha', False)
|
||||
and player.subsession.session.config['use_captchas'] == 1
|
||||
):
|
||||
return False
|
||||
else:
|
||||
return (
|
||||
player.captcha_attempt_1.lower() != C.captcha_text[
|
||||
C.captcha_rounds.index(player.round_number)
|
||||
].lower()
|
||||
and player.captcha_attempt_2.lower() != C.captcha_text[
|
||||
C.captcha_rounds.index(player.round_number)
|
||||
].lower()
|
||||
)
|
||||
@staticmethod
|
||||
def vars_for_template(player):
|
||||
max_captcha_time = C.max_captcha_time
|
||||
return {
|
||||
'image_path': "images/captchas/captcha{}.png".format(C.captcha_rounds.index(player.round_number) + 1),
|
||||
'attempt': 3,
|
||||
'max_captcha_time': max_captcha_time,
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
def before_next_page(player, timeout_happened):
|
||||
correct_text = C.captcha_text[C.captcha_rounds.index(player.round_number)].lower()
|
||||
if (
|
||||
player.round_number in C.captcha_rounds
|
||||
and player.captcha_attempt_1.lower() != correct_text
|
||||
and player.captcha_attempt_2.lower() != correct_text
|
||||
and player.captcha_attempt_3.lower() != correct_text
|
||||
):
|
||||
player.participant.vars['failed_captcha'] = True
|
||||
|
||||
|
||||
# Update page_sequence
|
||||
page_sequence = [
|
||||
Instructions,
|
||||
Captcha1,
|
||||
Captcha2,
|
||||
Captcha3,
|
||||
CaptchaFailed,
|
||||
TaskIntro,
|
||||
Task,
|
||||
TaskFeedback,
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue