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)