from otree.api import *
from helpers import *
from treatments import Treatment
from .labels import *
import math
doc = """
Your app description
"""
class C(BaseConstants):
NAME_IN_URL = "survey"
PLAYERS_PER_GROUP = None
NUM_ROUNDS = 1
class Subsession(BaseSubsession):
pass
def creating_session(subsession: Subsession):
# Set the correct label object for the session according to its treatment
fixed_wage = get_fixed_wage(subsession)
if is_treatment(subsession, Treatment.FIXED_WAGE):
labels = FixedWageLabels(fixed_wage=fixed_wage)
elif is_treatment(subsession, Treatment.PIECE_RATE):
piece_rate = get_piece_rate(subsession)
labels = PieceRateLabels(fixed_wage=fixed_wage, piece_rate=piece_rate)
elif is_treatment(subsession, Treatment.TOURNAMENT):
[prize1, prize2, prize3, prize4] = get_tournament_prizes(subsession)
labels = TournamentLabels(
fixed_wage=fixed_wage,
prize1=prize1,
prize2=prize2,
prize3=prize3,
prize4=prize4,
)
subsession.session.labels = labels
class Group(BaseGroup):
pass
class Player(BasePlayer):
payoff_rounded = models.FloatField()
payoff_real_currency = models.FloatField()
satisf_fixedwage = models.IntegerField()
fair_fixedwage = models.IntegerField()
satisf_piecerate = models.IntegerField()
fair_piecerate = models.IntegerField()
satisf_prize = models.IntegerField()
fair_prize = models.IntegerField()
expected_pay = models.BooleanField(
label="Ich habe heute mit der Erwartung am Experiment teilgenommen, einen bestimmten Geldbetrag zu verdienen:"
)
expected_pay_amount = models.FloatField(
label="Falls ja, so geben Sie bitte hier den erwarteten Betrag in EURO an:", blank=True, min=0, max=99.99
)
task_motivation = models.IntegerField()
task_fun = models.IntegerField()
task_difficult = models.IntegerField()
task_exhausting = models.IntegerField()
task_obligation = models.IntegerField()
task_pressure = models.IntegerField()
task_stress = models.IntegerField()
task_boredom = models.IntegerField()
task_concentration = models.IntegerField()
task_competition = models.IntegerField()
task_best = models.IntegerField()
task_reciprocity = models.IntegerField()
task_recognition = models.IntegerField()
task_diligent = models.IntegerField()
task_fixedwage = models.IntegerField()
task_piecerate = models.IntegerField()
task_prize = models.IntegerField()
task_competition2 = models.IntegerField()
task_notworst = models.IntegerField()
used_outsideoption = models.BooleanField(
label="Ich habe die Artikel aus dem TUM Magazin „Fazination Forschung“ gelesen“"
)
outsideoption_interesting = models.IntegerField()
outsideoption1 = models.IntegerField()
outsideoption2 = models.IntegerField()
outsideoption_fun = models.IntegerField()
no_outsideoption_reason = models.StringField(
label="Geben Sie bitte einen Grund ein warum Sie das TUM Magazin „Faszination Forschung“ nicht gelesen haben:"
)
comp1 = models.IntegerField()
comp2 = models.IntegerField()
comp3 = models.IntegerField()
comp4 = models.IntegerField()
rec1 = models.IntegerField()
rec2 = models.IntegerField()
rec3 = models.IntegerField()
rec4 = models.IntegerField()
rec5 = models.IntegerField()
rec6 = models.IntegerField()
risk_gen = models.IntegerField()
risk1 = models.IntegerField()
risk2 = models.IntegerField()
risk3 = models.IntegerField()
risk4 = models.IntegerField()
risk5 = models.IntegerField()
risk6 = models.IntegerField()
gender = models.StringField(
label="Bitte geben Sie Ihr Geschlecht an:",
choices=["Weiblich", "Männlich", "Divers", "Ohne Angabe"],
widget=widgets.RadioSelect,
)
age = models.IntegerField(min=1922, max=2012, label="Bitte geben Sie Ihr Geburtsjahr an:")
nationality = models.StringField(label="Bitte geben Sie Ihre Staatsangehörigkeit/-en an:")
german_skills = models.StringField(
label="Bitte geben Sie Ihre Deutschkenntnisse an:",
choices=["Grundkenntnisse", "Sehr gute Kenntnisse", "Fließend", "Verhandlungssicher", "Muttersprache"],
widget=widgets.RadioSelect,
)
lab_experience = models.StringField(
label="An wie vielen Experimenten von experimenTUM haben Sie vorher ungefähr teilgenommen?",
choices=["0", "1 - 5", "6 - 10", "Mehr als 10"],
widget=widgets.RadioSelect,
)
number_acquaintances = models.StringField(
label="Wie viele Personen, die heute mit Ihnen im Labor sitzen, kennen Sie persönlich?",
choices=["Gar keine", "1 - 3 Personen", "4 - 8 Personen", "Mehr als 8 Personen"],
widget=widgets.RadioSelect,
)
grade = models.StringField(
label="Bitte nennen Sie Ihre Abiturnote/Note der Hochschulzugangsberechtigung:",
choices=[
"Sehr gut (1,0 - 1,5)",
"Gut (1,6 - 2,5)",
"Befriedigend (2,6 - 3,5)",
"Ausreichend (3,6 - 4,0)",
"Nicht zutreffend",
],
widget=widgets.RadioSelect,
)
student = models.BooleanField(label="Sind Sie derzeit Student/-in?")
field_of_study = models.StringField(
label="Bitte nennen Sie Ihre Studienrichtung?",
choices=[
"Geisteswissenschaften",
"Informatik",
"Ingenieurwesen",
"Naturwissenschaften",
"Rechtswissenschaften",
"Sozialwissenschaften",
"Sport",
"Wirtschaftsingenieurwesen",
"Wirtschaftswissenschaften",
"Sonstiges, bitte unten angeben",
],
widget=widgets.RadioSelect,
)
field_of_study_other = models.StringField(
label="Falls Sie Sonstiges gewählt haben, geben Sie bitte diese Studienrichtung an:", blank=True
)
targeted_degree = models.StringField(
label="Welchen Abschluss streben Sie in Ihrem derzeitigen Studium an?",
choices=[
"Bachelor",
"Master",
"Diplom",
"Promotion",
"Sonstiges, bitte unten nennen",
],
widget=widgets.RadioSelect,
)
targeted_degree_other = models.StringField(
label="Falls Sie Sonstiges gewählt haben, geben Sie bitte den angestrebten Abschluss an:", blank=True
)
semester = models.IntegerField(
label="In welchem Semester Ihres aktuellen Studiengangs befinden Sie sich? (Falls nicht zutreffend, bitte „0“ eintragen)",
min=0,
)
current_grade = models.StringField(
label="Bitte nennen Sie Ihren aktuellen Notendurchschnitt:",
choices=[
"Sehr gut (1,0 - 1,5)",
"Gut (1,6 - 2,5)",
"Befriedigend (2,6 - 3,5)",
"Ausreichend (3,6 - 4,0)",
"Noch nicht vorhanden",
],
widget=widgets.RadioSelect,
)
# PAGES
def get_progress(page):
return int(((page_sequence.index(page)) / (survey_len)) * 100)
def get_form_fields_for_page(page, player: Player) -> List[str]:
labels = player.session.labels
return labels.get_form_fields(page)
def get_labels_for_page(page, player: Player):
labels = player.session.labels
return labels.get_labels(page)
class Intro(Page):
@classmethod
def vars_for_template(cls, player: Player):
return dict(progress=get_progress(cls))
class PaymentQuestions1(Page):
form_model = "player"
@classmethod
def get_form_fields(page, player: Player):
return get_form_fields_for_page(page, player)
@classmethod
def vars_for_template(page, player: Player):
labels = get_labels_for_page(page, player)
return dict(progress=get_progress(page), labels=labels)
class PaymentQuestions2(Page):
form_model = "player"
form_fields = ["expected_pay", "expected_pay_amount"]
@classmethod
def vars_for_template(cls, player: Player):
return dict(progress=get_progress(cls))
@staticmethod
def error_message(player: Player, values):
if values["expected_pay"] and values["expected_pay_amount"] is None:
return "Bitte geben Sie an welchen Betrag Sie erwartet haben."
@staticmethod
def before_next_page(player: Player, timeout_happened):
if player.field_maybe_none("expected_pay_amount") is None:
player.expected_pay_amount = -1
class TaskQuestions1_1(Page):
form_model = "player"
@classmethod
def get_form_fields(page, player: Player):
return get_form_fields_for_page(page, player)
@classmethod
def vars_for_template(page, player: Player):
labels = get_labels_for_page(page, player)
return dict(progress=get_progress(page), labels=labels)
class TaskQuestions1_2(Page):
form_model = "player"
@classmethod
def get_form_fields(page, player: Player):
return get_form_fields_for_page(page, player)
@classmethod
def vars_for_template(page, player: Player):
labels = get_labels_for_page(page, player)
return dict(progress=get_progress(page), labels=labels)
class TaskQuestions2_1(Page):
form_model = "player"
form_fields = ["used_outsideoption"]
@classmethod
def vars_for_template(page, player: Player):
return dict(progress=get_progress(page))
class TaskQuestions2_2(Page):
form_model = "player"
@classmethod
def get_form_fields(page, player: Player):
if player.used_outsideoption:
return get_form_fields_for_page(page, player)
else:
return ["no_outsideoption_reason"]
@classmethod
def vars_for_template(page, player: Player):
vft = dict(progress=get_progress(page))
if not player.used_outsideoption:
return vft
vft["labels"] = get_labels_for_page(page, player)
return vft
class AttitudeQuestions1(Page):
form_model = "player"
@classmethod
def get_form_fields(page, player: Player):
return get_form_fields_for_page(page, player)
@classmethod
def vars_for_template(page, player: Player):
labels = get_labels_for_page(page, player)
return dict(progress=get_progress(page), labels=labels)
class AttitudeQuestions2(Page):
form_model = "player"
@classmethod
def get_form_fields(page, player: Player):
return get_form_fields_for_page(page, player)
@classmethod
def vars_for_template(page, player: Player):
labels = get_labels_for_page(page, player)
return dict(progress=get_progress(page), labels=labels)
class AttitudeQuestions3(Page):
form_model = "player"
@classmethod
def get_form_fields(page, player: Player):
return get_form_fields_for_page(page, player)
@classmethod
def vars_for_template(page, player: Player):
labels = get_labels_for_page(page, player)
return dict(progress=get_progress(page), labels=labels)
class AttitudeQuestions4(Page):
form_model = "player"
@classmethod
def get_form_fields(page, player: Player):
return get_form_fields_for_page(page, player)
@classmethod
def vars_for_template(page, player: Player):
labels = get_labels_for_page(page, player)
return dict(progress=get_progress(page), labels=labels)
class GeneralQuestions1(Page):
form_model = "player"
form_fields = ["gender", "age", "nationality", "german_skills"]
@classmethod
def vars_for_template(cls, player: Player):
return dict(progress=get_progress(cls))
def round_nearest(num: float, to: float = 0.05) -> float:
return round(num / to) * to
def round_up(num: float, to: float = 0.05) -> float:
nearest = round_nearest(num, to)
if math.isclose(num, nearest):
return num
return nearest if nearest > num else nearest + to
class GeneralQuestions2(Page):
form_model = "player"
form_fields = ["lab_experience", "number_acquaintances", "grade", "student"]
@classmethod
def vars_for_template(cls, player: Player):
return dict(progress=get_progress(cls))
@staticmethod
def before_next_page(player: Player, timeout_happened):
if timeout_happened:
player.participant.dropout = True
# Set some payoff variables
real_payoff = player.participant.payoff.to_real_world_currency(player.session)
player.payoff_real_currency = float(round(real_payoff, 2))
payoff_rounded = float(round(round_up(real_payoff), 2))
player.payoff_rounded = payoff_rounded
player.participant.payoff_rounded = payoff_rounded
class GeneralQuestions3(Page):
form_model = "player"
form_fields = [
"field_of_study",
"field_of_study_other",
"targeted_degree",
"targeted_degree_other",
"semester",
"current_grade",
]
@classmethod
def vars_for_template(cls, player: Player):
return dict(progress=get_progress(cls))
@staticmethod
def error_message(player: Player, values):
if "Sonstiges" in values["field_of_study"] and not len(values["field_of_study_other"]):
return "Bitte geben Sie Ihre Studienrichtung an."
if "Sonstiges" in values["targeted_degree"] and not len(values["targeted_degree_other"]):
return "Bitte geben Sie Ihren angestrebten Abschluss an."
@staticmethod
def is_displayed(player: Player):
return player.student
class SurveyWait(WaitPage):
title_text = "Bitte warten"
body_text = "Es sind noch nicht alle Teilnehmer bereit. Bitte haben Sie einen Moment Geduld. Das Experiment geht weiter, wenn alle TeilnehmerInnen bereit sind."
wait_for_all_groups = True
page_sequence = [
Intro,
PaymentQuestions1,
PaymentQuestions2,
TaskQuestions1_1,
TaskQuestions1_2,
TaskQuestions2_1,
TaskQuestions2_2,
AttitudeQuestions1,
AttitudeQuestions2,
AttitudeQuestions3,
AttitudeQuestions4,
GeneralQuestions1,
GeneralQuestions2,
GeneralQuestions3,
SurveyWait,
]
survey_page_sequence = page_sequence[:-1]
survey_len = len(survey_page_sequence)