from otree.api import * c = cu doc = '' class C(BaseConstants): NAME_IN_URL = 'blood_measurement_eng' PLAYERS_PER_GROUP = None NUM_ROUNDS = 100 CHECK_PAYOFF = -1 CONT_PAYOFF = 0 DIS_PAYOFF = -10 ZERO_CONSTANT = 0 HIGH_VAL_FRAQ = 0.2 LOW_VAL_MIN = 70 LOW_VAL_MAX = 80 HIGH_VAL_MIN = 80 HIGH_VAL_MAX = 95 ERR_VAL_MIN = -10 ERR_VAL_MAX = 10 LONG_RANGE_LOSS = 10 LONG_RANGE_PROB = 3 START_SUM = 1000 COIN = (1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1) class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): session = subsession.session import random '''coinVal = random.random() if (coinVal >= C.HIGH_VAL_FRAQ): coin = 1 else: coin = 0 ''' coin = C.COIN[subsession.round_number - 1] players = subsession.get_players() for player in players: if (coin == 1): player.shown_value = random.randint(C.LOW_VAL_MIN,C.LOW_VAL_MAX) else: player.shown_value = random.randint(C.HIGH_VAL_MIN,C.HIGH_VAL_MAX) player.real_value = player.shown_value + random.randint(C.ERR_VAL_MIN,C.ERR_VAL_MAX) Subsession.creating_session = creating_session class Group(BaseGroup): pass class Player(BasePlayer): check_value = models.BooleanField() player_gender = models.StringField(choices=[['Male', 'Male'], ['Female', 'Female'], ['None', 'I do not want to respond']], label='Gender', widget=widgets.RadioSelectHorizontal) player_age = models.IntegerField(choices=[[18, '18'], [19, '19'], [20, '20'], [21, '21'], [22, '22'], [23, '23'], [24, '24'], [25, '25'], [26, '26'], [27, '27'], [28, '28'], [29, '29'], [30, '30'], [31, '31'], [32, '32'], [33, '33'], [34, '34'], [35, '35'], [36, '36'], [37, '37'], [38, '38'], [39, '39'], [40, '40'], [41, '41'], [42, '42'], [43, '43'], [45, '45'], [46, '46'], [47, '47'], [48, '48'], [49, '49'], [50, '50'], [51, '51'], [52, '52'], [53, '53'], [54, '54'], [55, '55'], [56, '56'], [57, '57'], [58, '58'], [59, '59'], [60, '60'], [61, '61'], [62, '62'], [63, '63'], [64, '64'], [65, '65'], [67, '67'], [68, '68'], [69, '69'], [70, '70'], [71, '71'], [72, '72'], [73, '73'], [74, '74'], [75, '75'], [76, '76'], [77, '77'], [78, '78'], [79, '79'], [80, '80'], [81, '81'], [82, '82'], [83, '83'], [84, '84'], [85, '85'], [86, '86'], [87, '87'], [88, '88'], [89, '89'], [90, '90'], [91, '91'], [92, '92'], [93, '93'], [94, '94'], [95, '95'], [96, '96'], [97, '97'], [98, '98'], [99, '99']], label='Age') real_value = models.FloatField() shown_value = models.FloatField() player_accepted = models.BooleanField(choices=[[True, 'I agree to participate in this study and am ready for the results of my experiment to be used for research purposes only.'], [False, 'I do not agree to participate in this study.']], label='', widget=widgets.RadioSelectHorizontal) player_diabetic = models.BooleanField(choices=[[True, 'Yes'], [False, 'No']], label='Are you type I Diabetic?', widget=widgets.RadioSelectHorizontal) player_sport_active = models.IntegerField(choices=[[0, '0'], [1, '1'], [2, '2'], [3, '3'], [4, '4'], [5, '5'], [6, '6'], [7, '7']], label='How many times a week do you exercise?') player_uses_cgm = models.IntegerField(choices=[[0, 'Yes'], [1, 'No'], [2, 'Irrelevant']], label='If so, do you use a CGM (Continuous Glucose Monitor)?', widget=widgets.RadioSelectHorizontal) long = models.IntegerField(initial=0) long_loss = models.FloatField(initial=0) diab_version = models.BooleanField(initial=False) player_cgm_model = models.StringField(blank=True, label='If so, which device do you use to measure blood glucose levels? ') mail_field = models.StringField(label='') all_time_payoff = models.FloatField(initial=0) bonus_choice = models.IntegerField(initial=0) bonus_thresh = models.FloatField() bonus_won = models.BooleanField(initial=False) class Introduction(Page): form_model = 'player' form_fields = ['player_accepted'] @staticmethod def is_displayed(player: Player): session = player.session subsession = player.subsession return subsession.round_number == 1 @staticmethod def before_next_page(player: Player, timeout_happened): session = player.session subsession = player.subsession import random if subsession.round_number == 1: cVal = random.random() if (cVal >= 0.5): player.diab_version = True class Instructions(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): session = player.session subsession = player.subsession r1player = player.in_round(1) accepted = r1player.player_accepted if not(accepted): return 0 return subsession.round_number == 1 @staticmethod def vars_for_template(player: Player): return dict(isDiab = player.in_round(1).diab_version) class Warning_50(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): session = player.session subsession = player.subsession r1player = player.in_round(1) accepted = r1player.player_accepted if not(accepted): return 0 return subsession.round_number == 51 class Decision(Page): form_model = 'player' form_fields = ['check_value'] @staticmethod def is_displayed(player: Player): r1player = player.in_round(1) accepted = r1player.player_accepted if not(accepted): return 0 return True @staticmethod def vars_for_template(player: Player): session = player.session subsession = player.subsession if subsession.round_number > 1: pay = round(player.in_round(subsession.round_number - 1).payoff) return dict(sval = round(player.shown_value), rnum = subsession.round_number, numr = C.NUM_ROUNDS, lrPayoff = abs(pay)) else: return dict(sval = round(player.shown_value), rnum = subsession.round_number, numr = C.NUM_ROUNDS, lrPayoff = 0) @staticmethod def before_next_page(player: Player, timeout_happened): import random if (player.check_value == 1): player.payoff = C.CHECK_PAYOFF elif (player.check_value == 0 and player.real_value < C.LOW_VAL_MIN): player.payoff = C.DIS_PAYOFF player.long = round(C.LOW_VAL_MIN - player.real_value) coinVal = 100 * random.random() if (coinVal < C.LONG_RANGE_PROB*player.long): player.long_loss = C.LONG_RANGE_LOSS else: player.payoff = C.CONT_PAYOFF class Outcome(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): r1player = player.in_round(1) accepted = r1player.player_accepted if not(accepted): return 0 else: return 1 ''' if (player.payoff == C.DIS_PAYOFF): return 1 return player.check_value ''' @staticmethod def vars_for_template(player: Player): return dict(rval = round(player.real_value), absLoss = round(abs(C.DIS_PAYOFF))) @staticmethod def before_next_page(player: Player, timeout_happened): pass class Details(Page): form_model = 'player' form_fields = ['player_age', 'player_gender', 'player_diabetic', 'player_cgm_model', 'player_sport_active', 'bonus_choice'] @staticmethod def is_displayed(player: Player): session = player.session subsession = player.subsession return (subsession.round_number == C.NUM_ROUNDS and player.in_round(1).player_accepted) @staticmethod def vars_for_template(player: Player): session = player.session subsession = player.subsession pay = round(player.in_round(subsession.round_number).payoff) lSum = 0 for x in player.in_all_rounds(): lSum += x.payoff lSum -= x.long_loss allTimePay = 1000 + lSum player.all_time_payoff = round(allTimePay) return dict(sval = round(player.shown_value), rnum = subsession.round_number, allTimePay = round(allTimePay), lrPayoff = abs(pay)) class Ending(Page): form_model = 'player' @staticmethod def is_displayed(player: Player): session = player.session subsession = player.subsession return (subsession.round_number == C.NUM_ROUNDS and player.in_round(1).player_accepted) @staticmethod def vars_for_template(player: Player): session = player.session subsession = player.subsession import random pay = round(player.in_round(subsession.round_number).payoff) lSum = 0 for x in player.in_all_rounds(): lSum += x.payoff lSum -= x.long_loss allTimePay = 1000 + lSum player.all_time_payoff = round(allTimePay) payoffThresh = random.randint(850,1000) player.bonus_thresh = round(payoffThresh) if allTimePay > payoffThresh: player.bonus_won = True return dict(sval = round(player.shown_value), rnum = subsession.round_number, allTimePay = round(allTimePay), lrPayoff = abs(pay)) page_sequence = [Introduction, Instructions, Warning_50, Decision, Outcome, Details, Ending]