from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) import random as random import math as math import itertools import json as json import pandas as pd author = 'Your name here' doc = """Subs can only work on the math task""" def load_math_options(): with open(f'AbilityMath/static/Addition_Increasing_Difficulty/task_list_8_rounds.json', 'r') as read_file: task_list = json.load(read_file) return task_list def make_math_field(): return models.IntegerField( widget=widgets.RadioSelect, blank=True, label='', ) def make_math_ability_field(): return models.IntegerField( blank=True, label='', ) class Constants(BaseConstants): name_in_url = '0hsgW2aBa' players_per_group = None num_rounds = 8 num_participants = 10 timeout = 40 # Payoff Constants payoff_incorrect = c(0) math_rate = 10 math_piecerate = c(math_rate) time_rate = 5 time_piecerate = c(time_rate) example_time = 38 task = 'Addition' num_math_tasks = 10 # Load math tasks addition_task = load_math_options() class Subsession(BaseSubsession): def creating_session(self): for p in self.get_players(): if self.round_number == 1: p.participant.vars['math_piecerate'] = Constants.math_piecerate # fixed on subject and session level p.task_option_this_round = (self.round_number - 1) p.task = Constants.task class Group(BaseGroup): pass class Player(BasePlayer): # Selected Task task = models.StringField() ### Cumulated Time needed for one math task ################ math_1_time = models.FloatField(blank=True) math_2_time = models.FloatField(blank=True) math_3_time = models.FloatField(blank=True) math_4_time = models.FloatField(blank=True) math_5_time = models.FloatField(blank=True) math_6_time = models.FloatField(blank=True) math_7_time = models.FloatField(blank=True) math_8_time = models.FloatField(blank=True) math_9_time = models.FloatField(blank=True) math_10_time = models.FloatField(blank=True) math_1 = make_math_ability_field() math_2 = make_math_ability_field() math_3 = make_math_ability_field() math_4 = make_math_ability_field() math_5 = make_math_ability_field() math_6 = make_math_ability_field() math_7 = make_math_ability_field() math_8 = make_math_ability_field() math_9 = make_math_ability_field() math_10 = make_math_ability_field() # Check correct answers math_correct = models.IntegerField(initial=0) # Number of tries math_1_tries = models.IntegerField(blank=True) math_2_tries = models.IntegerField(blank=True) math_3_tries = models.IntegerField(blank=True) math_4_tries = models.IntegerField(blank=True) math_5_tries = models.IntegerField(blank=True) math_6_tries = models.IntegerField(blank=True) math_7_tries = models.IntegerField(blank=True) math_8_tries = models.IntegerField(blank=True) math_9_tries = models.IntegerField(blank=True) math_10_tries = models.IntegerField(blank=True) # Timer timer_task1 = models.FloatField() new_timer_task1 = models.FloatField() math_time = models.FloatField() total_time = models.FloatField() # Time spent Math_Instructions_time_spent= models.FloatField(blank=True) MathTask_time_spent= models.FloatField(blank=True) # Warnings # Time spent Math_Instructions_warnings = models.IntegerField() MathTask_warnings = models.IntegerField() StartRound_warnings = models.IntegerField() # Selected Task task_option_this_round = models.IntegerField() payoff_math = models.CurrencyField() payoff_time = models.CurrencyField() def set_payoff(self): solutions = Constants.addition_task[self.task_option_this_round][1] answers = [ self.math_1, self.math_2, self.math_3, self.math_4, self.math_5, self.math_6, self.math_7, self.math_8, self.math_9, self.math_10, ] self.math_correct = sum([1 for x,y in zip(answers,solutions) if x == y]) self.payoff_math = self.math_correct * Constants.math_piecerate # Also give money for the time finished earlier # This code is robust to: # a) recorded time being not in the range (0,Timeout) # b) Participants proceeds by error/hacking and gets time bonus without completing all tasks if self.math_10_time != None and self.math_10_time < Constants.timeout and self.math_10_time > 0 and self.math_correct == Constants.num_math_tasks: self.payoff_time = (Constants.timeout - math.ceil(self.math_10_time)) * Constants.time_piecerate else: self.payoff_time = 0 * Constants.time_piecerate self.payoff = self.payoff_math + self.payoff_time # Put it into the ether self.participant.vars[f'math_ability_round_{self.round_number}'] = self.math_correct self.participant.vars[f'math_ability_payoff_round_{self.round_number}'] = self.payoff def save_data(self): p_vars = self.participant.vars if self.round_number == 1: p_vars[f'math_t_1'] = [] p_vars[f'math_t_2'] = [] p_vars[f'math_t_3'] = [] p_vars[f'math_t_4'] = [] p_vars[f'math_t_5'] = [] p_vars[f'math_t_6'] = [] p_vars[f'math_t_7'] = [] p_vars[f'math_t_8'] = [] p_vars[f'math_t_9'] = [] p_vars[f'math_t_10'] = [] elif self.round_number == Constants.num_rounds: p_vars['num_math_tasks_math_ability'] = Constants.num_math_tasks p_vars['num_rounds_math_ability'] = Constants.num_rounds else: pass # Put it into the ether p_vars[f'math_t_1'].append(self.math_1_time) p_vars[f'math_t_2'].append(self.math_2_time) p_vars[f'math_t_3'].append(self.math_3_time) p_vars[f'math_t_4'].append(self.math_4_time) p_vars[f'math_t_5'].append(self.math_5_time) p_vars[f'math_t_6'].append(self.math_6_time) p_vars[f'math_t_7'].append(self.math_7_time) p_vars[f'math_t_8'].append(self.math_8_time) p_vars[f'math_t_9'].append(self.math_9_time) p_vars[f'math_t_10'].append(self.math_10_time)