import sys sys.path.append(".") import random from otree.api import * #from .group import Group doc = 'This is a project on endogenous college rankingm (Practice Round) written by Xiao Hanyu' class Constants(BaseConstants): name_in_url = 'Endogenous_college_ranking_PR' players_per_group = None#session.config['numberOfPartticipant'] num_rounds = 1 class Subsession(BaseSubsession): pass class Group(BaseGroup): cutOffForS = models.IntegerField(initial = 0) cutOffForC = models.IntegerField(initial = 0) avgScoreForS = models.IntegerField(initial = 0) avgScoreForC = models.IntegerField(initial = 0) sumEarningsForS = models.IntegerField(initial = 0) sumEarningsForC = models.IntegerField(initial = 0) numOfAdmittedForS = models.IntegerField(initial = 0) numOfAdmittedForC = models.IntegerField(initial = 0) class Player(BasePlayer): examScore = models.IntegerField(initial = 10) choseS = models.BooleanField(initial=False) cutOff = models.IntegerField(initial=0) admitted = models.BooleanField(initial=False) earning = models.IntegerField() squareOnTheLeft = models.BooleanField(initial=True) roundNumberToAdjust = models.BooleanField(initial=True) class firstPage(Page): form_model = 'player' form_fields = ['choseS'] @staticmethod def is_displayed(player): if player.id_in_group == 1: return False elif player.id_in_group == 2: return False return True @staticmethod def vars_for_template(player): try: prev_players = player.in_previous_rounds() except: prev_players = [] if player.round_number > 1: if len(prev_players) > 0: prev_players.pop(0) prev_players.reverse() positionIdx = random.randint(0, 100) if player.id_in_group > 2: if positionIdx % 2 == 0: player.squareOnTheLeft = False for p in prev_players: if p.roundNumberToAdjust: p.round_number -= 1 p.roundNumberToAdjust = False return dict( pp = prev_players, RN = player.round_number - 1 ) class collegeFirstPage(Page): form_model = 'player' form_fields = ['cutOff'] @staticmethod def is_displayed(player): if player.id_in_group == 1: return True elif player.id_in_group == 2: return True return False @staticmethod def vars_for_template(player): try: prev_players = player.in_previous_rounds() except: prev_players = [] if player.round_number > 1: if len(prev_players) > 0: prev_players.pop(0) prev_players.reverse() for p in prev_players: if p.roundNumberToAdjust: p.round_number -= 1 p.roundNumberToAdjust = False return dict( s = (player.id_in_group == 1), pp = prev_players, RN = player.round_number - 1 ) @staticmethod def error_message(player, values): if values['cutOff'] < 0: return 'Your exam cutoff must be an integer number between 0 and 100. Please input the cutoff again' if values['cutOff'] > 100: return 'Your exam cutoff must be an integer number between 0 and 100. Please input the cutoff again' class resultWaitPage(WaitPage): template_name = 'collegeRanking/resultWaitPage.html' after_all_players_arrive = 'set_payoff' class resultForStudents(Page): @staticmethod def is_displayed(player): if player.id_in_group == 1: return False elif player.id_in_group == 2: return False return True @staticmethod def vars_for_template(player): group = player.group if player.choseS: avg_score = group.avgScoreForS else: avg_score = group.avgScoreForC try: prev_players = player.in_previous_rounds() except: prev_players = [] if player.round_number > 1: if len(prev_players) > 0: prev_players.pop(0) prev_players.reverse() for p in prev_players: if p.roundNumberToAdjust: p.round_number -= 1 p.roundNumberToAdjust = False return dict( avgScore = avg_score, pp = prev_players, RN = player.round_number - 1 ) class resultForColleges(Page): @staticmethod def is_displayed(player): if player.id_in_group == 1: return True elif player.id_in_group == 2: return True return False @staticmethod def vars_for_template(player): group = player.group equal_score = False if group.avgScoreForC == group.avgScoreForS: equal_score = True if player.id_in_group == 1: avg_score = group.avgScoreForS sum_earnings = group.sumEarningsForS higher_score = (avg_score > group.avgScoreForC) else: avg_score = group.avgScoreForC sum_earnings = group.sumEarningsForC higher_score = (avg_score > group.avgScoreForS) try: prev_players = player.in_previous_rounds() except: prev_players = [] if player.round_number > 1: if len(prev_players) > 0: prev_players.pop(0) prev_players.reverse() for p in prev_players: if p.roundNumberToAdjust: p.round_number -= 1 p.roundNumberToAdjust = False return dict( s = (player.id_in_group == 1), avgScore = avg_score, sumEarnings = sum_earnings, equalScore = equal_score, higherScore = higher_score, pp = prev_players, RN = player.round_number - 1 ) class officialRoundsBegins(Page): '''@staticmethod def is_displayed(player): return (player.round_number == 2)''' class officialWaitPage(WaitPage): template_name = 'collegeRanking/officialWaitPage.html' @staticmethod def is_displayed(player): return (player.round_number == 2) def creating_session(subsession): subsession.group_randomly(fixed_id_in_group=True) #assume to have fixed roles for p in subsession.get_players(): if p.id_in_group > 2: p.examScore = random.randint(0, 100) def set_payoff(group): collegeS = group.get_player_by_id(1) collegeC = group.get_player_by_id(2) cutOffForS = collegeS.cutOff cutOffForC = collegeC.cutOff group.cutOffForS = cutOffForS group.cutOffForC = cutOffForC sumExamScoreForS = 0 sumExamScoreForC = 0 sumEarningsForS = 0 sumEarningsForC = 0 players = group.get_players() for p in players: if p.id_in_group > 2: if p.choseS: if p.examScore > cutOffForS: p.admitted = True sumExamScoreForS += p.examScore group.numOfAdmittedForS+=1 else: if p.examScore > cutOffForC: p.admitted = True sumExamScoreForC += p.examScore group.numOfAdmittedForC+=1 #calculate avgscore of a college if group.numOfAdmittedForC != 0: group.avgScoreForC = round(sumExamScoreForC / group.numOfAdmittedForC) if group.numOfAdmittedForS != 0: group.avgScoreForS = round(sumExamScoreForS / group.numOfAdmittedForS) #calculate player earning for p in players: if p.id_in_group > 2: if p.admitted: if p.choseS: p.earning = round(p.examScore * group.avgScoreForS / 50) sumEarningsForS += p.earning else: p.earning = round(p.examScore * group.avgScoreForC / 50) sumEarningsForC += p.earning group.sumEarningsForS = sumEarningsForS group.sumEarningsForC = sumEarningsForC #calculate college earning if (group.avgScoreForS > group.avgScoreForC): collegeS.earning = round((sumEarningsForS + group.avgScoreForS * 2) / 5) collegeC.earning = round(sumEarningsForC / 5) else: collegeS.earning = round(sumEarningsForS / 5) collegeC.earning = round((sumEarningsForC + group.avgScoreForC * 2) / 5) page_sequence = [firstPage, collegeFirstPage, resultWaitPage, resultForStudents, resultForColleges, officialRoundsBegins, officialWaitPage]