from otree.api import * import pandas as pd import numpy as np doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'task' PLAYERS_PER_GROUP = None NUM_ROUNDS = 20 answer_A = [ 78, 92, 107, 82, 49, 77, 60, 85, 71, 57, 55, 70, 85, 79, 44, 99, 58, 95, 91, 62 ] answer_B = [ 66, 81, 91, 76, 87, 85, 79, 88, 75, 104, 81, 98, 97, 62, 76, 73, 61, 62, 103, 82 ] class Subsession(BaseSubsession): def df(self): return pd.DataFrame() def date(delf): return str() class Group(BaseGroup): pass class Player(BasePlayer): csv_input = models.LongStringField( label="請上傳您的 CSV 檔案:" ) date = models.StringField( label= "請選擇您的實驗日期:", choices=['今天', '7 天後', '14 天後', '21 天後'], ) user_id = models.StringField( label="請輸入您的學號(英文字母請輸入小寫):" ) version = models.StringField( label="請選擇您拿到的版本(A 卷或 B 卷):", widget=widgets.RadioSelect, choices=['A', 'B'], ) task = models.IntegerField( label="請輸入表格中「0」的數量:", min=0, max=150, ) task_record = models.StringField( initial='', ) # PAGES class Login(Page): form_model = 'player' form_fields = ['user_id', 'version'] @staticmethod def error_message(player, values): if values['user_id'] != 'admin': if Subsession.df.empty: return '請稍後再試!' elif values['user_id'] not in Subsession.df['user_id'].values: return '請輸入正確的學號!' @staticmethod def before_next_page(player, timeout_happened): if player.user_id != 'admin': player.participant.version = player.version player.participant.random_money = int(Subsession.df.loc[Subsession.df['user_id'] == player.user_id, 'random_money'].values[0]) player.participant.date_money = str(Subsession.df.loc[Subsession.df['user_id'] == player.user_id, 'date_money'].values[0]) player.participant.amount_money = int(Subsession.df.loc[Subsession.df['user_id'] == player.user_id, 'amount_money'].values[0]) player.participant.random_effort = int(Subsession.df.loc[Subsession.df['user_id'] == player.user_id, 'random_effort'].values[0]) player.participant.date_effort = str(Subsession.df.loc[Subsession.df['user_id'] == player.user_id, 'date_effort'].values[0]) player.participant.amount_effort = int(Subsession.df.loc[Subsession.df['user_id'] == player.user_id, 'amount_effort'].values[0]) player.participant.user_id = player.user_id @staticmethod def is_displayed(player): return player.round_number == 1 class Admin_input(Page): form_model = 'player' form_fields = ['csv_input', 'date'] @staticmethod def before_next_page(player, timeout_happened): if player.user_id == 'admin': player.participant.date_effort = player.date # 輸入日期 Subsession.date = player.date # 輸入 CSV 檔案 csv_data = player.csv_input.split('\r\n') header = csv_data[0].split(',') # 假设标题在 CSV 数据的第一行 data_rows = [row.split(',') for row in csv_data[1:]] # 数据从第二行开始 Subsession.df = pd.DataFrame(data_rows, columns=header) # 使用指定的标题创建 DataFrame # 格式 columns_to_convert_1 = ["money_1","money_2","effort_1","effort_2"] Subsession.df[columns_to_convert_1] = Subsession.df[columns_to_convert_1].astype(int) columns_to_convert_2 = ["random_money", "amount_money", "random_effort", "amount_effort"] Subsession.df[columns_to_convert_2] = Subsession.df[columns_to_convert_2].astype(int) @staticmethod def is_displayed(player): return (player.participant.user_id == 'admin' and player.round_number == 1) class Results(Page): @staticmethod def vars_for_template(player): return dict( random_money = player.participant.random_money, date_money = player.participant.date_money, amount_money = player.participant.amount_money, random_effort = player.participant.random_effort, date_effort = player.participant.date_effort, amount_effort = player.participant.amount_effort, ) @staticmethod def is_displayed(player): return (player.participant.user_id != 'admin' and player.round_number == 1) class Task(Page): form_model = 'player' form_fields = ['task'] @staticmethod def error_message(player: Player, values): if player.participant.version == 'A': if values['task'] != C.answer_A[player.round_number-1]: player.task_record += str(values['task']) + ',' return '答案錯誤!請重新再試!' elif player.participant.version == 'B': if values['task'] != C.answer_B[player.round_number-1]: player.task_record += str(values['task']) + ',' return '答案錯誤!請重新再試!' @staticmethod def is_displayed(player): return (player.participant.user_id != 'admin' and player.round_number <= player.participant.amount_effort and player.participant.date_effort == Subsession.date) @staticmethod def vars_for_template(player: Player): return dict( round_number = player.round_number, amount_effort = player.participant.amount_effort, ) class End(Page): @staticmethod def is_displayed(player): return player.round_number == C.NUM_ROUNDS @staticmethod def vars_for_template(player: Player): return dict( today = 1 if player.participant.date_effort == Subsession.date else 0, ) page_sequence = [Login, Admin_input, Results, Task, End]