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,
]