from otree.api import *
from django.core.validators import MaxValueValidator, MinValueValidator
import os
import pandas as pd
import random
doc = """
Your app description
"""
class Group(BaseGroup):
pass
class C(BaseConstants):
NAME_IN_URL = 'hiringFlexible'
PLAYERS_PER_GROUP = None
NUM_ROUNDS = 4
def get_candidate():
data_people = pd.read_csv("/Users/max/Documents/GitHub/Experiment/survey_2/data/clean_randomise.csv")
candidate = data_people[data_people["Group"] == random.randint(1, 100)]
cons_cols = ["participantlabel","survey1playerage","majority","reservation wage","profile_name","quartile","Set","Group"]
selected_columns = ["score1","score2","score3"]
cons_cols.extend(random.sample(selected_columns,2))
candidate = candidate[cons_cols]
if ('score3' in candidate.columns.tolist()) & ('score1' in candidate.columns.tolist()):
candidate.rename(columns={"score3":"score2"},inplace=True)
elif ('score3' in candidate.columns.tolist()) & ('score2' in candidate.columns.tolist()):
candidate.rename(columns={"score3":"score1"},inplace=True)
candidate = candidate.sort_values(by="majority")
candidate.reset_index(inplace=True,drop=True)
return candidate
candidate = get_candidate()
class Player(BasePlayer):
question3_answer = models.BooleanField(
label='3. If you decide to hire candidate 1 and candidate 2, which following pairs of wages you can offer respectively?',
choices=((False, 'A. 17, 18'),
(False, "B. 20, 20"),
(False,"C. 1, 2"),
(False, "D. 4, 4"),
(True, "E. A, B"))
)
pass
competition5_answer = models.BooleanField(
label="""5. If you decide to hire none of the candidates or
fail to hire any of the candidates successfully, how much you can earn (in points)? """,
choices=(
(False,"A. 22 points"),
(False,"B. 21 points"),
(True,"C. 7 points"),
(False,"D. 10 points")
)
)
competition6_answer = models.BooleanField(
label="""6. If you successfully hire candidate 2 and you offer a wage of 10 points,
how much you can earn in total?""",
choices=(
(True,"A. 22 points"),
(False,"B. 21 points"),
(False,"C. 7 points"),
(False,"D. 10 points")
)
)
competition7_answer = models.BooleanField(
label="""7. If you want to hire candidate 2 and offer a wage of 11, and y
our competitor offer a wage of 15. Can you successfully hire candidate 2?""",
choices=(
(True,"""A. No. Because my competitor offers a higher wage, and both of our
wage offers are greater than the reservation wage of candidate 2"""),
(False,"""B. Yes. Because my wage offer is greater than the reservation wage of candidate 2"""),
(False,"C. Not sure"),
(False,"""D. Yes. Because we can both successfully hire candidate
2 as our wage offer is greater than our assigned reservation wage. """)
)
)
noncompetition5_answer = models.BooleanField(
label="""5. If you decide to hire none of the candidates or fail to hire any
of the candidates successfully, how many points you did have in total? """,
choices=(
(False,"""A. 0 point"""),
(False,"""B. 5 points"""),
(True,"C. 15 points"),
(False,"""D. 10 points""")
)
)
noncompetition6_answer = models.BooleanField(
label="""6. If you successfully hire candidate 2 and you offer a wage of 10 points,
how many points did you earn in total (assume candidate 2 is the only candidate you successfully hire)""",
choices=(
(True,"""A. 22 points"""),
(False,"""B. 21 points"""),
(False,"C. 7 points"),
(False,"""D. 10 points""")
)
)
prac_hiring_1 = models.CharField(label="",
choices=
("Yes","NO")
)
prac_wage_1 = models.IntegerField(
default=0,
label="", validators=[
MaxValueValidator(25),
MinValueValidator(5)
]
)
prac_hiring_2 = models.CharField(label="",
choices=
("Yes","NO")
)
prac_wage_2 = models.IntegerField(
default=0,
label="", validators=[
MaxValueValidator(25),
MinValueValidator(5)
]
)
prac_hiring_3 = models.CharField(label="",
choices=
("Yes","NO")
)
prac_wage_3 = models.IntegerField(
default=0,
label="", validators=[
MaxValueValidator(25),
MinValueValidator(5)
]
)
prac_hiring_4 = models.CharField(label="",
choices=
("Yes","NO")
)
prac_wage_4 = models.IntegerField(
default=0,
label="", validators=[
MaxValueValidator(25),
MinValueValidator(5)
]
)
estimate_performance_1 = models.CurrencyField(initial=0)
estimate_performance_2 = models.CurrencyField(initial=0)
estimate_performance_3 = models.CurrencyField(initial=0)
estimate_performance_4 = models.CurrencyField(initial=0)
set_number = models.StringField()
treatment = models.StringField()
def estimate_score(self):
return
class Subsession(BaseSubsession):
pass
# PAGES
class FirstRoundPage(Page):
def is_displayed(self):
return self.round_number == 1
class TestingQuestion3(FirstRoundPage):
form_model = 'player'
form_fields = ["question3_answer"]
def before_next_page(self,timeout_happened):
self.treatment = self.session.config["name"]
# def error_message(player,values):
def error_message(self, values=Player):
error_dict = {"Flexible":"""
You can choose different wages for different candidates you want to hire.
The candidate will only accept your wage offer only if it is greater than the reservation wage you face, which ranges from 5 to 25. """,
"Fix":"""You can only choose an identical wage for different candidates you want to hire. The candidate will only accept your wage offer only
if it is greater than the reservation wage you face, which ranges from 5 to 25"""}
if values["question3_answer"] != True:
if "Flexible" in self.session.config["name"]:
return error_dict["Flexible"]
else:
return error_dict["Fix"]
else:
pass
pass
class TestingQuestionCompetition(FirstRoundPage):
form_model = 'player'
form_fields = ["competition5_answer","competition6_answer","competition7_answer"]
def is_displayed(self):
return ("Comp" in self.session.config["name"]) & (self.round_number == 1)
def error_message(player, values):
hints= {
"competition5_answer": """Your total payment will consist of 15
initial points and the additional points you earn from the manager task.""",
"competition6_answer": """You will receive 1 point for each score of the Employment Performance of your
successfully hired candidate, minus the wage you decided to offer as additional points.
Your total payment will consist of 15 initial points and the additional points you
earn from the manager task.""",
"competition7_answer": """Candidate will only accept your wage offer only if 1) it is greater than or equal to the reservation wage of the candidate 2)
it is higher than your competing employer’s wage offer after deducting the reservation wage."""
}
error_messages = dict()
for key, item in values.items():
if item != True:
if key == "competition5_answer":
error_messages["competition5_answer"] = hints[key]
elif key == "competition6_answer":
error_messages["competition6_answer"] = hints[key]
elif key == "competition7_answer":
error_messages["competition7_answer"] = hints[key]
return error_messages
class TestingQuestionNonCompetition(FirstRoundPage):
form_model = 'player'
form_fields = ["noncompetition5_answer","noncompetition6_answer"]
def is_displayed(self):
return ("NonCom" in self.session.config["name"]) & (self.round_number == 1)
def error_message(player, values):
hints= {
"noncompetition5_answer": """ Your total payment will consist of 15 initial points
and the additional points you earn from the manager task. """,
"noncompetition6_answer": """ You will receive 1 point for each score of the
Employment Performance of your successfully hired candidate, minus the wage you decided to
offer as additional points. Your total payment
will consist of 15 initial points and the additional points you earn from the manager task. """
}
error_messages = dict()
for key, item in values.items():
if item != True:
if key == "competition5_answer":
error_messages["noncompetition5_answer"] = hints[key]
else:
error_messages["noncompetition6_answer"] = hints[key]
return error_messages
class DynamicPage(Page):
def get_proper_page_name(self):
return self.__class__.__name__.lower()
def vars_for_template(self):
candidates = C.candidate
roundNum = self.round_number
self.set_number = str(candidates["Group"].unique()[0])
if self.round_number == 1:
est_payment = self.estimate_performance_1
elif self.round_number == 2:
est_payment = self.estimate_performance_2
elif self.round_number == 3:
est_payment = self.estimate_performance_3
elif self.round_number == 4:
est_payment = self.estimate_performance_4
# if "feedback" in self.get_proper_page_name():
# # add estimation to each candidate
# candidates["assigned_estimation"] = candidates["identity"].apply(
# lambda row: self.player.get_score_estimation_as_dict()[row]
# )
return {
"round1":"hiringFlexible/hiringTask_{roundNum}".format(
roundNum = self.round_number
),
'candidates': candidates[candidates["quartile"] == self.round_number],
'roundNumber':roundNum,
'estimate':est_payment
}
class HiringPage(DynamicPage):
form_model = 'player'
form_fields = ["prac_hiring_1",'prac_wage_1',"prac_hiring_2",'prac_wage_2',
"prac_hiring_3",'prac_wage_3',"prac_hiring_4",'prac_wage_4']
def before_next_page(self,timeout_happened):
payment = 0
data = C.candidate
data = data[data["quartile"] == self.round_number]
index = data[data["quartile"] == self.round_number].index
if self.prac_hiring_1 == "Yes":
if self.prac_wage_1 >= data.at[data.index[0],"reservation wage"]:
payment = payment + data.at[data.index[0],"score2"] - self.prac_wage_1
else:
payment = payment
if self.prac_hiring_2 == "Yes":
if self.prac_wage_2 >= data.at[data.index[1],"reservation wage"]:
payment = payment + data.at[data.index[1],"score2"] - self.prac_wage_2
else:
payment = payment
if self.prac_hiring_3 == "Yes":
if self.prac_wage_3 >= data.at[data.index[2],"reservation wage"]:
payment = payment + data.at[data.index[2],"score2"] - self.prac_wage_3
else:
payment = payment
if self.prac_hiring_4 == "Yes":
if self.prac_wage_4 >= data.at[data.index[3],"reservation wage"]:
payment = payment + data.at[data.index[3],"score2"] - self.prac_wage_4
else:
payment = payment
payment = (15+ payment)*0.1
print(payment)
if self.round_number == 1:
self.estimate_performance_1 = float(payment)
elif self.round_number == 2:
self.estimate_performance_2 = float(payment)
elif self.round_number == 3:
self.estimate_performance_3 = float(payment)
elif self.round_number == 4:
self.estimate_performance_4 = float(payment)
pass
class Estimation(DynamicPage):
form_model = 'player'
page_sequence = [
TestingQuestion3,
TestingQuestionCompetition,
TestingQuestionNonCompetition,
HiringPage,
Estimation
]