from otree.api import * import random import pandas as pd author = 'Wonwoo Bae' doc = """ Diagnostic Expectations (Individual Decision Making) """ class C(BaseConstants): NAME_IN_URL = 'diagnostic_belief_updating' PLAYERS_PER_GROUP = None NUM_ROUNDS = 20 incentive = [5000, 15000] penalty = [50, 75] df = {} for i in range(30): df[i] = pd.read_excel("_static/oTree_data-Korean.xlsx", sheet_name='participant_{}'.format(i + 1), header=0) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): signal_conjecture_o = models.IntegerField(label="귀하의 추론 (%): 0에서 100사이의 숫자를 입력해주세요.", min=0, max=100) signal_conjecture_b = models.IntegerField(label="귀하의 추론 (%): 0에서 100사이의 숫자를 입력해주세요.", min=0, max=100) conjecture = models.IntegerField(label="귀하의 추론 (%): 0에서 100사이의 숫자를 입력해주세요.", min=0, max=100) confidence = models.IntegerField(label="귀하의 추론에 확신하는 정도 (%):", min=0, max=100) check_slider = models.IntegerField() payoff_round_signal_color = models.StringField() payoff_round_signal = models.CurrencyField(label="귀하의 이번 라운드 보수:") payoff_selround_signal_color = models.StringField() payoff_selround_signal = models.CurrencyField() payoff_roundnum_signal = models.IntegerField() payoff_round = models.CurrencyField(label="귀하의 이번 라운드 보수:") payoff_selround = models.CurrencyField() payoff_roundnum = models.IntegerField() q1 = models.IntegerField(choices=[[1, '어떤 라운드에서도 모집단 상자의 구성을 관찰할 수 없습니다.'], [2, '각 라운드가 시작할 때, 모집단 상자의 구성을 관찰할 수 있습니다.']], widget=widgets.RadioSelectHorizontal, label="다음 중 모집단 상자에 대한 설명으로 옳은 것은 무엇입니까?") q2 = models.IntegerField(choices=[[1, '각 라운드가 시작할 때, 표본 상자의 구성을 관찰할 수 없습니다.'], [2, '각 라운드가 시작할 때, 표본 상자의 구성을 관찰할 수 있습니다.']], widget=widgets.RadioSelectHorizontal, label="다음 중 표본 상자에 대한 설명으로 옳은 것은 무엇입니까?") q3 = models.IntegerField(choices=[[1, '각 라운드에서, 표본 상자는 동일한 색상의 모집단 상자와 동일한 공 조합을 가집니다.'], [2, '각 라운드에서, 표본 상자는 동일한 색상의 모집단 상자와 다른 공 조합을 가질 수 있습니다.']], widget=widgets.RadioSelectHorizontal, label="다음 중 표본 상자에 대한 설명으로 옳은 것은 무엇입니까?") q4 = models.IntegerField(choices=[[1, '각 라운드에서, 신호 상자는 동일한 색상의 표본 상자와 동일한 공 조합을 가집니다.'], [2, '각 라운드에서, 신호 상자는 동일한 색상의 표본 상자와 다른 공 조합을 가질 수 있습니다.']], widget=widgets.RadioSelectHorizontal, label="다음 중 신호 상자에 대한 설명으로 옳은 것은 무엇입니까?") q5 = models.IntegerField(choices=[[1, '상자에서 세 자리 숫자 공이 무작위로 추첨된 경우, 다음 추첨에서 세 자리 숫자 공이 선택될 확률은 감소합니다.'], [2, '상자에서 세 자리 숫자 공이 무작위로 추첨된 경우, 다음 추첨에서 세 자리 숫자 공이 선택될 확률은 동일합니다.']], widget=widgets.RadioSelectHorizontal, label="다음 중 공의 무작위 추첨에 대한 설명으로 옳은 것은 무엇입니까?") q6 = models.IntegerField(choices=[[1, '두 개의 표본 상자의 구성을 관찰한 후, 모집단 상자의 실제 구성 X를 추론합니다.'], [2, '두 개의 신호 상자의 구성을 관찰한 후, 표본 상자의 실제 구성 X를 추론합니다.']], widget=widgets.RadioSelectHorizontal, label="다음 중 귀하의 의사 결정에 대한 설명으로 옳은 것은 무엇입니까?") read = models.IntegerField(initial=-1) retrieval_start = models.FloatField() conjecture_start = models.FloatField() signal_conjecture_start = models.FloatField() retrieval_duration = models.FloatField() signal_conjecture_duration = models.FloatField() conjecture_duration = models.FloatField() age = models.IntegerField(min=19, label="귀하의 나이는 어떻게 되십니까?") sex = models.IntegerField(widget=widgets.RadioSelect, choices=[[1, '남성'], [2, '여성']], label="귀하의 성별은 무엇입니까?") education = models.IntegerField(widget=widgets.RadioSelect, choices=[[1, '고졸'], [2, '학사'], [3, '석사'], [4, '박사']], label="귀하의 최종 학력은 어떻게 되십니까?") major = models.StringField(label="귀하의 전공 (소속/졸업 학부(과))은 무엇입니까?") knowledge = models.IntegerField(widget=widgets.RadioSelect, choices=[[1, '예'], [2, '아니오']], label="귀하는 확률 이론과 통계학 이론에 익숙하다고 생각하십니까?") color_b = models.IntegerField(widget=widgets.RadioSelect, choices=[[1, '오렌지색'], [2, '파란색']], label="위의 숫자는 무슨 색입니까?") color_o = models.IntegerField(widget=widgets.RadioSelect, choices=[[1, '오렌지색'], [2, '파란색']], label="위의 도형은 무슨 색입니까?") certainty = models.FloatField(min=0, max=30000, label="귀하는 위의 복권이 몇 원을 확실히 얻는 것과 동일한 가치가 있다고 생각하십니까?") feedback = models.LongStringField(label="본 실험에 대한 의견 (실험의 난이도, 보수 책정 방식 등)이 있다면 공유해주시기 바랍니다. 의견이 없으시면 0을 입력해주세요.") # FUNCTIONS def payoff_decision_signal(player: Player, local_seed): local_random = random.Random(local_seed + player.id_in_group) round_sel = local_random.randint(1, C.NUM_ROUNDS) player = player.in_round(round_sel) return player.payoff_round_signal_color, player.payoff_round_signal, round_sel def payoff_decision(player: Player, local_seed): local_random = random.Random(local_seed + player.id_in_group) round_sel = local_random.randint(1, C.NUM_ROUNDS) player = player.in_round(round_sel) return player.payoff_round, round_sel # PAGES class Instructions_Korean(Page): form_model = 'player' form_fields = ['q1', 'q2', 'q3', 'q4', 'q5', 'q6'] def is_displayed(player: Player): return player.round_number == 1 @staticmethod def live_method(player: Player, data): if data['read'] == 1: if player.read == -1: player.read = 1 return {player.id_in_group: {'read': player.read}} @staticmethod def vars_for_template(player: Player): correct_answers = {"q1": 2, "q2": 1, "q3": 2, "q4": 2, "q5": 2, "q6": 2} return {'correct_answers' : correct_answers, 'incentive_signal': int(C.incentive[0]), 'penalty_signal': int(C.penalty[0]), 'incentive': int(C.incentive[1]), 'penalty': int(C.penalty[1]), 'num_rounds': C.NUM_ROUNDS, } class RoundWaitPage(WaitPage): def is_displayed(player: Player): return player.subsession.round_number == 1 class RoundStart_Korean(Page): def is_displayed(player: Player): return player.subsession.round_number == 1 class MotherUrnsImage_Korean(Page): @staticmethod def vars_for_template(player: Player): player_id = player.id_in_group ind = player_id - 1 round_num = player.round_number return dict( round_num = round_num, os_num = int(list(C.df[ind].loc[C.df[ind]['round']==player.round_number, 'os'])[0]), on_num = int(list(C.df[ind].loc[C.df[ind]['round']==player.round_number, 'on'])[0]), bs_num = int(list(C.df[ind].loc[C.df[ind]['round']==player.round_number, 'bs'])[0]), bn_num = int(list(C.df[ind].loc[C.df[ind]['round']==player.round_number, 'bn'])[0]), image_path = 'https://raw.githubusercontent.com/wonwoobae/experiment-data/main/pilot-session-7/Participant_{}/Mother_Round_{}.png'.format(player_id, round_num) ) class SignalUrnsImage_Korean(Page): timeout_seconds = 10 timer_text = "남은 시간" @staticmethod def vars_for_template(player: Player): player_id = player.id_in_group round_num = player.round_number return dict( round_num=round_num, image_path = 'https://raw.githubusercontent.com/wonwoobae/experiment-data/main/pilot-session-7/Participant_{}/Signal_Round_{}.png'.format( player_id, round_num) ) @staticmethod def before_next_page(player: Player, timeout_happened): import time player.retrieval_start = time.time() class Retrieval_Korean(Page): @staticmethod def vars_for_template(player: Player): return dict( round_num=player.round_number ) @staticmethod def before_next_page(player: Player, timeout_happened): import time player.retrieval_duration = time.time() - player.retrieval_start player.signal_conjecture_start = time.time() class Signal_Conjecture_Korean(Page): form_model = 'player' form_fields = ['signal_conjecture_o', 'signal_conjecture_b'] @staticmethod def vars_for_template(player: Player): ind = player.id_in_group - 1 so_true = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'Signal_Orange_True'])[0] so_state = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'Signal_Orange_State'])[0] sb_true = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'Signal_Blue_True'])[0] sb_state = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'Signal_Blue_State'])[0] round_num = player.round_number return dict( round_num = round_num, so_true = so_true, so_state = so_state, sb_true = sb_true, sb_state = sb_state, ) @staticmethod def before_next_page(player: Player, timeout_happened): import time player.signal_conjecture_duration = time.time() - player.signal_conjecture_start player.conjecture_start = time.time() class Conjecture_Korean(Page): form_model = 'player' form_fields = ['conjecture'] @staticmethod def vars_for_template(player: Player): ind = player.id_in_group - 1 X = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'X'])[0] true_urn = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'X_color'])[0] if true_urn == "오렌지색": color = "#f28e2b" elif true_urn == "파란색": color = "#4e79a7" round_num = player.round_number return dict( round_num = round_num, color = color, urn = true_urn, X = X, ) @staticmethod def before_next_page(player: Player, timeout_happened): import time player.conjecture_duration = time.time() - player.conjecture_start class Confidence_Korean(Page): form_model = 'player' form_fields = ['confidence', 'check_slider'] @staticmethod def error_message(player, value): if value["check_slider"] == None: return '슬라이더를 이용해 귀하의 추론에 대한 확신의 정도를 나타내주세요.' @staticmethod def vars_for_template(player: Player): ind = player.id_in_group - 1 X = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'X'])[0] true_urn = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'X_color'])[0] if true_urn == "오렌지색": color = "#f28e2b" elif true_urn == "파란색": color = "#4e79a7" round_num = player.round_number return dict( round_num = round_num, color = color, conjecture=player.conjecture, conjecture_ub = min(player.conjecture+1, 100), conjecture_lb = max(player.conjecture-1, 0), urn = true_urn, X = X, ) class NoResults_Korean(Page): @staticmethod def vars_for_template(player: Player): player_id = player.id_in_group ind = player.id_in_group - 1 round_num = player.round_number true = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'true_value'])[0] so_true = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'Signal_Orange_True'])[0] sb_true = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'Signal_Blue_True'])[0] rnd = random.randint(0,1) if rnd == 0: player.payoff_round_signal_color = "오렌지색" player.payoff_round_signal = max(C.incentive[0] - C.penalty[0] * \ (so_true * 4 - player.signal_conjecture_o) ** 2, 0) elif rnd == 1: player.payoff_round_signal_color = "파란색" player.payoff_round_signal = max(C.incentive[0] - C.penalty[0] * \ (sb_true * 4 - player.signal_conjecture_b) ** 2, 0) player.payoff_round = max(C.incentive[1] - C.penalty[1] * \ (true * 4 - player.conjecture) ** 2, 0) return dict( round_num = round_num, conjecture1 = player.signal_conjecture_o, conjecture2 = player.signal_conjecture_b, conjecture = player.conjecture, answer_key1 = so_true, answer_key2 = sb_true, answer_key = true, payoff_round_signal_color = player.payoff_round_signal_color, payoff_round_signal = player.payoff_round_signal, payoff_round = player.payoff_round, ) @staticmethod def before_next_page(player: Player, timeout_happened): if player.round_number == C.NUM_ROUNDS: player.payoff_selround_signal_color, player.payoff_selround_signal, player.payoff_roundnum_signal \ = payoff_decision_signal(player, random.randint(0, 1000)) player.payoff_selround, player.payoff_roundnum = payoff_decision(player, random.randint(0, 1000)) player.participant.payoff = player.payoff_selround_signal + player.payoff_selround # class Results_Korean(Page): # @staticmethod # def vars_for_template(player: Player): # player_id = player.id_in_group # ind = player.id_in_group - 1 # round_num = player.round_number # X = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'X'])[0] # true_urn = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'X_color'])[0] # player.payoff_round = max(C.incentive - C.penalty * \ # (list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'true_value'])[ # 0] * 4 - player.conjecture) ** 2, 0) # return dict( # round_num = round_num, # conjecture = player.conjecture, # urn = true_urn, # X = X, # answer_key = list(C.df[ind].loc[C.df[ind]['round'] == player.round_number, 'true_value'])[0] * 4, # payoff_round = player.payoff_round, # ) class Payoff_Korean(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): so_conjecture_dict = {} sb_conjecture_dict = {} conjecture_dict = {} signal_payoff_color_dict = {} signal_payoff_dict = {} payoff_dict = {} for i in range(C.NUM_ROUNDS): player_each_round = player.in_round(i+1) so_conjecture_dict[i] = player_each_round.signal_conjecture_o sb_conjecture_dict[i] = player_each_round.signal_conjecture_b signal_payoff_color_dict[i] = player_each_round.payoff_round_signal_color signal_payoff_dict[i] = int(player_each_round.payoff_round_signal) conjecture_dict[i] = player_each_round.conjecture payoff_dict[i] = int(player_each_round.payoff_round) return dict(final_payoff = player.participant.payoff, total_payment = player.participant.payoff_plus_participation_fee(), selround_signal_color = player.payoff_selround_signal_color, round_sel_signal = player.payoff_roundnum_signal, round_sel = player.payoff_roundnum, so_conjecture_dict = so_conjecture_dict, sb_conjecture_dict = sb_conjecture_dict, signal_payoff_color_dict = signal_payoff_color_dict, signal_payoff_dict = signal_payoff_dict, conjecture_dict = conjecture_dict, payoff_dict = payoff_dict, total_num = C.NUM_ROUNDS, ) class ExitSurvey_Korean(Page): form_model = 'player' form_fields = ['age', 'sex', 'education', 'major', 'knowledge', 'color_b', 'color_o', 'certainty', 'feedback'] def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS class ExitLink_Korean(Page): def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS page_sequence = [Instructions_Korean, RoundWaitPage, RoundStart_Korean, MotherUrnsImage_Korean, SignalUrnsImage_Korean, Retrieval_Korean, Signal_Conjecture_Korean, Conjecture_Korean, Confidence_Korean, NoResults_Korean, Payoff_Korean, ExitSurvey_Korean, ExitLink_Korean]