from otree.api import * doc = """ This is a one-shot "Prisoner's Dilemma". Two players are asked separately whether they want to cooperate or defect. Their choices directly determine the payoffs. """ class C(BaseConstants): NAME_IN_URL = 'prisonerC' PLAYERS_PER_GROUP = 2 NUM_ROUNDS = 5 PAYOFF_A = cu(18) PAYOFF_B = cu(12) PAYOFF_C = cu(6) PAYOFF_D = cu(0) RESPONSE_SCALE_1= [ (1, 'Überhaupt nicht'), (2, 'Ein bisschen'), (3, 'Weder ein bisschen noch viel'), (4, 'Viel'), (5, 'Völlig'), ] RESPONSE_SCALE_2 = [ (1, 'Stimme überhaupt nicht zu'), (2, 'Stimme nicht zu'), (3, 'Stimme eher nicht zu'), (4, 'Neutral'), (5, 'Stimme eher zu'), (6, 'Stimme völlig zu'), (7, 'Stimme zu'), ] POSITION_CHOICES = [ ("Professur W3, C4, o.ä.", "Professur W3, C4, o.ä."), ("Professur W2, C3, o.ä.", "Professur W2, C3, o.ä."), ("Professur C2, o.ä.", "Professur C2, o.ä."), ("Juniorprofessur", "Juniorprofessur"), ("Andere Hochschullehrposition", "Andere Hochschullehrposition"), ("Andere Wissenschaftlerposition EG14 TVL/TVöD und höher", "Andere Wissenschaftlerposition EG14 TVL/TVöD und höher"), ("Andere Wissenschaftlerposition EG13 TVL/TVöD und darunter", "Andere Wissenschaftlerposition EG13 TVL/TVöD und darunter"), ] DISCIPLINE_CHOICES = [ ("Pädagogik, Lehramt und Erziehungswissenschaften", "Pädagogik, Lehramt und Erziehungswissenschaften"), ("Geisteswissenschaften und Künste", "Geisteswissenschaften und Künste"), ("Sozialwissenschaften und Psychologie", "Sozialwissenschaften und Psychologie"), ("Wirtschaftswissenschaften", "Wirtschaftswissenschaften"), ("Rechtswissenschaften", "Rechtswissenschaften"), ("Lebenswissenschaften", "Lebenswissenschaften"), ("Physik und Mathematik", "Physik und Mathematik"), ("Chemie", "Chemie"), ("Informatik", "Informatik"), ("Ingenieurwesen", "Ingenieurwesen"), ("Agrarwissenschaft und Forstwissenschaft", "Agrarwissenschaft und Forstwissenschaft"), ("Medizin, Pharmazie und Gesundheitswesen", "Medizin, Pharmazie und Gesundheitswesen"), ("Soziale Arbeit und Sozialwesen", "Soziale Arbeit und Sozialwesen"), ("Andere (bitte angeben)", "Andere (bitte angeben)"), ] EMPLOYMENT_CHOICES = [ ("Vollzeit", "Vollzeit"), ("Teilzeit", "Teilzeit"), ] EMPLOYMENT_DURATION_CHOICES = [ ("Unbefristet beamtet", "Unbefristet beamtet"), ("Unbefristet angestellt", "Unbefristet angestellt"), ("Befristet mit Aussicht auf unbefristeten Vertrag", "Befristet mit Aussicht auf unbefristeten Vertrag"), ("Befristet ohne Aussicht auf unbefristeten Vertrag", "Befristet ohne Aussicht auf unbefristeten Vertrag"), ("Bezahlung nach Stunden, Werkvertrag, o.ä.", "Bezahlung nach Stunden, Werkvertrag, o.ä."), ("Andere (bitte angeben)", "Andere (bitte angeben)"), ] TRAUM = [ ("Ja", "Ja"), ("Nein", "Nein"), ("Zum Teil", "Zum Teil"), ] #randomizes particpants in the first round and #keeps the matching constant over all following rounds: class Subsession(BaseSubsession): pass #def creating_session(self): #if self.round_number == 1: #self.group_randomly() #else: # Explicitly set groups to match previous round #for player in self.get_players(): # player.group = player.in_round(self.round_number - 1).group # Alternatively, you can use: player.group_like_round(self.round_number - 1) #def creating_session(self): #self.group_randomly() #if self.round_number == 1: #self.group_randomly() #else: #self.group_like_round(1) class Group(BaseGroup): pass class Player(BasePlayer): def make_q(label): return models.IntegerField(label=label, choices=[1, 2, 3, 4, 5], widget=widgets.RadioSelect) def make_c(label): return models.IntegerField(label=label, choices=[1, 2, 3, 4, 5, 6, 7], widget=widgets.RadioSelect) q1 = make_q('Ich bin eher zurückhaltend, reserviert. ') q2 = make_q('Ich schenke anderen leicht Vertrauen, glaube an das Gute im Menschen.') q3 = make_q('Ich bin bequem, neige zur Faulheit.') q4 = make_q('Ich bin entspannt, lasse mich durch Stress nicht aus der Ruhe bringen.') q5 = make_q('Ich habe nur wenig künstlerisches Interesse.') q6 = make_q('Ich gehe aus mir heraus, bin gesellig.') q7 = make_q('Ich neige dazu, andere zu kritisieren.') q8 = make_q('Ich erledige Aufgaben gründlich.') q9 = make_q('Ich werde leicht nervös und unsicher') q10 = make_q('Ich habe eine aktive Vorstellungskraft, bin fantasievoll.') c15 = make_c('Zusammenarbeit ist für jede Organisation, die Wachstum, Innovation und Produktivität erreichen möchte, von entscheidender Bedeutung') c16 = make_c('Ich bin „gut“ darin, Konflikte oder Meinungsverschiedenheiten mit Kolleginnen und Kollegen oder Teammitgliedern zu lösen') c17 = make_c('In meiner aktuellen Position ist es oft erforderlich, dass ich mit anderen zusammenarbeite.') c18 = make_c('Wenn es Begriffe gibt, die ich nicht verstehe, mache ich mir normalerweise nicht die Mühe zu fragen, was sie bedeuten') c19 = make_c('Ich verhandle mit anderen, wenn ich denke, dass es nötig ist') c20 = make_c('Oft erkunde ich keine alternativen Lösungen') c21 = make_c('Ich übernehme die Verantwortung, wenn Entscheidungen getroffen werden müssen') c22 = make_c('Es macht mir Spaß, mich an Entscheidungen zu beteiligen') c23 = make_c('Wenn widersprüchliche Ansichten (im Team) existieren, vertrete ich meinen Standpunkt oft nicht') c24 = make_c('Ich frage nicht nach alternativen Lösungen') c25 = make_c('Ich neige dazu, keine Vorschläge für Handlungs- oder Entscheidungsoptionen zu unterbreiten, wenn man mich nicht gezielt dazu auffordert') c26 = make_c('Meistens gehöre ich zu den Personen im Team, die Vorschläge machen/unterbreiten. Ich übernehme eine aktive Rolle im Team, anstatt darauf zu warten, dass andere Vorschläge machen') c27 = make_c('Normalerweise spreche ich offen darüber, wie ich mich fühle') c28 = make_c('Wenn ich nicht alle Optionen verstehe, schweige ich') c29 = make_c('Ich schaue anderen in die Augen, wenn ich anderer Meinung bin') ### gender_b = models.StringField(label="Bitte wählen Sie Ihr Geschlecht aus*:", choices=["Männlich", "Weiblich", "Divers"]) birthd_b = models.IntegerField(label="Bitte tragen Sie Ihr Geburtsjahr ein*:") email_b = models.StringField(label="Bitte tragen Sie Ihre E-Mail-Adresse ein*:") state_b = models.StringField(label="In welchem Bundesland arbeiten Sie*?") traum_role = models.StringField(label="Bitte geben Sie an, welche Rolle/Position Sie im T!Raum-Projekt innehaben*") from otree.api import ( models, widgets ) hprofed_b = models.StringField( label="Welchen höchsten beruflichen Ausbildungs- oder (Fach-)Hochschulabschluss haben Sie?", choices=[ 'Noch in beruflicher Ausbildung (Berufsvorbereitungsjahr, Auszubildende/-r, Praktikant/-in, Student/-in)', 'Schüler/-in und besuche eine berufsorientierte Aufbau-, Fachschule o. ä.', 'Keinen beruflichen Abschluss und bin nicht in beruflicher Ausbildung', 'Beruflich-betriebliche Berufsausbildung (Lehre) abgeschlossen', 'Beruflich-schulische Ausbildung (Berufsfachschule, Handelsschule, Vorbereitungsdienst für den mittleren Dienst in der öffentlichen Verwaltung) abgeschlossen', 'Ausbildung an einer Fachschule der DDR abgeschlossen Ausbildung an einer Fach-, Meister-, Technikerschule, Berufs- oder Fachakademie abgeschlossen', 'Bachelor an (Fach-)Hochschule abgeschlossen', 'Fachhochschulabschluss (z. B. Diplom, Master)', 'Universitätsabschluss (z. B. Diplom, Magister, Staatsexamen, Master)', 'Promotion' ], widget=widgets.RadioSelect ) other_hprofed_b = models.StringField( label="Ein anderer beruflicher Abschluss, und zwar", blank=True ) salc_b = models.StringField( label="Was ist Ihre heutige Position bzw. Gehaltskategorie?", choices=C.POSITION_CHOICES, widget=widgets.RadioSelect, ) salc_b_other_position = models.StringField( label="Andere (bitte angeben):", blank=True ) arear_b = models.StringField( label="Bitte nennen Sie Ihre Disziplin bzw. Fachrichtungsgruppe, der Sie Ihre wissenschaftliche Tätigkeit zurechnen. (Bitte nur eine Angabe)", choices=C.DISCIPLINE_CHOICES, widget=widgets.RadioSelect, ) other_arear_b = models.StringField( label="", blank=True ) Traum_b = models.StringField( label="Verfügen Sie im Rahmen der T!Raum-Inititative über einen Arbeitsvertrag?", choices= C.TRAUM, widget=widgets.RadioSelect ) scopee_b = models.StringField( label="In Welchem Umfang sind Sie derzeitig in Ihrer T!Raum-Inititative beschäftigt?", choices=C.EMPLOYMENT_CHOICES, widget=widgets.RadioSelect, ) part_time_description = models.StringField( label="Bitte geben Sie Ihren genauen Teilzeitumfang an:", blank=True ) other_employment = models.StringField( label="Andere: Bitte geben Sie Ihre genaue Beschäftigung an:", blank=True ) duratione_b = models.StringField( label="Welche Beschäftigungsdauer ist bei Ihrem Beschäftigungsvertrag vorgesehen? (Bitte nur eine Angabe)", choices=C.EMPLOYMENT_DURATION_CHOICES, widget=widgets.RadioSelect, ) other_duratione_b = models.StringField( label="", blank=True ) consent = models.BooleanField( label='Ich habe die Informationen nach Art. 13 DSGVO anlässlich der Datenerhebung bei der Teilnahme und Durchführung des Lab-in-the-field Experiments im Rahmen der T!Raum Begleitforschung des International Center for Higher Education Research (INCHER) der Universität Kassel gelesen und ich willige in die Teilnahme am Forschungsprojekt und die damit verbundene Datenverarbeitung ein. Sofern ich besondere Kategorien von personenbezogenen Daten angebe bzw. angegeben habe, sind diese von der Einwilligungserklärung umfasst. Mir ist bewusst, dass die Einwilligung/en freiwillig ist/sind und ohne Nachteile (auch einzeln) verweigert oder jederzeit auch ohne Angaben von Gründen widerrufen werden können. Ich weiß, dass im Falle eines Widerrufs die Rechtmäßigkeit der aufgrund der Einwilligung bis zum Widerruf erfolgten Verarbeitung nicht berührt wird. Ich habe verstanden, dass ich mich für einen Widerruf einfach an Herrn Prof. Dr. Guido Bünstorf, E-Mail: buenstorf@uni-kassel.de, Telefon +49 561 804 2961, wenden kann und dass aus der Verweigerung der Einwilligung oder ihrem Widerruf keine Nachteile entstehen', widget=widgets.CheckboxInput, ) essay = models.LongStringField( label="Das Ziel dieses Kurz-Essays besteht darin, Ihnen bei der Reflektion über unterschiedliche Strategien " "behilflich zu sein. In diesem Zusammenhang möchten wir Sie dazu einladen, innerhalb der " "nächsten 5 Minuten einen kurzen Text zu verfassen, in dem Sie Argumente sowohl für als auch gegen " "jede denkbare Verteilung von Auszahlungen erörtern.", blank=True ) quiz1 = models.IntegerField(label="Füllen Sie die Lücke aus: Wenn Sie und die andere Person beide A wählen, erhalten Sie beide", choices = [0, 12, 6, 18], ) quiz2 = models.IntegerField(label="Füllen Sie die Lücke aus: Wenn Sie B wählen und die andere Person A wählt, erhalten Sie 18 und die andere Person erhält", choices = [0,12,6,18], ) quiz3 = models.StringField( label="Ihr Gegenüber im Spiel ist über alle Runden", choices = ['identisch', 'unterschiedlich'], ) cooperate = models.BooleanField( choices=[[True, 'A'], [False, 'B']], doc="""This player's decision""", widget=widgets.RadioSelect, ) def creating_session(subsession): if self.round_number == 1: players = self.get_players() num_groups = 2 # Adjust this to the number of groups you want players_per_group = len(players) // num_groups for i in range(num_groups): group = self.get_groups()[i] group.set_players(players[i * players_per_group : (i + 1) * players_per_group]) else: for group in self.get_groups(): # Set groups explicitly to match the previous round group.set_players(group.in_round(self.round_number - 1).get_players()) # FUNCTIONS def set_payoffs(group: Group): for p in group.get_players(): set_payoff(p) def other_player(player: Player): return player.get_others_in_group()[0] def set_payoff(player: Player): payoff_matrix = { (False, True): C.PAYOFF_A, (True, True): C.PAYOFF_B, (False, False): C.PAYOFF_C, (True, False): C.PAYOFF_D, } other = other_player(player) player.payoff = payoff_matrix[(player.cooperate, other.cooperate)] # PAGES class Introduction(Page): timeout_seconds = 180 def is_displayed(player: Player): return player.round_number == 1 class Consent(Page): form_model = 'player' form_fields = ['consent'] def is_displayed(player: Player): return player.round_number == 1 class Survey1(Page): form_model = 'player' form_fields = ['gender_b', 'email_b','state_b', 'traum_role','hprofed_b','other_hprofed_b', 'salc_b', 'salc_b_other_position','arear_b','other_arear_b','Traum_b','scopee_b','part_time_description','other_employment', 'duratione_b','other_duratione_b'] def is_displayed(self): return self.round_number == 1 class Survey2(Page): form_model = 'player' form_fields = ['q1', 'q2', 'q3', 'q4', 'q5', 'q6', 'q7', 'q8', 'q9', 'q10'] def is_displayed(player: Player): return player.round_number == 1 class Survey3(Page): form_model = 'player' form_fields = ['c15', 'c16', 'c17', 'c18', 'c19', 'c20', 'c21', 'c22', 'c23', 'c24', 'c25', 'c26', 'c27', 'c28', 'c29'] def is_displayed(player: Player): return player.round_number == 1 class Info(Page): timeout_seconds = 50 def is_displayed(player: Player): return player.round_number == 1 class Instruction(Page): timeout_seconds = 420 def is_displayed(player: Player): return player.round_number == 1 class Testfragen(Page): form_model = 'player' form_fields = ['quiz1', 'quiz2', 'quiz3'] def is_displayed(player: Player): return player.round_number == 1 @staticmethod def error_message(player: Player, values): solutions = dict(quiz1=12, quiz2=0, quiz3='identisch') if values != solutions: return "Eine oder mehrere Antworten waren falsch, versuchen Sie es noch einmal." class MatchingWaitPage(WaitPage): def is_displayed(player: Player): return player.round_number == 1 def after_all_players_arrive(subsession: Subsession): #for group in self.subsession.get_groups(): #print(f"Round {self.round_number} - Group {group.id_in_subsession}: {[(p.id_in_group, p.group_id) for p in group.get_players()]}") # Execute creating_session after all players have arrived subsession.creating_session() class Decision(Page): form_model = 'player' form_fields = ['cooperate'] class ResultsWaitPage(WaitPage): after_all_players_arrive = set_payoffs class Results(Page): @staticmethod def vars_for_template(player: Player): opponent = other_player(player) return dict( opponent=opponent, same_choice=player.cooperate == opponent.cooperate, my_decision=player.field_display('cooperate'), opponent_decision=opponent.field_display('cooperate'), ) class Chat1(Page): timeout_seconds = 300 def is_displayed(player: Player): return player.round_number == 2 class Chat2(Page): timeout_seconds = 300 def is_displayed(player: Player): return player.round_number == 4 class End(Page): timeout_seconds = 60 def is_displayed(player: Player): return player.round_number == 5 page_sequence = [ Testfragen, MatchingWaitPage, Decision, ResultsWaitPage, Results, Chat1, Chat2, End] #Introduction, Consent, Survey1, Survey2, Survey3, Info, Instruction