from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'news_prosumers_5' PLAYERS_PER_GROUP = None NUM_ROUNDS = 140 RET_price = cu(0.30) class Subsession(BaseSubsession): pass class Coins(ExtraModel): tasks = models.IntegerField() table = models.StringField() coin = models.StringField() value = models.FloatField() country = models.StringField() def creating_session(subsession: Subsession): rows = read_csv(__name__ + '/cointask_list3.csv', Coins) number_tasks = len(rows) tasks = [] tables = [] coins = [] values = [] countries = [] for i in range(0, number_tasks): tasks.append(rows[i]['tasks']) tables.append(rows[i]['table']) coins.append(rows[i]['coin']) values.append(rows[i]['value']) countries.append(rows[i]['country']) for p in subsession.get_players(): p.participant.tasks_3 = tasks p.participant.tables_3 = tables p.participant.coins_3 = coins p.participant.RET_second_value = values p.participant.RET_second_country = countries class Group(BaseGroup): pass class Player(BasePlayer): country = models.StringField( widget=widgets.RadioSelect, choices=[ 'Andorra', 'Austria', 'Belgium', 'Cyprus', 'Estonia', 'Finland', 'France', 'Germany', 'Greece', 'Ireland', 'Italy', 'Latvia', 'Lithuania', 'Luxembourg', 'Malta', 'Monaco', 'Netherlands', 'Portugal', 'San Marino', 'Slovakia', 'Slovenia', 'Spain', 'Vatican City' ], label='Country' ) value_coin = models.FloatField( widget=widgets.RadioSelect, choices=[0.01, 0.02, 0.05, 0.1, 0.2, 0.5, 1, 2], label="Value" ) RET_second_correct = models.IntegerField() RET_second_attempt = models.IntegerField() RET_second_earnings = models.CurrencyField() RET_correct_individual_attempt_2 = models.IntegerField() UQattempt_5_answer = models.IntegerField(widget=widgets.RadioSelect, choices=[[1, "Guessing your performance"], [2, "Guessing the average performance of other respondents"]]) UQattempt_5 = models.IntegerField(initial=0) UQattempt_6_answer = models.IntegerField(widget=widgets.RadioSelect, choices=[[1, "Guessing your performance"], [2, "Guessing the average performance of other respondents"]]) UQattempt_6 = models.IntegerField(initial=0) GUESS_own_second = models.IntegerField(min=0, max=99) GUESS_own_second_earnings = models.CurrencyField() GUESS_own_second_time = models.FloatField() GUESS_other_second = models.IntegerField(min=0, max=99) GUESS_other_second_earnings = models.IntegerField() GUESS_other_second_time = models.FloatField() leavescreen_32 = models.IntegerField(blank=True) leavescreen_33 = models.IntegerField(blank=True) leavescreen_34 = models.IntegerField(blank=True) leavescreen_35 = models.IntegerField(blank=True) leavescreen_36 = models.IntegerField(blank=True) leavescreen_37 = models.IntegerField(blank=True) leavescreen_38 = models.IntegerField(blank=True) leavescreen_39 = models.IntegerField(blank=True) def get_timeout_seconds(player): participant = player.participant import time return participant.expiry_3 - time.time() # PAGES class Part_2_instructions_task_1(Page): def is_displayed(player: Player): return player.round_number == 1 def before_next_page(player: Player, timeout_happened): import time player.participant.expiry_3 = time.time() + 2 * 60 form_model = 'player' form_fields = ['leavescreen_32'] class Task_1(Page): get_timeout_seconds = get_timeout_seconds timer_text = 'Residual time' @staticmethod def is_displayed(player): return get_timeout_seconds(player) > 0 form_model = 'player' form_fields = ['country', 'value_coin', 'leavescreen_33'] @staticmethod def vars_for_template(player: Player): return dict(image_path_coin='news_prosumers/{}'.format(player.participant.coins_3[player.round_number-1]), image_path_table='news_prosumers/{}'.format(player.participant.tables_3[player.round_number-1])) @staticmethod def before_next_page(player: Player, timeout_happened): player_country_guess = player.country player_country_guess_processed = player_country_guess.replace(" ", "").lower() if player.participant.RET_second_value[player.round_number - 1] == player.value_coin and \ player.participant.RET_second_country[player.round_number - 1] == player_country_guess_processed: player.RET_correct_individual_attempt_2 = 1 else: player.RET_correct_individual_attempt_2 = 0 class Part_2_instructions_task_2(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['UQattempt_5_answer', 'leavescreen_34'] def error_message(player: Player, values): if values['UQattempt_5_answer'] != 1: player.UQattempt_5 += 1 return "Answer is wrong. Try again" @staticmethod def before_next_page(player: Player, timeout_happened): coins = [] countries = [] for p in player.in_all_rounds(): coins.append(p.field_maybe_none('value_coin')) countries.append(p.field_maybe_none('country')) correct = 0 for i in range(0, C.NUM_ROUNDS): if coins[i] == player.participant.RET_second_value[i] and countries[i].replace(" ", "").lower() == player.participant.RET_second_country[i]: correct += 1 player.RET_second_correct = correct player.participant.RET_second_correct = player.RET_second_correct player.RET_second_attempt = len(countries) - countries.count(None) - countries.count('') player.RET_second_earnings = C.RET_price * player.RET_second_correct player.participant.RET_second_earnings = player.field_maybe_none('RET_second_earnings') class Part_2_instructions_task_2_2(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS timeout_seconds = 5 form_model = 'player' form_fields = ['leavescreen_35'] class Guess_1(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['GUESS_own_second', 'GUESS_own_second_time', 'leavescreen_36'] def before_next_page(player: Player, timeout_happened): player.participant.GUESS_own_second = player.GUESS_own_second if player.RET_second_correct == player.GUESS_own_second: player.participant.GUESS_own_second_earnings = 4 else: if (player.GUESS_own_second - 1) == player.RET_second_correct: player.participant.GUESS_own_second_earnings = 3 else: if (player.GUESS_own_second - 2) == player.RET_second_correct: player.participant.GUESS_own_second_earnings = 3 else: if (player.GUESS_own_second + 1) == player.RET_second_correct: player.participant.GUESS_own_second_earnings = 3 else: if (player.GUESS_own_second + 2) == player.RET_second_correct: player.participant.GUESS_own_second_earnings = 3 else: if (player.GUESS_own_second - 3) == player.RET_second_correct: player.participant.GUESS_own_second_earnings = 2 else: if (player.GUESS_own_second - 4) == player.RET_second_correct: player.participant.GUESS_own_second_earnings = 2 else: if (player.GUESS_own_second + 3) == player.RET_second_correct: player.participant.GUESS_own_second_earnings = 2 else: if (player.GUESS_own_second + 4) == player.RET_second_correct: player.participant.GUESS_own_second_earnings = 2 else: player.participant.GUESS_own_second_earnings = 0 class Part_2_instructions_task_3(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['UQattempt_6_answer', 'leavescreen_37'] def error_message(player: Player, values): if values['UQattempt_6_answer'] != 2: player.UQattempt_6 += 1 return "Answer is wrong. Try again" class Part_2_instructions_task_3_2(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS timeout_seconds = 5 form_model = 'player' form_fields = ['leavescreen_38'] class Guess_2(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS form_model = 'player' form_fields = ['GUESS_other_second', 'GUESS_other_second_time', 'leavescreen_39'] def before_next_page(player: Player, timeout_happened): player.participant.GUESS_other_second = player.GUESS_other_second page_sequence = [ Part_2_instructions_task_1, Task_1, Part_2_instructions_task_2, Part_2_instructions_task_2_2, Guess_1, Part_2_instructions_task_3, Part_2_instructions_task_3_2, Guess_2, ]