from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random import itertools import numpy as np from django import forms from django.forms import widgets as django_widgets import math author = 'Zheng Li' doc = """ Intertemporal Choice """ class Constants(BaseConstants): name_in_url = 'inter_work_main' players_per_group = None decisions = [ # pairs of tau2 and tau1# # [0:3] sub-additivity 1 ['In 7 days', 'Today'], ['In 14 days', 'In 7 days'], ['In 14 days', 'Today'], # [3:6] sub-additivity 2 ['In 5 days', 'Today'], ['In 10 days', 'In 5 days'], ['In 10 days', 'Today'], # [6:10] separate ['In 1 day', 'Today'], ['In 2 days', 'Today'], ['In 3 days', 'Today'], ['In 20 days', 'Today'], ] amounts= range(90,125,5) steps = 5 num_rounds = 12 list1 = np.arange(1 * 20, - 1, -1) list2 = [] list2.append(0) for x in range(20): list2.append((x+1)*5) c = 0 d = 0 for x in range(40): c +=1 if c%2 != 0: list2.append(0) if c % 2 == 0 and c != 0: list2.append(int(d + 5)) d+=5 example_set = [('In 10 days', 'In 5 days', 15)] example_steps = 1 class Subsession(BaseSubsession): def creating_session(self): if self.round_number == 1: for p in self.get_players(): datessub1 = random.sample(Constants.decisions[0:3], 3) datessub2 = random.sample(Constants.decisions[3:6], 3) dates_sub1 = list() dates_sub2 = list() amount_tmp1 = random.choice(Constants.amounts) amount_tmp2 = random.choice(Constants.amounts) for date in datessub1: date = (date, amount_tmp1, 1) dates_sub1.append(date) for date in datessub2: date = (date, amount_tmp2, 2) dates_sub2.append(date) dates_sub = dates_sub1 + dates_sub2 datessep = random.sample(Constants.decisions[6:10], 4) dates_sep = list() for date in datessep: amount_tmp = random.choice(Constants.amounts) date = (date, amount_tmp, 0) dates_sep.append(date) dates_sep_extra = random.sample(dates_sep, 2) dates_sep = dates_sep + dates_sep_extra p.participant.vars['dates'] = random.sample(dates_sep + dates_sub, 12) p.participant.vars['failed_comprehension'] = False for p in self.get_players(): p.set_current_task_number() class Group(BaseGroup): pass class Player(BasePlayer): prolific_id = models.StringField() sub_identifier = models.IntegerField() # parameters in the optimization problem task_amount = models.IntegerField() # benchmark task at tau2 time_date_lhs = models.StringField() # tau2 time_date_rhs = models.StringField() # tau1 # indicator_never_always_switcher = models.IntegerField() # indifferent payment task: switching_point = models.FloatField() confidence = models.FloatField() # higher -> more confident; from 0 to 20 respectively corresponding to from 0% to 100%; step = $5% # overall indicator of whether passed the comprehension check failed_comprehension = models.BooleanField(initial=False) qn_lottery_got_wrong = models.BooleanField(initial=False) qn_hypo_got_wrong = models.BooleanField(initial=False) qn_confidence_got_wrong = models.BooleanField(initial=False) ##### qn_lottery = models.IntegerField( choices=[ [7, '7 additional tasks at any time in the next 5 days.'], [1, 'EITHER 2 additional tasks in 2 days OR 5 additional tasks in 5 days.'], [25, '2 additional tasks in 2 days AND 5 additional tasks in 5 days.'], ], widget=widgets.RadioSelect, blank=False, label="" ) qn_hypo = models.IntegerField( choices=[ [1, 'Even though my decisions are hypothetical, I am asked to assume that I would actually complete the tasks assigned, regardless of whether they take place now or in the future.'], [2, 'Even though my decisions are hypothetical, I am asked to assume that I would not actually complete the tasks assigned, regardless of whether they take place now or in the future.'], [3, 'Even though my decisions are hypothetical, I am asked to assume that I would only actually complete the tasks assigned to be completed now.'], ], widget=widgets.RadioSelect, blank=False, label="" ) qn_confidence = models.FloatField( blank=False, label="" ) # to determine parameters in the current task def set_current_task_number(self): setattr(self, 'time_date_lhs', self.participant.vars['dates'][self.round_number - 1][0][0]) setattr(self, 'time_date_rhs', self.participant.vars['dates'][self.round_number - 1][0][1]) setattr(self, 'task_amount', self.participant.vars['dates'][self.round_number - 1][1]) setattr(self, 'sub_identifier', self.participant.vars['dates'][self.round_number - 1][2]) def current_choice(self): iet_choice = [(self.time_date_lhs, self.time_date_rhs, self.task_amount)] return iet_choice def frange(self, start, stop, step): i = start while i < stop: if isinstance(i, int): yield i else: yield round(i, 2) i += step def right_side_amounts1(self): if self.task_amount > 0: lst = np.arange(self.task_amount, 0, -Constants.steps) return list(enumerate(lst, 1)) def right_side_amounts2(self): lst = np.arange(Constants.example_set[0][2], 0, -Constants.example_steps) return list(enumerate(lst, 1)) def range_bounds(self): if self.switching_point >= 0: bounds = [0, self.task_amount] return bounds def table_length1(self): return abs(self.task_amount) + 1 def set_switching_point_and_indicator(self): if self.task_amount > 0: # always choose option A if self.switching_point == 9999: self.switching_point = 0 self.indicator_never_always_switcher = 2 # always choose option B elif self.switching_point == self.task_amount: self.indicator_never_always_switcher = 0 else: self.indicator_never_always_switcher = 1