from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) from otree.models import Participant import random import csv author = 'Luca' doc = """ Tedious task for excuse experiment """ class Constants(BaseConstants): name_in_url = 'large_task' players_per_group = None num_rounds = 60 def create_matrix_database(): with open('small_matrix.csv', mode='r') as file: reader = csv.reader(file) return {int(rows[0]): int(rows[1]) for rows in reader} def create_hard_matrix_database(): with open('large_matrix.csv', mode='r') as file: reader = csv.reader(file) return {int(rows[0]): int(rows[1]) for rows in reader} #def create_hard_matrix_database(): # with open('large_matrix.csv', mode='r') as file: # reader = csv.reader(file) # return {int(rows[0]): { # 'solution': int(rows[1]), # 'search_character': rows[2] # } # for rows in reader} Matrix = create_matrix_database() HardMatrix = create_hard_matrix_database() class Subsession(BaseSubsession): def creating_session(self): for p in self.get_players(): p.matrix_id_in_round = random.choice(range(1, 200)) if p.round_number == 1: p.participant.vars['updated_payoffs_already'] = False p.participant.vars['finished'] = False p.participant.vars['finished_too_many_wrong'] = False class Group(BaseGroup): pass class Player(BasePlayer): solution_guess = models.IntegerField() guess_is_correct = models.BooleanField() matrix_id_in_round = models.IntegerField() for_how_much_do_extra_10_easy = models.CurrencyField( label="This is a hypothetical question. What is the smallest payment for which you would be willing to do 10 additional small matrices?" ) for_how_much_do_extra_10_hard = models.CurrencyField( label="This is a hypothetical question. What is the smallest payment for which you would be willing to do 10 additional large matrices?" ) @property def wrong_guesses(self): return sum([not q.guess_is_correct for q in self.in_all_rounds() if q.guess_is_correct is not None]) @property def required_hard_tasks(self): s = self.session return self.participant.vars['hard_tasks_for_session'][s.config['period'] - 1] @property def has_more_attempts(self): return self.correct_guesses < self.total_tasks and not self.reached_max_wrong_guesses def set_finished_successfully(self): self.participant.vars['finished'] = True return def set_finished_unsuccessfully(self): self.participant.vars['finished_too_many_wrong'] = True return @property def has_seen_final(self): p = self.participant return p.vars['finished'] or p.vars['finished_too_many_wrong'] @property def total_tasks(self): return self.session.config['total_tasks_per_session'] @property def reached_max_wrong_guesses(self): return self.wrong_guesses > self.total_tasks @property def correct_guesses(self): return sum([q.guess_is_correct for q in self.in_all_rounds() if q.guess_is_correct is not None]) @property def hard_or_easy_matrix(self): matrix_type = 'easy' if self.correct_guesses >= self.required_hard_tasks else 'hard' return matrix_type @property def matrix_solution(self): if self.hard_or_easy_matrix == 'hard': #solution = Constants.HardMatrix[self.matrix_id_in_round].get('solution') solution = Constants.HardMatrix[self.matrix_id_in_round] else: solution = Constants.Matrix[self.matrix_id_in_round] return solution @property def matrix_character(self): if self.hard_or_easy_matrix == 'hard': # character = Constants.HardMatrix[self.matrix_id_in_round].get('search_character') character = "1" else: character = "1" return character @property def matrix_path(self): x = self.matrix_id_in_round if self.hard_or_easy_matrix == 'hard': path = 'elicitation/large_matrix_{}.png'.format(x) else: path = 'elicitation/small_matrix_{}.png'.format(x) return path @property def session_bonus(self): s = self.session bonus = s.config['session_bonus'] if s.config['pay_session_bonus'] else 0 return bonus @property def completion_bonus(self): p = self.participant s = self.session completion_bonus = s.config['completion_bonus'] + p.vars['chosen_option_that_counts']['extra_payment'] if s.config['pay_completion_bonus'] else 0 return completion_bonus @property def completed_tasks(self): return self.participant.vars['finished'] def increase_payoffs_on_hit(self): p = self.participant hit_participant = Participant.objects.filter(mturk_worker_id=p.label,session__code=self.session.config['hit_session_code']) if len(hit_participant) == 1: # Increase the payoffs. Make sure this only happens once by checking if it was already done if not p.vars['updated_payoffs_already']: p_hit = hit_participant[0] p_hit.payoff = p_hit.payoff + self.session_bonus + self.completion_bonus p.vars['updated_payoffs_already'] = True else: # Houston, we have a problem print("EXCEPTION! We have {} participants in the session {} with MTurk ID {}!".format(len(hit_participant), self.session.config['hit_session_code'], p.label))