from otree.api import * author = "Henrik Orzen" doc = """ Guesstimations Main task """ class C(BaseConstants): NAME_IN_URL = 'Guesstimation' PLAYERS_PER_GROUP = None NUM_ROUNDS = 2 TIME_ALERT = 30 Q1 = 'How many intensive-care-unit beds were there in July 2022 (in total) in the hospitals of the 20 largest ' \ 'German cities?' Keyword1 = 'intensive care units' A1 = 6353 Q2 = 'How many living dogs of the breed "Labrador Retriever" were registered in the German speaking cantons of ' \ 'Switzerland at the end of the year 2019?' Keyword2 = 'Labrador Retrievers' A2 = 19410 Q3 = 'What is the total number of first-time registrations of battery electric passenger cars (BEV) in the new ' \ 'states of Germany ("neue Bundesländer", excluding Berlin) in the years of 2019, 2020, and 2021 (in total)?' Keyword3 = 'electric cars' A3 = 48786 Q4 = 'What is the total distance (in km) that the 20% oldest German football Bundesliga players ran during all ' \ 'football matches in the 2021/22 season? Consider all players that had a contract with a Bundesliga club (' \ '"Lizenzspieler") at some point during the 2021/22 German Bundesliga football season.' Keyword4 = 'football players' A4 = 15584 Q5 = 'How many yellow cards did the 20% shortest players (by height) accumulate over the 2021/22 German ' \ 'Bundesliga football season? Consider all players that had a contract with a Bundesliga club ' \ '("Lizenzspieler") at some point during the 2021/22 German Bundesliga football season.' Keyword5 = 'yellow cards' A5 = 193 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): TestBot = models.BooleanField(initial=False) MyQ = models.StringField(initial="", blank=True) MyKeyword = models.StringField(initial="") MyA = models.IntegerField(initial=0) MyGuess = models.IntegerField(initial=0) MyGuesses = models.LongStringField(initial="", blank=True) MyDescr = models.LongStringField(initial="", blank=True) MyCalc = models.LongStringField(initial="", blank=True) MyStepCount = models.IntegerField(initial=0) MyTimeLeft = models.IntegerField(initial=-1) MyGuessTime = models.IntegerField(initial=-1) MyTimeout = models.BooleanField(initial=False) MyDiscrepancy = models.FloatField(initial=0) MyDiscrepancyBin = models.IntegerField(initial=0) MyGuessPay = models.FloatField(initial=0) MySpeedPay = models.IntegerField(initial=0) MyPay = models.FloatField(initial=0) def iif(boolean, if_true, if_false): if boolean: return if_true else: return if_false def discrepancy_bin(the_discrepancy): if the_discrepancy <= 10: the_bin = 10 elif the_discrepancy <= 20: the_bin = 20 elif the_discrepancy <= 40: the_bin = 40 elif the_discrepancy <= 60: the_bin = 60 elif the_discrepancy <= 80: the_bin = 80 else: the_bin = 81 return the_bin def pay_factor(disc_bin): dic_factor = { 10: 1, 20: 0.8, 40: 0.6, 60: 0.4, 80: 0.2, 81: 0 } return dic_factor.get(disc_bin, -1) # PAGES class P01Start(Page): @staticmethod def js_vars(player: Player): return dict( FirstSecond=iif(player.round_number == 1, "first", "second"), TimeLimit=player.participant.TimeLimit, TestBot=player.participant.TestBot ) @staticmethod def before_next_page(player, timeout_happened): import random questions = {1: C.Q1, 2: C.Q2, 3: C.Q3, 4: C.Q4, 5: C.Q5} keywords = {1: C.Keyword1, 2: C.Keyword2, 3: C.Keyword3, 4: C.Keyword4, 5: C.Keyword5} answers = {1: C.A1, 2: C.A2, 3: C.A3, 4: C.A4, 5: C.A5} # my_qa = iif(player.round_number == 1, random.randint(1, 3), random.randint(4, 5)) my_qa = iif(player.round_number == 1, random.randint(2, 3), random.randint(4, 5)) player.MyQ = questions[my_qa] player.MyKeyword = keywords[my_qa] player.MyA = answers[my_qa] class P02Guesstimation(Page): form_model = 'player' form_fields = ['MyGuess', 'MyDescr', 'MyCalc', 'MyStepCount', 'MyTimeLeft'] @staticmethod def get_timeout_seconds(player): return player.participant.TimeLimit @staticmethod def js_vars(player: Player): import random return dict( MyRole='Me', TimeLimit=player.participant.TimeLimit, TimeAlert=C.TIME_ALERT, Question=player.MyQ, TestBot=player.participant.TestBot, TestValue=random.randint(0, 2*player.MyA), AutoSubmitTime=player.participant.TimeLimit - 10 ) @staticmethod def live_method(player: Player, data): player.MyGuesses = player.MyGuesses + str(data['Guess']) + ' ' @staticmethod def before_next_page(player, timeout_happened): import math player.MyTimeout = timeout_happened player.MyTimeLeft = max(0, player.MyTimeLeft) player.MyGuessTime = player.participant.TimeLimit - player.MyTimeLeft player.MySpeedPay = math.floor(player.MyTimeLeft / 5) if player.MyTimeout: guess_list = player.MyGuesses.split() player.MyGuess = int(guess_list[-1]) player.MyDiscrepancy = 100 * math.fabs(player.MyGuess - player.MyA) / player.MyA player.MyDiscrepancyBin = discrepancy_bin(player.MyDiscrepancy) player.MyGuessPay = pay_factor(player.MyDiscrepancyBin) * player.participant.Prize guess_data = [ player.MyQ, # 0 player.MyA, # 1 player.MyGuess, # 2 player.MyDescr, # 3 player.MyCalc, # 4 player.MyStepCount, # 5 player.MyTimeLeft, # 6 player.MyTimeout, # 7 player.MyGuessTime, # 8 player.MySpeedPay, # 9 player.MyDiscrepancy, # 10 player.MyDiscrepancyBin, # 11 player.MyGuessPay, # 12 player.MyKeyword # 13 ] if player.round_number == 1: player.participant.MyGuessData = [guess_data] else: player.participant.MyGuessData = player.participant.MyGuessData + [guess_data] class P03PostGuess(Page): @staticmethod def js_vars(player: Player): return dict( TestBot=player.participant.TestBot ) class ResultsWaitPage(WaitPage): pass page_sequence = [P01Start, P02Guesstimation, P03PostGuess]