from email.utils import format_datetime from otree.api import * author = 'Nathaniel Lawrence, LEMMA, Université Panthéon-Assas' doc = """ This app provides a consumption simultion app, combined with surveys on demographics; financial knowledge, behavior, and attitude; and numeracy; as well as tests of time preferences and compulsivity/learning rates. """ def read_csv_stimuli(): import csv # import random f = open(__name__ + '/stimuli.csv', encoding='utf-8-sig') rows = [row for row in csv.DictReader(f)] # random.shuffle(rows) for row in rows: # all values in CSV are string unless you convert them row['later'] = cu(row['later']) return rows def read_csv_delay(): import csv import random f = open(__name__ + '/delay.csv', encoding='utf-8-sig') rows = [row for row in csv.DictReader(f)] random.shuffle(rows) return rows def jsonDelay(delayDict): import json delayJson = json.dumps({"delay":[delay for delay in delayDict]}) return delayJson ### Define constants here, in all-caps class C(BaseConstants): NAME_IN_URL = 'tp' PLAYERS_PER_GROUP = None NUM_ROUNDS = 3 ## Introduction constants PAYOUT_1 = cu(20) PAYOUT_2 = cu(100) INTRO_DELAY = '1 month' # get larger-later options LATER = read_csv_stimuli() # get delay DELAY = read_csv_delay() # DELAY_INDEX = [0,1,2,3,4,5] NOW_REWARD = cu(20) DELAY_JSON = jsonDelay(DELAY) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass ### define the questions a player must answer here class Player(BasePlayer): ## Session indices day = models.IntegerField() app_sequence = models.IntegerField() inf_sequence = models.IntegerField() intervention = models.IntegerField() ### choices = [[value,label],[value,label],...] practice = models.IntegerField( widget=widgets.RadioSelect, choices=[[0,C.PAYOUT_1],[1,C.PAYOUT_2]] ) delay = models.LongStringField(initial=C.DELAY_JSON) def make_field(number): return models.FloatField( choices=[[float(C.NOW_REWARD),C.NOW_REWARD],[float(C.LATER[number]['later']),C.LATER[number]['later']]], label='',#f"{C.NOW_REWARD} right now or {C.LATER[number]['later']} in ", widget=widgets.RadioSelect ) q1 = make_field(0) q2 = make_field(1) q3 = make_field(2) q4 = make_field(3) q5 = make_field(4) q6 = make_field(5) q7 = make_field(6) q8 = make_field(7) q9 = make_field(8) q10 = make_field(9) # PAGES class Intro(Page): form_model = 'player' form_fields = ['practice'] @staticmethod def error_message(player: Player, values): solutions = dict( practice=0 ) error_messages = dict( practice='That is not the correct selection. Please, try again.' ) for field_name in solutions: if values[field_name] != solutions[field_name]: error_messages = error_messages[field_name] return error_messages @staticmethod def is_displayed(player): return player.round_number == 1 class Intro_2(Page): pass @staticmethod def is_displayed(player): return player.round_number == 1 class TimePreferences(Page): form_model = 'player' @staticmethod def get_form_fields(player: Player): import random form_fields = ['q1','q2','q3','q4','q5','q6','q7','q8','q9','q10'] random.shuffle(form_fields) return form_fields @staticmethod def vars_for_template(player): delay = C.DELAY[(player.round_number - 1)]['delay'] return dict(delay=delay) class Results(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 3 # @staticmethod # def vars_for_template(player: Player): # import random # choices_list = [player.q1,player.q2,player.q3,player.q4,player.q5,player.q6,player.q7,player.q8,player.q9,player.q10] # random_selection = random.randint(0,9) # choice = choices_list[random_selection] # print(choice) # return dict( # choice=choice # ) page_sequence = [Intro, Intro_2, TimePreferences, Results] def custom_export(players): yield ['participant_code', 'delay'] for player in players: yield [player.participant.code, player.delay]