from otree.api import ( Page, WaitPage, models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import csv import random import json doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'ht_pilot' players_per_group = None num_rounds = 4 with open('ht_pilot/2x2.csv') as f: questions = list(csv.DictReader(f)) with open('ht_pilot/2x3.csv') as f: questions2 = list(csv.DictReader(f)) class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): num_a = models.StringField() num_b = models.StringField() answer = models.StringField() responses = models.StringField(initial="[]") num_correct = models.IntegerField(initial=0) num_incorrect = models.IntegerField(initial=0) finished = models.BooleanField(initial=0) num_a_2x3 = models.StringField() num_b_2x3 = models.StringField() answer_2x3 = models.StringField() responses_2x3 = models.StringField(initial="[]") num_correct_2x3 = models.IntegerField(initial=0) num_incorrect_2x3 = models.IntegerField(initial=0) def make_field1(label): return models.IntegerField( choices=[ [1, "1 (Very Low Effort)"], [2, "2"], [3, "3"], [4, "4 (Moderate Effort)"], [5, "5"], [6, "6"], [7, "7 (Very High Effort)"] ], label=label, widget=widgets.RadioSelectHorizontal, ) peq1 = make_field1('1. How much effort did you devote to performing well in the Type 1 ' '(subtracting two-digit from two-digit numbers in Round 1) math task?') peq2 = make_field1('2. How much effort did you devote to performing well in the Type 2 ' '(subtracting two-digit from three-digit numbers in Round 2) math task?') peq3 = make_field1('3. How much effort did you devote to performing well in the Type 3 ' '(subtracting two-digit from three-digit numbers with the slider in Rounds 3-12) math task?') def make_field2(label): return models.IntegerField( choices=[ [1, "1 (Not at all interesting)"], [2, "2"], [3, "3"], [4, "4 (Moderately interesting)"], [5, "5"], [6, "6"], [7, "7 (Very interesting)"] ], label=label, widget=widgets.RadioSelectHorizontal, ) peq4 = make_field2('How interesting did you find the Type 1 ' '(subtracting two-digit from two-digit numbers in Round 1) math task? ') peq5 = make_field2('How interesting did you find the Type 2 ' '(subtracting two-digit from three-digit numbers in Round 2) math task? ') peq6 = make_field2('How interesting did you find the Type 3 ' '(subtracting two-digit from three-digit numbers with the slider in Rounds 3-12) math task? ') total_strategy = models.LongStringField( label='Please describe your strategy (if any) during Rounds 3-12.' ) strategy_change = models.LongStringField( label='Did your strategy change during Rounds 3-12? If so, please describe how.' ) gender = models.IntegerField( label='Gender Identification:', choices=[ [1, 'Male'], [2, 'Female'], [3, 'Other'], [4, 'Prefer not to answer'] ], widget=widgets.RadioSelect) age = models.IntegerField( min=18, label='Age (in years):') grade_status = models.IntegerField( label='Current grade status', choices=[ [1, 'Freshman'], [2, 'Sophomore'], [3, 'Junior'], [4, 'Senior'], [5, 'Graduate'] ], widget=widgets.RadioSelect) major = models.StringField( label='What is your academic major? (answer "none" or "undecided" if applicable):' ) gpa = models.FloatField( label='What is your GSU GPA?' ) math = models.IntegerField( label='How many college-level math classes have you taken? (answer with a number)' ) # FUNCTIONS def creating_session(subsession: Subsession): num_questions = len(Constants.questions) num_questions_2x3 = len(Constants.questions2) for p in subsession.get_players(): p.participant.vars['total_attempted'] = 0 p.participant.vars['question_sequence'] = random.sample(range(num_questions), num_questions) q = p.participant.vars['question_sequence'][0] p.num_a = Constants.questions[q]['num_a'] p.num_b = Constants.questions[q]['num_b'] p.answer = Constants.questions[q]['answer'] p.participant.vars['total_attempted_2x3'] = 0 p.participant.vars['question_sequence_2x3'] = random.sample(range(num_questions_2x3), num_questions_2x3) q = p.participant.vars['question_sequence_2x3'][0] p.num_a_2x3 = Constants.questions2[q]['num_a'] p.num_b_2x3 = Constants.questions2[q]['num_b'] p.answer_2x3 = Constants.questions2[q]['answer'] # PAGES class Page1_General(Page): def is_displayed(player): return player.round_number == 1 class TaskInformation(Page): def is_displayed(player): return player.round_number == 1 class Feedback_Earnings(Page): def is_displayed(player): return player.round_number == 1 class Procedures(Page): def is_displayed(player): return player.round_number == 1 class TwoDigit(Page): timeout_seconds = 60 def is_displayed(player): return player.round_number == 1 def live_method(player, data): print(player.num_a, player.num_b) player.participant.vars['total_attempted'] += 1 print("participant total attempted", player.participant.vars['total_attempted']) if data == player.answer: player.num_correct += 1 else: player.num_incorrect += 1 #record the response; convert to/from string/list # lst = json.loads(player.responses) print("response", data) # lst.append(data) # player.responses = json.dumps(lst) print("correct answer", player.answer) print("number correct", player.num_correct) print("number incorrect", player.num_incorrect) # Check to see if any questions left num_completed = player.num_correct + player.num_incorrect if num_completed < len(Constants.questions): q = player.participant.vars['question_sequence'][player.participant.vars['total_attempted']] player.num_a = Constants.questions[q]['num_a'] player.num_b = Constants.questions[q]['num_b'] player.answer = Constants.questions[q]['answer'] else: player.finished = True msg = { 'num_a': player.num_a, 'num_b': player.num_b, 'answer': player.answer, 'finished': player.finished, 'num_correct': player.num_correct, 'num_incorrect': player.num_incorrect, } return {player.id_in_group: msg} class Results(Page): def vars_for_template(player): question_total = player.num_correct + player.num_incorrect question_total_2x3 = player.num_correct_2x3 + player.num_incorrect_2x3 return dict( question_total=question_total, question_total_2x3=question_total_2x3, ) class TwobyThree(Page): timeout_seconds = 60 def is_displayed(player): return player.round_number == 2 def live_method(player, data): print(player.num_a_2x3, player.num_b_2x3) player.participant.vars['total_attempted_2x3'] += 1 print("participant total attempted", player.participant.vars['total_attempted_2x3']) if data == player.answer_2x3: player.num_correct_2x3 += 1 else: player.num_incorrect_2x3 += 1 # record the response; convert to/from string/list # lst = json.loads(player.responses) print("response", data) # lst.append(data) # player.responses = json.dumps(lst) print("correct answer", player.answer_2x3) print("number correct", player.num_correct_2x3) print("number incorrect", player.num_incorrect_2x3) # Check to see if any questions left num_completed_2x3 = player.num_correct_2x3 + player.num_incorrect_2x3 if num_completed_2x3 < len(Constants.questions2): q = player.participant.vars['question_sequence_2x3'][player.participant.vars['total_attempted_2x3']] player.num_a_2x3 = Constants.questions2[q]['num_a'] player.num_b_2x3 = Constants.questions2[q]['num_b'] player.answer_2x3 = Constants.questions2[q]['answer'] else: player.finished = True msg = { 'num_a_2x3': player.num_a_2x3, 'num_b_2x3': player.num_b_2x3, 'answer_2x3': player.answer_2x3, 'finished': player.finished, 'num_correct_2x3': player.num_correct_2x3, 'num_incorrect_2x3': player.num_incorrect_2x3, } return {player.id_in_group: msg} class Slider(Page): timeout_seconds = 60 def is_displayed(player): return player.round_number >= 3 def live_method(player, data): print(player.num_a_2x3, player.num_b_2x3) player.participant.vars['total_attempted_2x3'] += 1 print("participant total attempted", player.participant.vars['total_attempted_2x3']) if data == player.answer_2x3: player.num_correct_2x3 += 1 else: player.num_incorrect_2x3 += 1 # record the response; convert to/from string/list # lst = json.loads(player.responses) print("response", data) # lst.append(data) # player.responses = json.dumps(lst) print("correct answer", player.answer_2x3) print("number correct", player.num_correct_2x3) print("number incorrect", player.num_incorrect_2x3) # Check to see if any questions left num_completed_2x3 = player.num_correct_2x3 + player.num_incorrect_2x3 if num_completed_2x3 < len(Constants.questions2): q = player.participant.vars['question_sequence_2x3'][player.participant.vars['total_attempted_2x3']] player.num_a_2x3 = Constants.questions2[q]['num_a'] player.num_b_2x3 = Constants.questions2[q]['num_b'] player.answer_2x3 = Constants.questions2[q]['answer'] else: player.finished = True msg = { 'num_a_2x3': player.num_a_2x3, 'num_b_2x3': player.num_b_2x3, 'answer_2x3': player.answer_2x3, 'finished': player.finished, 'num_correct_2x3': player.num_correct_2x3, 'num_incorrect_2x3': player.num_incorrect_2x3, } return {player.id_in_group: msg} class PEQ1(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds form_model = 'player' form_fields = ['peq1', 'peq2', 'peq3', 'peq4', 'peq5', 'peq6', ] class PEQ2(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds form_model = 'player' form_fields = ['total_strategy', 'strategy_change', ] class PEQ3(Page): def is_displayed(player: Player): return player.round_number == Constants.num_rounds form_model = 'player' form_fields = ['gender', 'age', 'grade_status', 'major', 'gpa', 'math', ] page_sequence = [Page1_General, TaskInformation, Feedback_Earnings, Procedures, TwoDigit, TwobyThree, Slider, Results, PEQ1, PEQ2, PEQ3]