from otree.api import *
doc = """
Causal Determination Mouse-tracking experiment
"""
class Constants(BaseConstants):
name_in_url = 'CausalDetermine'
players_per_group = None
num_rounds = 32
class Subsession(BaseSubsession):
pass
class Group(BaseGroup):
pass
class Player(BasePlayer):
GivesConsent = models.BooleanField(widget=widgets.CheckboxInput(), label="Agree")
CausalScore = models.StringField(widget=widgets.RadioSelectHorizontal, choices=['Not at all', 'Very Slightly', 'Slightly', 'Neutral', 'Moderately', 'Very much',
'Almost Entirely'], label="Causal Attribution: ")
BonusScore = models.IntegerField(widget=widgets.RadioSelectHorizontal, choices=[[-10,'-10%'], [-1,'-1%'], [0,'0%'], [1,'1%'], [10,'10%']], label="Bonus / Malus: ")
Timeb1 = models.FloatField(blank=True, default=0.0)
Timeb2 = models.FloatField(blank=True, default=0.0)
Timeb3 = models.FloatField(blank=True, default=0.0)
Timeb4 = models.FloatField(blank=True, default=0.0)
Timeb5 = models.FloatField(blank=True, default=0.0)
Timeb6 = models.FloatField(blank=True, default=0.0)
Timeb7 = models.FloatField(blank=True, default=0.0)
Viewsb1 = models.IntegerField(blank=True, default=0)
Viewsb2 = models.IntegerField(blank=True, default=0)
Viewsb3 = models.IntegerField(blank=True, default=0)
Viewsb4 = models.IntegerField(blank=True, default=0)
Viewsb5 = models.IntegerField(blank=True, default=0)
Viewsb6 = models.IntegerField(blank=True, default=0)
Viewsb7 = models.IntegerField(blank=True, default=0)
InfoOrderGroup = models.StringField()
Participant_order = models.IntegerField()
Agent = models.StringField()
Outcome1 = models.StringField()
Outcome2 = models.StringField()
Action = models.StringField()
Incentive = models.StringField()
Pivotality = models.StringField()
Context = models.StringField()
Dummy1 = models.StringField()
Numeracy_Answer = models.IntegerField(label="Answer (%): ")
Age = models.IntegerField(label="What is your age?: ")
Nationality = models.StringField(label="What is your nationality?: ")
Education = models.StringField(choices=["0) None", "1) Highschool", "2) College Diploma", "3) Bachelors Degree", "4) Postgraduate Diploma/Honours Degree", "5) Master's Degree", "6) PhD or Higher"], label="Which of the following best describes the highest level of education you have completed? ")
Employment = models.StringField(choices=["Unemployed", "Apprentice/Trainee", "Full-time student", "Employed part-time", "Employed full-time", "Self-Employed"], label="Which of the following best describes your current employment situation? ")
Email_Address = models.StringField(blank=True, label="Email Address")
KeepPosted = models.BooleanField(widget=widgets.CheckboxInput(), label="I would like to receive a copy of the working paper when it becomes available", blank=True)
# Functions
def response_outcome(player: Player):
if player.Context == "Business":
OutcomeResponseTxt = "the company's environmental footprint to " + player.Outcome2
elif player.Context == "Football":
OutcomeResponseTxt = "their team to " + player.Outcome2
return OutcomeResponseTxt
def context_description(player: Player):
if player.Context == "Football":
Context_Descr = "In the football scenario, the Agent is either a professional football player or a pre-programmed football-AI. This agent then, during a point in the game, is faced with either passing the ball, or shooting to try and score. Either way, this can result in a goal being scored off of the play, or not. The end outcome is then either a win or a loss at the end of the game, and that could be by various margins. For the sake of this experiment, assume that you support the team for which the agent is playing.
The question is: to what extent did the football agent cause their team to win/lose? "
elif player.Context == "Business":
Context_Descr = "In the business scenario, the Agent is either a senior business executive or a pre-programmed strategic-AI. This agent then votes on whether or not their firm should adopt a new business strategy. The individual’s vote can pass by one or more votes on the voting panel (we do not consider cases where the agent was outvoted). In the months following the chosen strategy, the company then either sees an increase or a decrease in their profits; as well as either an improvement or worsening of their environmental footprint.
The question is: to what extent did the strategy agent cause their firm’s environmental footprint to improve/worsen? "
return Context_Descr
def buttonlabels(player: Player):
if player.Context == "Football":
#Self made OR statement since OTree was being bitchy
if (player.InfoOrderGroup == "A" ) + (player.InfoOrderGroup == "B") >=1:
button1 = "Human/A.I."
button2 = "Shoot/Pass"
button3 = "Motivation"
button4 = "Win margin"
button5 = "Score/Miss"
button6 = "Home/Away"
button7 = "Win/Lose"
if player.InfoOrderGroup == "C":
button1 = "Score/Miss"
button2 = "Home/Away"
button3 = "Human/A.I."
button4 = "Motivation"
button5 = "Win/Lose"
button6 = "Win margin"
button7 = "Shoot/Pass"
if player.Context == "Business":
if player.InfoOrderGroup == "A":
button1 = "Human/A.I."
button2 = "Strategy"
button3 = "Motivation"
button4 = "Vote margin"
button5 = "Financial Outcome"
button6 = "Industry"
button7 = "Environment Outcome"
if (player.InfoOrderGroup == "B") + (player.InfoOrderGroup == "C") >= 1:
button1 = "Strategy"
button2 = "Motivation"
button3 = "Financial Outcome"
button4 = "Human/A.I."
button5 = "Industry"
button6 = "Environment Outcome"
button7 = "Vote margin"
return button1, button2, button3, button4, button5, button6, button7
def buttonlabelsFootDummy(player: Player):
#Self made OR statement since OTree was being bitchy
if (player.InfoOrderGroup == "A" ) + (player.InfoOrderGroup == "B") >=1:
button1 = "Human/A.I."
button2 = "Shoot/Pass"
button3 = "Motivation"
button4 = "Win margin"
button5 = "Score/Miss"
button6 = "Home/Away"
button7 = "Win/Lose"
if player.InfoOrderGroup == "C":
button1 = "Score/Miss"
button2 = "Home/Away"
button3 = "Human/A.I."
button4 = "Motivation"
button5 = "Win/Lose"
button6 = "Win margin"
button7 = "Shoot/Pass"
return button1, button2, button3, button4, button5, button6, button7
def buttonlabelsBusDummy(player: Player):
# Self made OR statement since OTree was being bitchy
if player.InfoOrderGroup == "A":
button1 = "Human/A.I."
button2 = "Strategy"
button3 = "Motivation"
button4 = "Vote margin"
button5 = "Financial Outcome"
button6 = "Industry"
button7 = "Environment Outcome"
if (player.InfoOrderGroup == "B") + (player.InfoOrderGroup == "C") >= 1:
button1 = "Strategy"
button2 = "Motivation"
button3 = "Financial Outcome"
button4 = "Human/A.I."
button5 = "Industry"
button6 = "Environment Outcome"
button7 = "Vote margin"
return button1, button2, button3, button4, button5, button6, button7
def creating_session(subsession):
import itertools
FieldOrders = itertools.cycle(["A", "B", "C"])
PartOrders = itertools.cycle(range(1,61))
TempDummy = itertools.cycle(["A", "B"]) # Dummy variable doesn't need to be perfectly balanced
if subsession.round_number == 1:
for player in subsession.get_players():
player.participant.vars['InfoOrder'] = next(FieldOrders)
player.participant.vars['ParticipantNum'] = next(PartOrders)
for player in subsession.get_players():
player.InfoOrderGroup = player.participant.vars['InfoOrder']
player.Participant_order = player.participant.vars['ParticipantNum']
player.Dummy1 = next(TempDummy)
import csv
with open('Vignettes.csv', mode='r') as csv_file:
csv_reader = csv.DictReader(csv_file)
line_count = 0
for row in csv_reader:
for player in subsession.get_players():
if int(row["Subject"]) == player.Participant_order and int(row["RoundNum"]) == player.round_number:
player.Agent = row["Agent"]
player.Outcome1 = row["Outcome1"]
player.Outcome2 = row["Outcome2"]
player.Action = row["Action"]
player.Incentive = row["Incentive"]
player.Pivotality = row["Pivotality"]
player.Context = row["Context"]
# Pages
class Consent(Page):
form_model = 'player'
form_fields = ['GivesConsent']
def is_displayed(player):
return player.round_number == 1 # only display in first round
class ExampleFootball(Page):
def is_displayed(player):
return player.round_number == 1 # only display in first round
@staticmethod
def js_vars(player):
return dict(
InfoOrder = player.InfoOrderGroup,
)
@staticmethod
def vars_for_template(player: Player):
return dict(
Button1=buttonlabelsFootDummy(player)[0],
Button2=buttonlabelsFootDummy(player)[1],
Button3=buttonlabelsFootDummy(player)[2],
Button4=buttonlabelsFootDummy(player)[3],
Button5=buttonlabelsFootDummy(player)[4],
Button6=buttonlabelsFootDummy(player)[5],
Button7=buttonlabelsFootDummy(player)[6]
)
class ExampleBusiness(Page):
def is_displayed(player):
return player.round_number == 1 # only display in first round
@staticmethod
def js_vars(player):
return dict(
InfoOrder=player.InfoOrderGroup,
)
@staticmethod
def vars_for_template(player: Player):
return dict(
Button1=buttonlabelsBusDummy(player)[0],
Button2=buttonlabelsBusDummy(player)[1],
Button3=buttonlabelsBusDummy(player)[2],
Button4=buttonlabelsBusDummy(player)[3],
Button5=buttonlabelsBusDummy(player)[4],
Button6=buttonlabelsBusDummy(player)[5],
Button7=buttonlabelsBusDummy(player)[6]
)
class Response(Page):
form_model = 'player'
form_fields = ['CausalScore','BonusScore']
def vars_for_template(player: Player):
return dict(OutcomeResponseTxt=response_outcome(player))
class InfoBlocks(Page):
form_model = 'player'
form_fields = ['Timeb1', 'Timeb2', 'Timeb3', 'Timeb4', 'Timeb5', 'Timeb6', 'Timeb7', 'Viewsb1', 'Viewsb2', 'Viewsb3', 'Viewsb4', 'Viewsb5', 'Viewsb6', 'Viewsb7']
@staticmethod
def js_vars(player):
return dict(
InfoOrder = player.InfoOrderGroup,
Agent = player.Agent,
Outcome1 = player.Outcome1,
Outcome2 = player.Outcome2,
Action = player.Action,
Incentive = player.Incentive,
Pivotality = player.Pivotality,
Context = player.Context,
Dummy = player.Dummy1
)
@staticmethod
def vars_for_template(player: Player):
return dict(
ContextDescr=context_description(player),
Button1=buttonlabels(player)[0],
Button2=buttonlabels(player)[1],
Button3=buttonlabels(player)[2],
Button4=buttonlabels(player)[3],
Button5=buttonlabels(player)[4],
Button6=buttonlabels(player)[5],
Button7=buttonlabels(player)[6]
)
class ResultsWaitPage(WaitPage):
pass
class Results(Page):
pass
class FixationCross(Page):
timeout_seconds = 1.5
class ExperimentAlmostDone(Page):
@staticmethod
def is_displayed(player):
return player.round_number == Constants.num_rounds # only display in last round
class PostQuestions(Page):
form_model = 'player'
form_fields = ['Age','Nationality','Education','Employment','Email_Address','KeepPosted']
@staticmethod
def is_displayed(player):
return player.round_number == Constants.num_rounds # only display in last round
class Numeracy(Page):
form_model = 'player'
form_fields = ['Numeracy_Answer']
@staticmethod
def is_displayed(player):
return player.round_number == Constants.num_rounds # only display in last round
class Closing(Page):
@staticmethod
def is_displayed(player):
return player.round_number == Constants.num_rounds # only display in last round
page_sequence = [Consent, ExampleFootball, ExampleBusiness, FixationCross, InfoBlocks, Response, ExperimentAlmostDone, Numeracy, PostQuestions, Closing]