from otree.api import * c = cu doc = '' #Class Creation class C(BaseConstants): NAME_IN_URL = 'Intro' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 TOTAL_EARNINGS_WIN = 35 TOTAL_EARNINGS_LOSE = 25 #Set task parameters sliders_task_pms = dict( time_in_seconds=10, num=120, columns=3, max=100, min=0, target=50, default='min', # Sliders default value when the task begin ret_score=0, bonus_per_slider=cu(1), bonus=cu(0) ) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): ret_score = models.IntegerField(initial=0) #KC Questions KC1 = models.StringField(choices=[['True', 'True'], ['False', 'False']], label='1.\tYou will work as an employee for BMS, Inc. for 5 rounds.', widget=widgets.RadioSelect) KC2 = models.StringField(choices=[['$10', '$10'], ['$20', '$20']], label='3.\tAs an employee of BMS, Inc., how much will you earn as a fixed wage in each ' 'round?', widget=widgets.RadioSelect) KC3 = models.StringField(choices=[['True', 'True'], ['False', 'False']], label='4.\tAs an employee of BMS, Inc., will you be matched with another randomly selected ' 'employee each round.', widget=widgets.RadioSelect) KC4a = models.StringField(choices=[['$15', '$15'], ['$25', '$25']], label='5.\tWhat bonus will you earn if you correctly position more sliders than the ' 'employee with which you are paired in the randomly selected round?', widget=widgets.RadioSelect) KC4b = models.StringField(choices=[['$15 gift card', '$15 gift card'], ['$25 gift card', '$25 gift card']], label='5.\tWhat bonus will you earn if you correctly position more sliders than the ' 'employee with which you are paired in the randomly selected round?', widget=widgets.RadioSelect) KC5a = models.StringField(choices=[['$5', '$5'], ['$15', '$15']], label='6.\tWhat bonus will you earn if you correctly position fewer sliders than the ' 'employee with which you are paired in the randomly selected round?', widget=widgets.RadioSelect) KC5b = models.StringField(choices=[['$5 gift card', '$5 gift card'], ['$15 gift card', '$15 gift card']], label='6.\tWhat bonus will you earn if you correctly position fewer sliders than the ' 'employee with which you are paired in the randomly selected round?', widget=widgets.RadioSelect) #Function Building def creating_session(subsession: Subsession): import random config = subsession.session.config session = subsession.session session.bonus_win = C.TOTAL_EARNINGS_WIN - config['participation_fee'] session.bonus_lose = C.TOTAL_EARNINGS_LOSE - config['participation_fee'] session.round_for_pay = random.randint(1, C.NUM_ROUNDS) def set_chunks(l, n): for i in range(0, len(l), n): yield l[i:i + n] def set_sliders_task(const: C): from random import randint, choice # Copy task parameters from C (which therefore will remain unchanged) task = const.sliders_task_pms.copy() # Set random value for left margin of sliders in each row offsets = [randint(0, 10) for _ in range(task['num'] // task['columns'])] # Set default values of sliders: either to "min" or to random values if task['default'] == 'min': m = task['min'] curr_values = [m for _ in range(task['num'])] else: input_range = list(range(task['min'], task['max'])) input_range.remove(task['target']) curr_values = [choice(input_range) for _ in range(task['num'])] # Set list of rows containing the sliders: each row contains 3 sliders and the left margin for that row sliders = list(zip(set_chunks(curr_values, task['columns']), offsets)) # Flag task as set task_set = True # Update dictionary containing task parameters task.update(offsets=offsets, curr_values=curr_values, sliders=sliders) return task_set, task #Pages class GenInstructions(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class TaskInstructions(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class PracticeInstructions(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class PracticeRound(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 timeout_seconds = C.sliders_task_pms['time_in_seconds'] timer_text = 'Remaining time: ' @staticmethod def vars_for_template(player: Player): pvars = player.participant.vars pvars['sliders_task_set'], pvars['sliders_task'] = set_sliders_task(C) # Returns the dictionary containing the task parameters as variables for the template return pvars['sliders_task'] @staticmethod def js_vars(player: Player): return player.participant.vars['sliders_task'] @staticmethod def live_method(player: Player, data): participant = player.participant # Get task parameters task = participant.vars['sliders_task'] # Get updated number of centered sliders player.ret_score = len([v for v in data if v == task['target']]) # Update task parameters based on: current values of the sliders, number of centered sliders, bonus accumulated task.update( sliders=list(zip(set_chunks(data, task['columns']), task['offsets'])), ret_score=player.ret_score, bonus=player.ret_score * task['bonus_per_slider'] ) # Send updated task's parameters to the webpage return {player.id_in_group: dict(ret_score=player.ret_score, bonus=task['bonus'])} # Set participant field with number of centered sliders @staticmethod def before_next_page(player: Player, timeout_happened): player.ret_score = player.participant.vars['sliders_task']['ret_score'] class PracticeEnd(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Setting1(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class Setting2(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class KC(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): return player.round_number == 1 @staticmethod def get_form_fields(player: Player): session = player.session if session.config['cash_payment']: return ['KC1', 'KC2', 'KC3', 'KC4a', 'KC5a'] else: return ['KC1', 'KC2', 'KC3', 'KC4b', 'KC5b'] @staticmethod def error_message(player: Player, values): session = player.session if session.config['cash_payment'] and session.config['participation_fee'] == 10: solutions = dict( KC1='True', KC2='$10', KC3='True', KC4a='$25', KC5a='$15' ) error_msg = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_msg[field_name] = 'Incorrect. Please select another answer.' return error_msg if session.config['cash_payment'] and session.config['participation_fee'] == 20: solutions = dict( KC1='True', KC2='$20', KC3='True', KC4a='$15', KC5a='$5' ) error_msg = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_msg[field_name] = 'Incorrect. Please select another answer.' return error_msg if session.config['cash_payment'] == False and session.config['participation_fee'] == 10: solutions = dict( KC1='True', KC2='$10', KC3='True', KC4b='$25 gift card', KC5b='$15 gift card', ) error_msg = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_msg[field_name] = 'Incorrect. Please select another answer.' return error_msg if session.config['cash_payment'] == False and session.config['participation_fee'] == 20: solutions = dict( KC1='True', KC2='$20', KC3='True', KC4b='$15 gift card', KC5b='$5 gift card', ) error_msg = dict() for field_name in solutions: if values[field_name] != solutions[field_name]: error_msg[field_name] = 'Incorrect. Please select another answer.' return error_msg page_sequence = [ GenInstructions, TaskInstructions, PracticeInstructions, PracticeRound, PracticeEnd, Setting1, Setting2, KC, ]