from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, safe_json ) import itertools import random author = 'Thomas Graeber' doc = """ Assign treatment status. """ class Constants(BaseConstants): """Contains constants of the current experiment app.""" name_in_url = 'framing_tasks' players_per_group = None tasks_intertemporal = { 'baseline': [ { 'name': 'intertemp_base_25_1_26_4', 'type': 'intertemporal', 'specification': ['base', 25, '1 day later than X', 26, '4 days later than X', 'in 0 days (today)'] }, { 'name': 'intertemp_base_25_96_26_99', 'type': 'intertemporal', 'specification': ['base', 25, '96 days later than X', 26, '99 days later than X', 'in 0 days (today)'] }, { 'name': 'intertemp_base_25_0_26_4', 'type': 'intertemporal', 'specification': ['base2', 25, 'in: 0 days divided by Z', 26, 'in: 4 days divided by Z', '1'] }, { 'name': 'intertemp_base_25_0_35_100', 'type': 'intertemporal', 'specification': ['base2', 25, 'in: 0 days times Z', 35, 'in: 100 days times Z', '1'] }, ], 'treatment': [ { 'name': 'intertemp_base_25_1_26_4', 'type': 'intertemporal', 'specification': ['treat', 25, '99 days earlier than X', 26, '96 days earlier than X', 'in 100 days'] }, { 'name': 'intertemp_base_25_4_26_1', 'type': 'intertemporal', 'specification': ['treat', 25, '4 days earlier than X', 26, '1 day earlier than X', 'in 100 days'] }, { 'name': 'intertemp_base_25_0_26_100', 'type': 'intertemporal', 'specification': ['treat2', 25, 'in: 0 days divided by Z', 26, 'in: 100 days divided by Z', '25'] }, { 'name': 'intertemp_base_25_0_35_100', 'type': 'intertemporal', 'specification': ['treat2', 25, 'in: 0 days times Z', 35, 'in: 4 days times Z', '25'] }, ], } tasks_risk = { 'baseline': [ { 'name': 'risk_base_40_1_10_21', 'type': 'risk', 'specification': ['base', 40, 'Y plus 1%', 10, 'Y plus 21%', 0] }, { 'name': 'risk_base_40_41_10_61', 'type': 'risk', 'specification': ['base', 40, 'Y plus 41%', 10, 'Y plus 61%', 0] }, { 'name': 'risk_base_40_80_30_100', 'type': 'risk', 'specification': ['base2', 40, '80% times Z', 30, '100% times Z', 1] }, { 'name': 'risk_base_40_20_30_25', 'type': 'risk', 'specification': ['base2', 40, '20% divided by Z', 30, '25% divided by Z', 1] }, ], 'treatment': [ { 'name': 'risk_treat_40_21_10_1', 'type': 'risk', 'specification': ['treat', 40, 'Y reduced by 21%', 10, 'Y reduced by 1%', 62] }, { 'name': 'risk_treat_40_61_10_41', 'type': 'risk', 'specification': ['treat', 40, 'Y reduced by 61%', 10, 'Y reduced by 41%', 62] }, { 'name': 'risk_treat_40_20_30_25', 'type': 'risk', 'specification': ['treat2', 40, '20% times Z', 30, '25% times Z', 4] }, { 'name': 'risk_treat_40_80_30_100', 'type': 'risk', 'specification': ['treat2', 40, '80% divided by Z', 30, '100% divided by Z', 4] }, ], } tasks_cons_choice = { 'baseline': [ { 'name': 'wine_0_20', 'type': 'cons_choice', 'specification': ['base', 25, '0%', 25, '20%', 0] }, { 'name': 'wine_40_60', 'type': 'cons_choice', 'specification': ['base', 25, '40%', 25, '60%', 0] }, { 'name': 'wine_80_100', 'type': 'cons_choice', 'specification': ['base', 25, '80%', 25, '100%', 0] }, ] } num_rounds = len(tasks_intertemporal['baseline']) + len(tasks_risk['baseline']) + len(tasks_cons_choice['baseline']) intertemporal_rounds = len(tasks_intertemporal['baseline']) cons_choice_rounds = len(tasks_cons_choice['baseline']) risk_rounds = len(tasks_risk['baseline']) class Subsession(BaseSubsession): """Contains subsession-level objects of the current experiment app.""" def before_session_starts(self): """Depending on session configs, get respective list of treatment conditions from constants. Then distribute treatment conditions and groups to participants. """ if self.round_number == 1: for p in self.get_players(): p.participant.vars['condition_risk'] = random.choice(['baseline', 'treatment']) p.participant.vars['condition_time'] = random.choice(['baseline', 'treatment']) p.participant.vars['condition_wine'] = random.choice(['baseline']) blocks_and_pages_shuffled_risk = random.sample([random.choice([[0, 1], [0, 1]]), random.choice([[2, 3], [3, 2]])], 2) blocks_and_pages_shuffled_time = random.sample([random.choice([[0, 1], [0, 1]]), random.choice([[2, 3], [3, 2]])], 2) p.participant.vars['page_sequence_risk'] = [item for sublist in blocks_and_pages_shuffled_risk for item in sublist] p.participant.vars['page_sequence_time'] = [item for sublist in blocks_and_pages_shuffled_time for item in sublist] p.participant.vars['page_sequence_wine'] = random.sample(range(0, 3), 3) for p in self.get_players(): p.condition_risk = p.participant.vars['condition_risk'] p.condition_time = p.participant.vars['condition_time'] p.condition_cons_choice = p.participant.vars['condition_wine'] p.set_current_task_number() class Group(BaseGroup): """Contains group-level objects of the current experiment app.""" pass class Player(BasePlayer): """Contains player-level objects of the current experiment app.""" task_identifier = models.StringField() condition_risk = models.StringField() condition_time = models.StringField() condition_cons_choice = models.StringField() control_time = models.IntegerField() control_probability = models.IntegerField() control_variable = models.IntegerField() choice_time = models.CharField() choice_risk = models.CharField() choice_wine = models.CharField() def set_current_task_number(self): if self.round_number <= Constants.intertemporal_rounds: index = self.participant.vars['page_sequence_time'][self.round_number - 1] setattr(self, 'task_identifier', Constants.tasks_intertemporal[self.condition_time][index]['name']) elif self.round_number > Constants.intertemporal_rounds + Constants.cons_choice_rounds: index = self.participant.vars['page_sequence_risk'][self.round_number - Constants.intertemporal_rounds - Constants.cons_choice_rounds - 1] setattr(self, 'task_identifier', Constants.tasks_risk[self.condition_risk][index]['name']) else: index = self.participant.vars['page_sequence_wine'][self.round_number - Constants.intertemporal_rounds - 1] setattr(self, 'task_identifier', Constants.tasks_cons_choice[self.condition_cons_choice][index]['name']) def specification(self): if self.round_number <= Constants.intertemporal_rounds: index = self.participant.vars['page_sequence_time'][self.round_number - 1] return Constants.tasks_intertemporal[self.condition_time][index]['specification'] elif self.round_number > Constants.intertemporal_rounds + Constants.cons_choice_rounds: index = self.participant.vars['page_sequence_risk'][self.round_number - Constants.intertemporal_rounds - Constants.cons_choice_rounds - 1] return Constants.tasks_risk[self.condition_risk][index]['specification'] else: index = self.participant.vars['page_sequence_wine'][self.round_number - Constants.intertemporal_rounds - 1] return Constants.tasks_cons_choice[self.condition_cons_choice][index]['specification'] # def set_type(self): # index = self.participant.vars['page_sequence_vign'][self.round_number - 1] # return Constants.task_sets[int(self.round_number-1)][index]['type']