from otree.api import * import random import settings author = 'Patricia Zauchner (zauchner@uni-bremen.de)' doc = """ Acceptance: If the group accepted the suggested distribution procedure. Comparison of 3 distributions. """ # Models class C(BaseConstants): NAME_IN_URL = 'acceptance' PLAYERS_PER_GROUP = 5 NUM_ROUNDS = 1 NEEDS = settings.Needs # How many Token need to be consumed in each round? USUAL_CONSUMPTION = 0.9 # 90% of the income will be consumed # New TokenAdd TOKEN_ADD_1D_NAME = settings.TokenAdd_1dName # Main distribution: [30 / 5, 30 / 5, 30 / 5, 30 / 5, 30 / 5] TOKEN_ADD_2D_NAME = settings.TokenAdd_2dName TOKEN_ADD_3D_NAME = settings.TokenAdd_3dName # Arguments ARG_MIN_LENGHT = 10 ARG_MAX_LENGHT = 250 # ARG_BEST_TOKEN = 2 # Not used in this experiment. ARG_TIME = 5 # In Minutes class Subsession(BaseSubsession): pass def creating_session(subsession: Subsession): """ Create ID, StartToken, Wealth, and Treatments """ # try: subsession.session.vars["StartToken"] = subsession.session.config["StartToken"] # print("Acceptance ... StartToken taken from session config") except KeyError: subsession.session.vars["StartToken"] = settings.StartToken # print("Acceptance ... StartToken taken from settings") try: subsession.session.vars["Taxes"] = subsession.session.config["Taxes"] # print("Acceptance ... Taxes taken from session config") except KeyError: subsession.session.vars["Taxes"] = settings.Taxes # print("Acceptance ... Taxes taken from settings") subsession.session.vars["StartTokenPT"] = [] # StartToken --> Brutto Pretaxes for i in range(0, 5): subsession.session.vars["StartTokenPT"].append(subsession.session.vars["StartToken"][i] + subsession.session.vars["Taxes"][i]) # Assign Session TokenAdd # Main Distribution: Gleichverteilung try: subsession.session.vars["TokenAdd_1d"] = subsession.session.config["TokenAdd_1d"] # print("Acceptance ... TokenAdd_1d taken from session config.") except KeyError: subsession.session.vars["TokenAdd_1d"] = settings.TokenAdd_1d # print("Acceptance ... TokenAdd_1d taken from settings.") try: subsession.session.vars["TokenAdd_2d"] = subsession.session.config["TokenAdd_2d"] # print("Acceptance ... TokenAdd_2d taken from session config.") except KeyError: subsession.session.vars["TokenAdd_2d"] = settings.TokenAdd_2d # print("Acceptance ... TokenAdd_2d taken from settings.") try: subsession.session.vars["TokenAdd_3d"] = subsession.session.config["TokenAdd_3d"] # print("Acceptance ... TokenAdd_3d taken from session config.") except KeyError: subsession.session.vars["TokenAdd_3d"] = settings.TokenAdd_3d # print("Acceptance ... TokenAdd_3dtaken from settings.") # # # Copy the group and player id structure of the first app if "id_matrix" in subsession.session.vars: subsession.set_group_matrix(subsession.session.vars['id_matrix']) else: subsession.group_randomly() # oTree function subsession.session.vars['id_matrix'] = subsession.get_group_matrix() print("ID Matrix created in app acceptance", subsession.session.vars['id_matrix']) # # try: subsession.session.vars['do_acceptance'] = subsession.session.config["do_acceptance"] except KeyError: subsession.session.vars["do_acceptance"] = getattr(settings, "do_acceptance", False) # If not specified default is False # class Group(BaseGroup): # Treatments: REDIS und Effort: Not used here GroupAcknowledgement = models.IntegerField(doc="GV: Whether group accepted suggested distribution or not.") # Arguments # Number of votes for best argument Acc_nArgBest_1 = models.IntegerField(doc="Number of group members stating that Player 1s argument was best") Acc_nArgBest_2 = models.IntegerField(doc="Number of group members stating that Player 2s argument was best") Acc_nArgBest_3 = models.IntegerField(doc="Number of group members stating that Player 3s argument was best") Acc_nArgBest_4 = models.IntegerField(doc="Number of group members stating that Player 4s argument was best") Acc_nArgBest_5 = models.IntegerField(doc="Number of group members stating that Player 5s argument was best") # Acceptance of arguments - Not used in this experiment # Acc_nArgAkz_1 = models.IntegerField() # Acc_nArgAkz_2 = models.IntegerField() # Acc_nArgAkz_3 = models.IntegerField() # Acc_nArgAkz_4 = models.IntegerField() # Acc_nArgAkz_5 = models.IntegerField() # Acc_nArgAkzNo_1 = models.IntegerField() # Acc_nArgAkzNo_2 = models.IntegerField() # Acc_nArgAkzNo_3 = models.IntegerField() # Acc_nArgAkzNo_4 = models.IntegerField() # Acc_nArgAkzNo_5 = models.IntegerField() # Variables for Graphdesign (min/max of y) maxOneRound = models.FloatField(initial=0) minRounds = models.FloatField(initial=0) maxRounds = models.FloatField(initial=0) # Group Functions def define_group_rank(group: Group): """ Define group rank. Either get GroupRanks from the participant variables or assign new ones. """ randomnumber = random.sample(list(range(1, 6)), 5) for p in group.get_players(): try: p.GroupRank = p.participant.vars["GroupRank"] except KeyError: print("Acceptance ... No Grouprank here. Pretest only!") p.GroupRank = randomnumber[p.id_in_group - 1] # For Pretest Reasons Only # Change id_in_group for p in group.get_players(): p.id_in_group = p.GroupRank def define_start_token(group: Group): """ Get start token based on group ranks """ for p in group.get_players(): # For specific positions p.StartToken = group.session.vars["StartToken"][p.GroupRank - 1] p.StartTokenPT = group.session.vars["StartTokenPT"][p.GroupRank - 1] p.Taxes = group.session.vars["Taxes"][p.GroupRank - 1] p.TokenAdd_1d = group.session.vars["TokenAdd_1d"][p.GroupRank - 1] p.TokenAdd_2d = group.session.vars["TokenAdd_2d"][p.GroupRank - 1] p.TokenAdd_3d = group.session.vars["TokenAdd_3d"][p.GroupRank - 1] # For all p.SumRoundIncome_1d = p.StartToken + p.TokenAdd_1d p.SumRoundIncome_2d = p.StartToken + p.TokenAdd_2d p.SumRoundIncome_3d = p.StartToken + p.TokenAdd_3d def calc_wealth(group: Group): """ Calculate wealth for all distributions. No graphs, only numbers. """ for p in group.get_players(): # For Start - No Redistribution if (p.StartTokenPT * C.USUAL_CONSUMPTION) <= C.NEEDS: p.ConsumptionNoDis = C.NEEDS p.WealthNoDis_1R = p.StartTokenPT - C.NEEDS else: p.ConsumptionNoDis = p.StartTokenPT * C.USUAL_CONSUMPTION p.WealthNoDis_1R = p.StartTokenPT * (1-C.USUAL_CONSUMPTION) p.WealthNoDis_5R = p.WealthNoDis_1R * 5 # For Equality if ((p.StartToken + p.TokenAdd_1d) * C.USUAL_CONSUMPTION) <= C.NEEDS: p.Consumption_1d = C.NEEDS p.Wealth_1d_1R = p.StartToken - C.NEEDS + p.TokenAdd_1d else: p.Consumption_1d = (p.StartToken + p.TokenAdd_1d) * C.USUAL_CONSUMPTION p.Wealth_1d_1R = (p.StartToken + p.TokenAdd_1d) * (1-C.USUAL_CONSUMPTION) p.Wealth_1d_5R = p.Wealth_1d_1R * 5 # For Weaker First if ((p.StartToken + p.TokenAdd_2d) * C.USUAL_CONSUMPTION) <= C.NEEDS: p.Consumption_2d = C.NEEDS p.Wealth_2d_1R = p.StartToken - C.NEEDS + p.TokenAdd_2d else: p.Consumption_2d = (p.StartToken + p.TokenAdd_2d) * C.USUAL_CONSUMPTION p.Wealth_2d_1R = (p.StartToken + p.TokenAdd_2d) * (1-C.USUAL_CONSUMPTION) p.Wealth_2d_5R = p.Wealth_2d_1R * 5 # For Mixed if ((p.StartToken + p.TokenAdd_3d) * C.USUAL_CONSUMPTION) <= C.NEEDS: p.Consumption_3d = C.NEEDS p.Wealth_3d_1R = p.StartToken - C.NEEDS + p.TokenAdd_3d else: p.Consumption_3d = (p.StartToken + p.TokenAdd_3d) * C.USUAL_CONSUMPTION p.Wealth_3d_1R = (p.StartToken + p.TokenAdd_3d) * (1-C.USUAL_CONSUMPTION) p.Wealth_3d_5R = p.Wealth_3d_1R * 5 def results_graph_1d(group: Group): """ Calculate the numbers for the fist suggested distribution. Equal distribution. """ series_Start_PT = [] series_Start = [] series_Taxes = [] series_TokenAdd = [] series_Income = [] series_Cumulative = [] series_highest_lowest = [] # Wealth series_WealthAt1 = [] series_WealthAt5 = [] wealth_min = 0 wealth_max = 0 for p in group.get_players(): # Wealth series_WealthAt1.append({ "name": p.GroupRank, "y": p.Wealth_1d_1R}) series_WealthAt5.append({ "name": p.GroupRank, "y": p.Wealth_1d_5R}) # min/max Runde 1 if p.Wealth_1d_1R < wealth_min: wealth_min = p.Wealth_1d_1R if p.Wealth_1d_1R > wealth_max: wealth_max = p.Wealth_1d_1R # min/max Rund e5 if p.Wealth_1d_5R < wealth_min: wealth_min = p.Wealth_1d_5R if p.Wealth_1d_5R > wealth_max: wealth_max = p.Wealth_1d_5R # Others series_Start_PT.append(p.StartTokenPT) series_Start.append(p.StartToken) series_Taxes.append(p.Taxes) series_TokenAdd.append(p.TokenAdd_1d) cumulativedata = [0, p.Wealth_1d_1R * 1, p.Wealth_1d_1R * 2, p.Wealth_1d_1R * 3, p.Wealth_1d_1R * 4, p.Wealth_1d_1R * 5 ] series_Cumulative.append({ "name": p.GroupRank, "data": cumulativedata}) series_highest_lowest.append(p.Wealth_1d_1R * 5) series_Income.append(p.StartToken + p.TokenAdd_1d) if min_max_graph(series_Income)[1] > group.maxOneRound: group.maxOneRound = min_max_graph(series_Income)[1] if min_max_graph(series_highest_lowest)[1] > group.maxRounds: group.maxRounds = min_max_graph(series_highest_lowest)[1] if min_max_graph(series_highest_lowest)[0] < group.minRounds: group.minRounds = min_max_graph(series_highest_lowest)[0] return { "1d_series_StartToken_PT": series_Start_PT, "1d_StartToken": series_Start, "1d_Taxes": series_Taxes, "1d_TokenAdd": series_TokenAdd, "1d_Cumulative": series_Cumulative, "1d_MinValue_B": min_max_graph(series_highest_lowest)[0], "1d_MaxValue_B": min_max_graph(series_highest_lowest)[1], "1d_MinValue_A": 0, "1d_MaxValue_A": min_max_graph(series_Income)[1], # Wealth "1d_WealthAt1": series_WealthAt1, "1d_WealthAt5": series_WealthAt5, "1d_wealth_min": wealth_min, "1d_wealth_max": wealth_max, } def ResultsGraph_2d(group: Group): """ Calculate the numbers for the second suggested distribution. Weaker First.""" # Wealth series_WealthAt1 = [] series_WealthAt5 = [] wealth_min = 0 wealth_max = 0 # Others series_Start = [] series_TokenAdd = [] series_Income = [] series_Cumulative = [] series_highest_lowest = [] for p in group.get_players(): # Wealth series_WealthAt1.append({ "name": p.GroupRank, "y": p.Wealth_2d_1R}) series_WealthAt5.append({ "name": p.GroupRank, "y": p.Wealth_2d_5R}) # min/max Runde 1 if p.Wealth_2d_1R < wealth_min: wealth_min = p.Wealth_2d_1R if p.Wealth_2d_1R > wealth_max: wealth_max = p.Wealth_2d_1R # min/max Rund e5 if p.Wealth_2d_5R < wealth_min: wealth_min = p.Wealth_2d_5R if p.Wealth_2d_5R > wealth_max: wealth_max = p.Wealth_2d_5R # Others series_Start.append(p.StartToken) series_TokenAdd.append(p.TokenAdd_2d) cumulativedata = [0, p.Wealth_2d_1R * 1, p.Wealth_2d_1R * 2, p.Wealth_2d_1R * 3, p.Wealth_2d_1R * 4, p.Wealth_2d_1R * 5 ] series_Cumulative.append({ "name": p.GroupRank, "data": cumulativedata}) series_highest_lowest.append(p.Wealth_2d_1R * 5) series_Income.append(p.StartToken + p.TokenAdd_2d) if min_max_graph(series_Income)[1] > group.maxOneRound: group.maxOneRound = min_max_graph(series_Income)[1] if min_max_graph(series_highest_lowest)[1] > group.maxRounds: group.maxRounds = min_max_graph(series_highest_lowest)[1] if min_max_graph(series_highest_lowest)[0] < group.minRounds: group.minRounds = min_max_graph(series_highest_lowest)[0] return { "2d_StartToken": series_Start, "2d_TokenAdd": series_TokenAdd, "2d_Cumulative": series_Cumulative, "2d_MinValue_B": min_max_graph(series_highest_lowest)[0], "2d_MaxValue_B": min_max_graph(series_highest_lowest)[1], "2d_MinValue_A": 0, "2d_MaxValue_A": min_max_graph(series_Income)[1], # Wealth "2d_WealthAt1": series_WealthAt1, "2d_WealthAt5": series_WealthAt5, "2d_wealth_min": wealth_min, "2d_wealth_max": wealth_max, } def ResultsGraph_3d(group: Group): """ Calculate the numbers for the second suggested distribution. Mixed.""" # Wealth series_WealthAt1 = [] series_WealthAt5 = [] wealth_min = 0 wealth_max = 0 # Others series_Start = [] series_TokenAdd = [] series_Income = [] series_Cumulative = [] series_highest_lowest = [] for p in group.get_players(): # Wealth series_WealthAt1.append({ "name": p.GroupRank, "y": p.Wealth_3d_1R}) series_WealthAt5.append({ "name": p.GroupRank, "y": p.Wealth_3d_5R}) # min/max Runde 1 if p.Wealth_3d_1R < wealth_min: wealth_min = p.Wealth_3d_1R if p.Wealth_3d_1R > wealth_max: wealth_max = p.Wealth_3d_1R # min/max Rund e5 if p.Wealth_3d_5R < wealth_min: wealth_min = p.Wealth_3d_5R if p.Wealth_3d_5R > wealth_max: wealth_max = p.Wealth_3d_5R # Others series_Start.append(p.StartToken) series_TokenAdd.append(p.TokenAdd_3d) cumulativedata = [0, p.Wealth_3d_1R * 1, p.Wealth_3d_1R * 2, p.Wealth_3d_1R * 3, p.Wealth_3d_1R * 4, p.Wealth_3d_1R * 5 ] series_Cumulative.append({ "name": p.GroupRank, "data": cumulativedata}) series_highest_lowest.append(p.Wealth_3d_1R * 5) series_Income.append(p.StartToken + p.TokenAdd_3d) if min_max_graph(series_Income)[1] > group.maxOneRound: group.maxOneRound = min_max_graph(series_Income)[1] if min_max_graph(series_highest_lowest)[1] > group.maxRounds: group.maxRounds = min_max_graph(series_highest_lowest)[1] if min_max_graph(series_highest_lowest)[0] < group.minRounds: group.minRounds = min_max_graph(series_highest_lowest)[0] return { "3d_StartToken": series_Start, "3d_TokenAdd": series_TokenAdd, "3d_Cumulative": series_Cumulative, "3d_MinValue_B": min_max_graph(series_highest_lowest)[0], "3d_MaxValue_B": min_max_graph(series_highest_lowest)[1], "3d_MinValue_A": 0, "3d_MaxValue_A": min_max_graph(series_Income)[1], # Wealth # Wealth "3d_WealthAt1": series_WealthAt1, "3d_WealthAt5": series_WealthAt5, "3d_wealth_min": wealth_min, "3d_wealth_max": wealth_max, } def min_max_graph(list_): """ Calculate the minimun and maximum values for the graph. """ if min(list_) >= 0: minlist = -5 maxlist = max(list_) + 3 else: minlist = min(list_) - 5 maxlist = max(list_) + 3 return minlist, maxlist # Count acceptance (not used in this experiment) # def calc_acc_arg(group: Group, argpart): # if group.session.vars['do_acceptance']: # # argpart are either a_vote, redistribution, etc. # group_acc_base = argpart + "_nArgAkz_" # group_accNo_base = argpart + "_nArgAkzNo_" # ind_acc_base = argpart + "_ArgAkz_" # ind_accNo_base = argpart + "_ArgAkzNo_" # # for i in range(1, 6): # group_acc_mod = group_acc_base + str(i) # group_accNo_mod = group_accNo_base + str(i) # ind_acc_mod = ind_acc_base + str(i) # ind_accNo_mod = ind_accNo_base + str(i) # # Calculations # setattr(group, group_acc_mod, # sum((vars(p)[ind_acc_mod]) for p in group.get_players() if vars(p)[ind_acc_mod] is not None)) # setattr(group, group_accNo_mod, 5 - vars(group)[group_acc_mod]) def calc_best_arg(group: Group, argpart): """ Calculate the best argument 'argpart' is either "AVote", "BVote", "Rej" or "Acc" """ group_best_base = argpart + "_nArgBest_" ind_best_base = argpart + "_ArgBest_" for i in range(1, 6): group_best_mod = group_best_base + str(i) ind_best_mod = ind_best_base + str(i) # Calculations setattr(group, group_best_mod, sum((vars(p)[ind_best_mod]) for p in group.get_players())) # print(sum((vars(p)[ind_best_mod]) for p in group.get_players())) # Assign count of best argument to subjects. listofbest = [] # For overview for p in group.get_players(): setattr(p, argpart + "_nArgBest", vars(group)[group_best_base + str(p.GroupRank)]) listofbest.append(vars(p)[argpart + "_nArgBest"]) # Who won best argument? winners = [i for i, j in enumerate(listofbest) if j == max(listofbest)] for p in group.get_players(): # If winner if (p.GroupRank - 1) in winners and len(winners) <= 2: # There are max 2 winners. setattr(p, argpart + "_ArgBest", 1) # setattr(p, argpart + "_ArgToken", C.ARG_BEST_TOKEN) # Not used in this experiment. if len(winners) == 1: setattr(p, argpart + "_ArgBestSingle", 1) else: setattr(p, argpart + "_ArgBestSingle", 2) # If not winner else: setattr(p, argpart + "_ArgBest", 0) # setattr(p, argpart + "_ArgToken", 0) setattr(p, argpart + "_ArgBestSingle", 0) # p.participant.vars[argpart + "_ArgToken"] = getattr(p, argpart + "_ArgToken") class Player(BasePlayer): # Variables for all apps # Start Token StartToken = models.FloatField(doc="StartToken after deduction of taxes") StartTokenPT = models.FloatField(doc="StartToken pre taxes; formally coded as StartTokenAlt") Taxes = models.FloatField(doc="Taxes to be deducted from StartTokenPT") # Others GroupRank = models.IntegerField(doc="GV: Rank in group") # Token and wealth in suggested distributions TokenAdd_1d = models.FloatField( doc="TokenAdd as suggested by Experimenter") TokenAdd_2d = models.FloatField( doc="TokenAdd as suggested by WeakerFirst") TokenAdd_3d = models.FloatField( doc="TokenAdd as suggested by Mixed") ConsumptionNoDis = models.FloatField( doc="Initial Consumption = no Redistribution") Consumption_1d = models.FloatField( doc="Initial Consumption = with TokenAdd as suggested by Experimenter") Consumption_2d = models.FloatField( doc="Initial Consumption = with TokenAdd as suggested by Weaker First") Consumption_3d = models.FloatField( doc="Initial Consumption = with TokenAdd as suggested by Mixed") SumRoundIncome_2d = models.FloatField( doc="Total Income Token minus Taxes but with TokenAdd as suggested by Weaker First") SumRoundIncome_1d = models.FloatField( doc="Total Income Token minus Taxes but with TokenAdd as suggested by Experimenter") SumRoundIncome_3d = models.FloatField( doc="Total Income Token minus Taxes but with TokenAdd as suggested by Mixed") WealthNoDis_1R = models.FloatField( doc="Wealth for 1 Round - No Redistribution") WealthNoDis_5R = models.FloatField( doc="Wealth for 5 Rounds - No Redistribution") Wealth_1d_1R = models.FloatField( doc="Wealth for 1 Round - Suggested Distribution") Wealth_1d_5R = models.FloatField( doc="Wealth for 5 Rounds - Suggested Distribution") Wealth_2d_1R = models.FloatField(doc="Wealth for 1 Round - Suggested Distribution") Wealth_2d_5R = models.FloatField(doc="Wealth for 5 Rounds - Suggested Distribution") Wealth_3d_1R = models.FloatField(doc="Wealth for 1 Round - Suggested Distribution") Wealth_3d_5R = models.FloatField(doc="Wealth for 5 Rounds - Suggested Distribution") # Acceptance # Arguments Acceptance Acc_DistributionChange = models.IntegerField( doc="Preferred alternative distribution", choices=[ [1, 'Ich hätte mich dennoch für Verfahren >' + C.TOKEN_ADD_1D_NAME + '< entschieden.'], [2, 'Ich hätte mich für das alternative Verfahren >' + C.TOKEN_ADD_2D_NAME + '< entschieden.'], [3, 'Ich hätte mich für das alternative Verfahren >' + C.TOKEN_ADD_3D_NAME + '< entschieden.'] ], widget=widgets.RadioSelect) Acc_Arg = models.TextField( label="", max_length=250 ) # Acc --> Accept -- Arguments of choice (not used in this experiment) # Acc_ArgAkz_1 = models.IntegerField( # choices=[ # [1, "Ich akzeptiere das Argument"], # [0, "Ich akzeptiere das Argument nicht"], # ], # widget=widgets.RadioSelect # ) # Acc_ArgAkz_2 = models.IntegerField( # choices=[ # [1, "Ich akzeptiere das Argument"], # [0, "Ich akzeptiere das Argument nicht"], # ], # widget=widgets.RadioSelect # ) # Acc_ArgAkz_3 = models.IntegerField( # choices=[ # [1, "Ich akzeptiere das Argument"], # [0, "Ich akzeptiere das Argument nicht"], # ], # widget=widgets.RadioSelect # ) # Acc_ArgAkz_4 = models.IntegerField( # choices=[ # [1, "Ich akzeptiere das Argument"], # [0, "Ich akzeptiere das Argument nicht"], # ], # widget=widgets.RadioSelect # ) # Acc_ArgAkz_5 = models.IntegerField( # choices=[ # [1, "Ich akzeptiere das Argument"], # [0, "Ich akzeptiere das Argument nicht"], # ], # widget=widgets.RadioSelect # ) # Vote for best argument Acc_ArgBest_1 = models.BooleanField( doc="Individual votes for best argument - for player 1", blank=True, initial=False) Acc_ArgBest_2 = models.BooleanField( doc="Individual votes for best argument - for player 2", blank=True, initial=False) Acc_ArgBest_3 = models.BooleanField( doc="Individual votes for best argument - for player 3", blank=True, initial=False) Acc_ArgBest_4 = models.BooleanField( doc="Individual votes for best argument - for player 4", blank=True, initial=False) Acc_ArgBest_5 = models.BooleanField( doc="Individual votes for best argument - for player 5", blank=True, initial=False) # Acc --> Calculate best argument for new distribution - winners and tokens Acc_nArgBest = models.IntegerField(doc="Number of votes for best vote") Acc_ArgBest = models.IntegerField(doc="Whether participant is one of the best-vote winners.") # Acc_ArgToken = models.IntegerField(initial=0, doc="Token für the argument.") # Not used in this experiment Acc_ArgBestSingle = models.IntegerField() # Page basis class AccPage(Page): """ Handles if other pages are displayed """ @staticmethod def is_displayed(player): return player.group.GroupAcknowledgement == 1 # Pages class Before_Intro_WP(WaitPage): """ Intro to app. Here, the GroupAcknowledgement-variable is defined """ @staticmethod # Must be at the end, because otherwise GroupAcknowledgement is not defined! def is_displayed(player): # Get GroupAcknowledgement - calculated in redistribution/AckResultWP player.group.GroupAcknowledgement = player.participant.vars.get("GroupAcknowledgement", 1) return player.group.GroupAcknowledgement == 1 # GroupRank etc. can not be calculated if that is in a page? @staticmethod def after_all_players_arrive(group: Group): print( "------------------------------------- Start: Acceptance App ---------------------------------------------") define_group_rank(group) define_start_token(group) calc_wealth(group) # I only need this for the BVote and Acceptance App. # group.Nickname() # Create nicknames for chat - I don't need this in the Acceptance app. class WaitForArgs(WaitPage): """ Wait for the arguments of the group members """ @staticmethod def is_displayed(player): return player.group.GroupAcknowledgement == 1 class WaitForVotes(WaitPage): @staticmethod def is_displayed(player): return player.group.GroupAcknowledgement == 1 class Acc_Intro(AccPage): """ Intro page for acceptance app """ template_name = 'acceptance/Acc_Intro.html' class Acc_AltDis_123_c(AccPage): """ Explanation of the other suggested distributions """ template_name = 'acceptance/Acc_AltDis_123_c.html' @staticmethod def vars_for_template(player): Dict1 = results_graph_1d(player.group) Dict2 = ResultsGraph_2d(player.group) Dict3 = ResultsGraph_3d(player.group) DictTotal = {**Dict1, **Dict2, **Dict3} return DictTotal class Acc_2_Arg(AccPage): """ Enter the argument """ template_name = 'acceptance/Acc_Arg.html' form_model = "player" form_fields = ["Acc_DistributionChange", "Acc_Arg"] # Timeout for arguments timer_text = 'Verbleibende Zeit (in Sek.):' @staticmethod def get_timeout_seconds(player): # second argument of get()-method is the default---in this case the respective value from the settings return player.session.config.get("minutes_for_arguments", settings.minutes_for_arguments) * 60 @staticmethod def vars_for_template(player): return { "secondsTimerIsShown": player.session.config.get("secondsTimerIsShown", settings.secondsTimerIsShown) # the last 60 seconds when the timer is shown } @staticmethod def before_next_page(player, timeout_happened): if timeout_happened: player.Acc_Arg = player.Acc_Arg + " (Zeit abgelaufen)" class Acc_WaitPageForArgInput_Exc_Inc(WaitPage): @staticmethod def is_displayed(player): return player.group.GroupAcknowledgement == 1 @staticmethod def vars_for_template(player): return {"body_text": "Bitte warten Sie bis Ihre Gruppenmitglieder bereit sind."} class Acc_3_RateBestArg(Page): """ Acceptance of arguments """ template_name = 'acceptance/Acc_RateBestArg.html' @staticmethod def is_displayed(player): return player.group.GroupAcknowledgement == 1 and player.session.vars['do_acceptance'] form_model = "player" @staticmethod def get_form_fields(player): field_list = [] for i in range(1, 6): if player.GroupRank != i: field_list.append("Acc_ArgAkz_" + str(i)) return field_list @staticmethod def vars_for_template(player): """ A person cannot accept their own argument. Their assigned variable hence gets a value of -98. """ if player.GroupRank == 1: player.Acc_ArgAkz_1 = -98 elif player.GroupRank == 2: player.Acc_ArgAkz_2 = -98 elif player.GroupRank == 3: player.Acc_ArgAkz_3 = -98 elif player.GroupRank == 4: player.Acc_ArgAkz_4 = -98 elif player.GroupRank == 5: player.Acc_ArgAkz_5 = -98 class Acc_3_RateBestArg2(AccPage): """ Vote for best argument """ template_name = 'acceptance/Acc_RateBestArg2.html' form_model = "player" @staticmethod def get_form_fields(player): field_list = [] for i in range(1, 6): if player.GroupRank != i: field_list.append("Acc_ArgBest_" + str(i)) return field_list class Acc_4_BestUebersicht(AccPage): """ Show results for acceptances and votes for best argument """ template_name = 'acceptance/Acc_BestUebersicht.html' @staticmethod def vars_for_template(player): calc_best_arg(player.group, "Acc") # group.calc_acc_arg("Acc") # Not used in this experiment page_sequence = [ Before_Intro_WP, Acc_Intro, Acc_AltDis_123_c, # Don't forget to change tests.py if you choose another one Acc_2_Arg, WaitForArgs, Acc_3_RateBestArg, Acc_3_RateBestArg2, WaitForVotes, Acc_4_BestUebersicht, ]