from otree.api import * from decimal import Decimal class C(BaseConstants): NAME_IN_URL = 'hl_task' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 HL_OPTION_A_HIGH = [Decimal('2.00')] * 10 HL_OPTION_A_LOW = [Decimal('1.60')] * 10 HL_OPTION_B_HIGH = [Decimal('3.85')] * 10 HL_OPTION_B_LOW = [Decimal('0.10')] * 10 PROB_HIGH = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): HL_choice_1 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_2 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_3 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_4 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_5 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_6 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_7 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_8 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_9 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") HL_choice_10 = models.StringField(choices=[['A', 'Option A'], ['B', 'Option B']], widget=widgets.RadioSelect, label="") # Kept for data analysis only – not used for payment HL_num_safe_choices = models.IntegerField() risk_aversion = models.IntegerField( choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], min=1, max=10, label='', widget=widgets.RadioSelectHorizontal, ) def get_choice(player, decision_number): return getattr(player, f'HL_choice_{decision_number}') def count_safe_choices(player): player.HL_num_safe_choices = sum( 1 for i in range(1, 11) if get_choice(player, i) == 'A' ) #PAGES class HL_Instructions(Page): pass class HL_Task(Page): form_model = 'player' form_fields = [f'HL_choice_{i}' for i in range(1, 11)] @staticmethod def error_message(player, values): lang = getattr(player.participant, 'language', 'de') for i in range(1, 11): if not values.get(f'HL_choice_{i}'): if lang == 'en': return f'Please make a choice for all 10 decisions. Decision {i} is still missing.' else: return f'Bitte treffen Sie eine Wahl für alle 10 Entscheidungen. Entscheidung {i} fehlt noch.' @staticmethod def vars_for_template(player: Player): lotteries = [] for i in range(10): prob_high = C.PROB_HIGH[i] lotteries.append({ 'decision': i + 1, 'prob_high': prob_high, 'prob_low': 10 - prob_high, 'prob_low_start': prob_high + 1, 'option_a_high': C.HL_OPTION_A_HIGH[i], 'option_a_low': C.HL_OPTION_A_LOW[i], 'option_b_high': C.HL_OPTION_B_HIGH[i], 'option_b_low': C.HL_OPTION_B_LOW[i], 'field_name': f'HL_choice_{i + 1}', }) return dict(lotteries=lotteries) @staticmethod def before_next_page(player: Player, timeout_happened): count_safe_choices(player) class RiskQuestion(Page): form_model = 'player' form_fields = ['risk_aversion'] page_sequence = [HL_Instructions, HL_Task, RiskQuestion]