from otree.api import * from otree.api import models, Page, WaitPage import time doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'two_dimensional_dictator_game' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 1 materials_survey_part1 = { "field": models.IntegerField, "items": { "q1": { "question": """ Q. 先ほどの作業は楽しかったですか、それとも、つまらなかったですか? """, "opts": [ [1, "とても楽しい"], [2, "   楽しい  "], [3, " やや楽しい "], [4, "どちらでもない"], [5, "ややつまらない"], [6, " つまらない "], [7, "とてもつまらない"], ], }, "q2": { "question": """ Q. 先ほどの作業は苦痛でしたか、それとも、苦痛ではなかったですか? """, "opts": [ [1, "とても苦痛"], [2, "  苦痛  "], [3, " やや苦痛 "], [4, "どちらでもない"], [5, "ほぼ苦痛でない"], [6, " 苦痛でない "], [7, "全く苦痛でない"], ], }, "q3": { "question": """ Q. 先ほどの作業は簡単でしたか、それとも、難しかったですか? """, "opts": [ [1, "とても簡単"], [2, "  簡単  "], [3, " やや簡単" ], [4, "どちらでもない"], [5, "やや難しい"], [6, " 難しい "], [7, "とても難しい"], ], } } } class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): for g in subsession.get_groups(): if g.id_in_subsession % 5 == 1: g.treatment = 1 elif g.id_in_subsession % 5 == 2: g.treatment = 2 g.TaskAllocation = 5 elif g.id_in_subsession % 5 == 3: g.treatment = 3 g.MoneyAllocation = 500 elif g.id_in_subsession % 5 == 4: g.treatment = 4 else: g.treatment = 5 g.TaskAllocation = 5 class Group(BaseGroup): MoneyAllocation = models.IntegerField( choices=list(range(0, 1100, 100)), widget=widgets.RadioSelectHorizontal, blank=True ) TaskAllocation = models.IntegerField( choices=list(range(11)), widget=widgets.RadioSelectHorizontal, blank=True ) treatment = models.IntegerField(default = 1) class Player(BasePlayer): payoff_Part1 = models.IntegerField(default = 0) payoff_Part2 = models.IntegerField(default = 500) Count = models.IntegerField(default= -1) TaskQuota = models.IntegerField(default=5) Start_0 = models.FloatField(blank=True) Finish_0 = models.FloatField(blank=True) Time_0 = models.FloatField(blank=True, default=0) Start_1 = models.FloatField(blank=True, default=0) # 作業ページ10セット分 for i in range(1, 11): setattr(Player, f'Finish_{i}', models.FloatField(blank=True, default = 0)) # Part1のアンケート for k, v in C.materials_survey_part1["items"].items(): setattr( Player, k, C.materials_survey_part1["field"]( label = v["question"], choices = v["opts"], widget = widgets.RadioSelectHorizontal ) ) def set_payoffs(group: Group): players = group.get_players() for player in players: player.Time_0 = round(player.Finish_0 - player.Start_0, 2) if player.Time_0 <= 30: player.payoff_Part1 = 400 elif player.Time_0 <= 45: player.payoff_Part1 = 350 elif player.Time_0 <= 60: player.payoff_Part1 = 300 elif player.Time_0 <= 75: player.payoff_Part1 = 250 elif player.Time_0 <= 90: player.payoff_Part1 = 200 elif player.Time_0 <= 100: player.payoff_Part1 = 150 elif player.Time_0 <= 110: player.payoff_Part1 = 100 elif player.Time_0 <= 120: player.payoff_Part1 = 50 else: player.payoff_Part1 = 0 if group.treatment == 4: if player.id_in_group == 1: player.payoff_Part2 = group.MoneyAllocation player.TaskQuota = 10 - group.TaskAllocation else: player.payoff_Part2 = 1000 - group.MoneyAllocation player.TaskQuota = group.TaskAllocation else: if player.id_in_group == 1: player.payoff_Part2 = group.MoneyAllocation player.TaskQuota = group.TaskAllocation else: player.payoff_Part2 = 1000 - group.MoneyAllocation player.TaskQuota = 10 - group.TaskAllocation player.payoff = player.payoff_Part1 + player.payoff_Part2 ##################################################### ##################### PAGES ######################### ##################################################### class Overview(Page): pass class Slider(Page): template_name = 'two_dimensional_dictator_game/Slider.html' form_model = 'player' @staticmethod def before_next_page(player, timeout_happened): start_time_attr = 'Finish_{}'.format(player.Count) setattr(player, start_time_attr, time.time()) player.Count += 1 @staticmethod def is_displayed(player): return player.Count <= player.TaskQuota class TaskPractice(Slider): timeout_seconds = 30 timer_text = '' @staticmethod def before_next_page(player, timeout_happened): player.Count += 1 class Preparation1(Page): timeout_seconds = 10 timer_text = '' form_model = 'player' form_fields = ['Start_0'] @staticmethod def before_next_page(player, timeout_happened): player.Start_0 = time.time() class Task0(Slider): form_fields = ['Finish_0'] class SurveyPart1(Page): form_model = 'player' form_fields = ['q1', 'q2', 'q3'] class WaitForPart2(Page): template_name = 'two_dimensional_dictator_game/WaitDummy.html' class InstructionPart2(Page): pass class Dictator(Page): form_model = 'group' form_fields = ['TaskAllocation', 'MoneyAllocation'] @staticmethod def is_displayed(player): return player.id_in_group == 1 or (player.group.treatment == 4 and player.id_in_group == 2) class WaitForResults(WaitPage): template_name = 'two_dimensional_dictator_game/WaitPage.html' body_text = '' title_text = '' after_all_players_arrive = 'set_payoffs' class Results(Page): @staticmethod def vars_for_template(player: Player): return dict( payoff12 = player.payoff_Part1 + player.payoff_Part2, payoff123 = player.payoff_Part1 + player.payoff_Part2 + 1200, RivalTasks = 10 - player.TaskQuota, RivalMoney = 1000 - player.payoff_Part2 ) class Preparation2(Page): timeout_seconds = 15 timer_text = '' form_model = 'player' form_fields = ['Start_1'] @staticmethod def before_next_page(player, timeout_happened): player.Start_1 = time.time() @staticmethod def is_displayed(player): return player.TaskQuota != 0 tasks = [] for i in range(1, 11): task_class = type('Task{}'.format(i), (Slider,), {'form_fields': ['Finish_{}'.format(i)]}) tasks.append(task_class) page_sequence = [ Overview, TaskPractice, Preparation1, Task0, SurveyPart1, WaitForPart2, InstructionPart2, Dictator, WaitForResults, Results, Preparation2] + tasks