from otree.api import * import random import csv author = 'Lingguo XU' doc = """ Part 4: second task round """ class Constants(BaseConstants): name_in_url = 'Part4' players_per_group = None ECUpercorrect = 40 with open('Part4/Part4_asnwerkey.csv') as questions_file: questions = list(csv.DictReader(questions_file)) # num_rounds = len(questions) num_rounds = 30 class Subsession(BaseSubsession): def creating_session(subsession): if player.round_number == 1: player.session.vars['questions'] = Constants.questions.copy() for player in subsession.get_players(): question_data = current_question(player) player.solution = question_data['solution'] player.round_number = player.round_number class Group(BaseGroup): pass class Player(BasePlayer): solution = models.StringField() task_answers = models.StringField(label="Please fill in a single lower-case letter.", initial="") is_correct = models.BooleanField(initial=0) def current_question(player): return player.session.vars['questions'][player.round_number - 1] attempts_R2 = models.IntegerField() attempts_R2_level2 = models.IntegerField() attempts_R2_level3 = models.IntegerField() success_R2 = models.IntegerField() success_R2_1_10 = models.IntegerField() success_R2_11_20 = models.IntegerField() success_R2_21_25 = models.IntegerField() success_R2_26_30 = models.IntegerField() success_R2_22_30 = models.IntegerField() success_R2_level2 = models.IntegerField() success_R2_level3 = models.IntegerField() payoff_part4 = models.IntegerField() # FUNCTIONS def get_timeout_seconds(player): import time return player.participant.expiry - time.time() def creating_session(subsession): for player in subsession.get_players(): if player.round_number == 1: player.session.vars['questions'] = Constants.questions.copy() question_data = player.current_question() player.solution = question_data['solution'] player.round_number = player.round_number # PAGES class ReadyTask_ASU(Page): def is_displayed(player): return player.participant.is_dropout == False and player.round_number == 1 @staticmethod def get_timeout_seconds(player): participant = player.participant if participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): participant = player.participant if timeout_happened: participant.is_dropout = False import time # user has 10 minutes to complete as many pages as possible participant.vars['expiry'] = time.time() + player.session.config['task_round_timeout_seconds'] class Task(Page): form_model = 'player' form_fields = ['task_answers'] timer_text = 'Time left to complete this task:' get_timeout_seconds = get_timeout_seconds @staticmethod def is_displayed(player): return get_timeout_seconds(player) > 2 and player.participant.is_dropout == False @staticmethod def vars_for_template(player): return dict( image_path_1='Part4/ImagQuestions/{}.jpg'.format(player.round_number), image_path_2='Part4/ImagAnswers/{}.jpg'.format(player.round_number), round_number = player.round_number ) @staticmethod def before_next_page(player, timeout_happened): import time if player.task_answers: player.is_correct = (player.task_answers.lower() == player.solution.lower()) @staticmethod def error_message(player, value): print('You typed in', value) if value['task_answers'] not in ["a", "b", "c", "d", "e", "f"]: return 'Please enter a single lower-case letter, from the a list of "a", "b", "c", "d", "e", and "f".' class Results(Page): @staticmethod def is_displayed(player): return player.round_number == Constants.num_rounds and player.participant.is_dropout == False @staticmethod def vars_for_template(player): player_in_all_rounds = player.in_all_rounds() # Need to filter out the none types where the player didn't get a chance to answer the questions filtered1 = [p.task_answers for p in player_in_all_rounds if p.task_answers != ""] filtered1_1 = [p.task_answers for p in [player.in_round(1), player.in_round(4), player.in_round(7), player.in_round(10), player.in_round(13), player.in_round(16), player.in_round(19), player.in_round(22), player.in_round(25), player.in_round(28)] if p.task_answers != ""] filtered2 = [p.is_correct for p in player_in_all_rounds] filtered3 = [p.is_correct for p in player.in_rounds(1, 10)] filtered4 = [p.is_correct for p in player.in_rounds(11, 20)] filtered5 = [p.is_correct for p in player.in_rounds(21, 25)] filtered6 = [p.is_correct for p in player.in_rounds(26, 30)] filtered7 = [p.is_correct for p in [player.in_round(1), player.in_round(4), player.in_round(7), player.in_round(10), player.in_round(13), player.in_round(16), player.in_round(19), player.in_round(22), player.in_round(25), player.in_round(28)]] filtered8 = [p.is_correct for p in player.in_rounds(22, 30)] player.attempts_R2 = len(filtered1) player.attempts_R2_level2 = len(filtered1_1) player.attempts_R2_level3 = len(filtered1)-len(filtered1_1) player.success_R2 = sum(filtered2) player.success_R2_1_10 = sum(filtered3) player.success_R2_11_20 = sum(filtered4) player.success_R2_21_25 = sum(filtered5) player.success_R2_26_30 = sum(filtered6) player.success_R2_level2 = sum(filtered7) player.success_R2_level3 = sum(filtered2)-sum(filtered7) player.success_R2_22_30 = sum(filtered8) #Add participant variable for noisyfeedback player.participant.questionsattempted_R2 = player.attempts_R2 player.participant.correctanswer_R2 = player.success_R2 # Compute player payoff in Part 4 player.payoff_part4 = Constants.ECUpercorrect * player.success_R2 player.participant.part4payoff = player.payoff_part4 return { 'player_in_all_rounds': player_in_all_rounds, 'question_answered': len(filtered1), 'questions_correct': sum(filtered2) } @staticmethod def get_timeout_seconds(player): if player.participant.is_dropout: return 1 # instant timeout, 1 second else: return player.session.config['my_page_timeout_seconds'] @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.participant.is_dropout = True page_sequence = [ReadyTask_ASU, Task, Results]