from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random import itertools from django import forms from django.forms import widgets as django_widgets import math author = 'Nikolas Kirk' doc = """ Intertemporal Choice """ class Constants(BaseConstants): name_in_url = 'intertemporal_choice_defaults' players_per_group = None decisions = { 'time': [['1 week'], ['1 month'], ['6 months'], ['1 year'], ['2 years'], ['3 years']], 'amounts': [15, 20, 25], } defaults = ['2 weeks', '2 years'] default_min_time = 90 combinations = len(decisions['time']) * len(decisions['amounts']) num_rounds = 7 class Subsession(BaseSubsession): def before_session_starts(self): if self.round_number == 1: for p in self.get_players(): p.participant.vars['default'] = random.choice(Constants.defaults) p.participant.vars['failed_comprehension'] = False p.participant.vars['lists_paying_round'] = random.randint(1, Constants.num_rounds) p.participant.vars['list_sequence'] = random.sample(range(0, Constants.combinations), Constants.num_rounds) for p in self.get_players(): p.default = p.participant.vars['default'] p.set_current_task_number() class Group(BaseGroup): pass class Player(BasePlayer): default = models.StringField() total_pay = models.CurrencyField() task_number = models.IntegerField() task_identifier = models.StringField() switching_point_1 = models.FloatField() # switching_point_2 = models.FloatField() on_paying_round = models.BooleanField(initial=False) pay_amount = models.IntegerField() time_span = models.StringField() type = models.StringField() endowment = models.FloatField() indicator_never_always_switcher = models.IntegerField() switching_point = models.FloatField() choice_identifier = models.StringField() confidence = models.FloatField() confidence_upper_bound = models.FloatField() confidence_lower_bound = models.FloatField() question_failed = models.IntegerField() random_payoff = models.CurrencyField() random_right_side_amount = models.CurrencyField() delayed_payment_bool = models.StringField() delayed_payment_time = models.StringField() failed_comprehension = models.BooleanField(initial=False) qn_lottery_got_wrong = models.BooleanField(initial=False) qn_list_got_wrong = models.BooleanField(initial=False) qn_confidence_got_wrong = models.BooleanField(initial=False) qn_default_got_wrong = models.BooleanField(initial=False) qn_default = models.IntegerField( choices=[ [0, 'in 2 weeks'], [1, 'in 6 months'], [2, 'in 2 years'], ], widget=widgets.RadioSelect, blank=False, label="" ) qn_lottery = models.IntegerField( choices=[ [0, 'It would be possible that I get paid both $15 and $20, i.e., I may receive a total amount of $35 from this decision.'], [1, 'I would receive EITHER $15 today OR $20 in 10 days.'], [0, 'It would be possible that I receive no money from this decision.'], ], widget=widgets.RadioSelect, blank=False, label="" ) qn_list = models.IntegerField( choices=[ [0, 'This person indicated that the delayed payment would be worth more to them than $9 today.'], [0, 'This person indicated that the delayed payment would be worth between $3 and $7 to them today.'], [1, 'This person indicated that the delayed payment would be worth between $8 and $9 to them today.'], ], widget=widgets.RadioSelect, blank=False, label="" ) qn_confidence = models.FloatField( blank=False, label="" ) def set_current_task_number(self): setattr(self, 'task_number', self.participant.vars['list_sequence'][self.round_number-1]) task_list = [] l = itertools.product( Constants.decisions['time'], Constants.decisions['amounts'], ) task_list.extend(l) tup = task_list[self.task_number] setattr(self, 'time_span', random.choice(tup[0])) setattr(self, 'pay_amount', tup[1]) if self.round_number == 1: setattr(self, 'time_span', self.default) 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.pay_amount > 0: lst = self.frange(0, self.pay_amount + 1, 1) return list(enumerate(lst, 1)) def range_bounds(self): if self.pay_amount > 0: bounds = [0, self.pay_amount] return bounds def table_length1(self): return abs(self.pay_amount) + 1 def current_choice(self): iet_choice = [(self.time_span, self.pay_amount)] return iet_choice def set_switching_point_and_indicator(self): if self.pay_amount > 0: if self.switching_point == 9999: self.switching_point = self.pay_amount + 1 self.indicator_never_always_switcher = 2 elif self.switching_point == 0: self.indicator_never_always_switcher = 0 else: self.indicator_never_always_switcher = 1 elif self.pay_amount < 0: if self.switching_point == 9999: self.switching_point = 1 self.indicator_never_always_switcher = 2 elif self.switching_point == self.pay_amount: self.indicator_never_always_switcher = 0 else: self.indicator_never_always_switcher = 1