from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'hidden_ind' PLAYERS_PER_GROUP = None NUM_ROUNDS = 1 TIME_TEMPLATE = __name__ + '/Time.html' LOC_TEMPLATE = __name__ + '/Location.html' CAR_TEMPLATE = __name__ + '/Car.html' class Subsession(BaseSubsession): pass class Group(BaseGroup): pass def make_q(label): return models.CurrencyField(label=label, min=0, max=100, initial=0) class Player(BasePlayer): m = make_q('Monday') tu = make_q('Tuesday') w = make_q('Wednesday') th = make_q('Thursday') t_1 = make_q('8am') t_2 = make_q('9pm') t_3 = make_q('10pm') t_4 = make_q('11pm') L_1 = make_q('Docks') L_2 = make_q('Restaurant') L_3 = make_q('Bar') L_4 = make_q('Warehouse') C_1 = make_q('Honda') C_2 = make_q('Ford') C_3 = make_q('Warehouse') C_4 = make_q('Lamborghini') def creating_session(subsession: Subsession): with open('_rooms/group.txt') as f: labels = f.read().splitlines() for p, label in zip(subsession.get_players(), labels): p.participant.label = label for p, label in zip(subsession.get_players(), labels): p.participant.label = label # PAGES class Ind_Intro_p1(Page): pass class Ind_Intro_p2(Page): pass class Ind_Intro_p3(Page): pass class Ind_Intro_p4(Page): pass class Ind_Intro_p5(Page): pass class Ind_Intro_p6(Page): pass class Ind_Intro_p7(Page): pass class check(Page): form_model = 'player' form_fields = ['m', 'tu', 'w', 'th'] @staticmethod def error_message(player: Player, values): # since 'values' is a dict, you could also do sum(values.values()) solutions = dict(m=0, tu=50, w=0, th=50) if values != solutions: return 'Please read the instructions. If you know the crime wont occur on Monday or Wednesday, ' \ 'but have no other information, then there is an equal chance it will occur on the other days' class clues(Page): pass class Ind_q(Page): form_model = 'player' form_fields = ['t_1', 't_2', 't_3', 't_4', 'C_1', 'C_2', 'C_3', 'C_4', 'L_1', 'L_2', 'L_3', 'L_4'] @staticmethod def error_message(player: Player, values): # since 'values' is a dict, you could also do sum(values.values()) if ((values['t_1'] + values['t_2'] + values['t_3'] + values['t_4']) or (values['L_1'] + values['L_2'] + values['L_3'] + values['L_4']) or (values['C_1'] + values['C_2'] + values['C_3'] + values['C_4'])) != (100 or 99.9): return 'The total needs to add to 100 (or 99.9 in case of an equal split between 3)' class Time(Page): form_model = 'player' form_fields = ['t_1', 't_2', 't_3', 't_4'] @staticmethod def error_message(player: Player, values): # since 'values' is a dict, you could also do sum(values.values()) if (values['t_1'] + values['t_2'] + values['t_3'] + values['t_4']) != 100 or 99.9: return 'The total needs to add to 100 (or 99.9 in case of an equal split between 3)' class Location(Page): form_model = 'player' form_fields = ['L_1', 'L_2', 'L_3', 'L_4'] @staticmethod def error_message(player: Player, values): # since 'values' is a dict, you could also do sum(values.values()) if sum(values.values()) != 100 or 99.9: return 'The total needs to add to 100 (or 99.9 in case of an equal split between 3)' class Car(Page): form_model = 'player' form_fields = ['C_1', 'C_2', 'C_3', 'C_4'] @staticmethod def error_message(player: Player, values): # since 'values' is a dict, you could also do sum(values.values()) if sum(values.values()) != 100 or 99.9: return 'The total needs to add to 100 (or 99.9 in case of an equal split between 3)' page_sequence = [Ind_Intro_p1, Ind_Intro_p2, Ind_Intro_p3, Ind_Intro_p4, Ind_Intro_p5, Ind_Intro_p6, check, Ind_Intro_p7, clues, Ind_q]