from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) from django.db import models as djmodels import random import os import itertools author = 'Your name here' doc = """ Your app description """ class Constants(BaseConstants): name_in_url = 'innovation' players_per_group = None num_rounds = 1 num_participants = 3 # Sollte ungerade sein (da ein Investor) IMAGE_EXTENTION = 'png' class Subsession(BaseSubsession): def creating_session(self): for group in self.get_groups(): innovators_list = list(range(2, Constants.num_participants + 1)) dec_list = random.sample(innovators_list, len(innovators_list)) # Die innovators_list in geshuffelt group.dec1_i1 = dec_list[0] group.dec1_i2 = dec_list[1] #group.dec2_i1 = dec_list[2] #group.dec2_i2 = dec_list[3] #group.dec3_i1 = dec_list[4] #group.dec3_i2 = dec_list[5] #group.dec4_i1 = dec_list[6] #group.dec4_i2 = dec_list[7] #group.dec5_i1 = dec_list[8] #group.dec5_i2 = dec_list[9] #group.dec6_i1 = dec_list[10] #group.dec6_i2 = dec_list[11] #group.dec7_i1 = dec_list[12] #group.dec7_i2 = dec_list[13] #group.dec8_i1 = dec_list[14] #group.dec8_i2 = dec_list[15] # Mit dem Code weiter unten wird der Teilnehmer, der sich als erster einloggt der Investor. # Mit dem Code unmittelbar hier drunter ist die Zuteilung tatsächlich zufällig. if self.round_number == 1: treat_aux1 = list(range(1, Constants.num_participants + 1)) aux_list = random.sample(treat_aux1, len(treat_aux1)) for player in self.get_players(): player.treat_aux2 = aux_list.pop(0) # pop entfernt das Element aus der Liste (aux_list) am gegebenen Index und speichert es direkt # in player.treat_aux2 # treat_aux2 kann als selbst angelegte ID genutzt werden (und wird es auch), die das Programmieren um # einiges leichter macht. if player.treat_aux2 == 1: player.treat = 'investor' player.treat_investor = random.choice( [ 'CI', 'GradeCI', 'VerbalCI', 'GradeOnly', 'VerbalOnly' ] ) print(player.treat_investor) else: player.treat = 'innovator' player.photoid = str(player.treat_aux2) + str(self.session.code) print(player.photoid) #if self.round_number == 1: # treat_aux1 = itertools.count(1) # treat_investor_aux = itertools.cycle("") # randnum = itertools.count(2) # for player in self.get_players(): # teilnehmern treatment zuordnen # player.treat_aux2 = next(treat_aux1) # zufallszahl wird gezogen # if player.treat_aux2 == 1: # wenn zufallszahl 1 wird teilnehmer investor (es gibt einen investor pro session) # player.treat = 'investor' # player.treat_investor = random.choice(['CI', 'GradeCI', 'VerbalCI', 'GradeOnly', 'VerbalOnly']) # für investoren gibt es 5 treatments, hier wird eines der treatments für den investor zufällig gezogen # print(player.treat_investor) # else: # player.treat = 'innovator' # für die restlichen spieler (innovatoren) wird hier noch eine photoid generiert die im dateinamen der bilder auftaucht um diese aufrufen zu können # player.photoid = str(next(randnum)) + str(self.session.code) # die photoid besteht aktuell aus einer zahl die ab 2 hochgezählt wird, dh. der id_in_subsession entspricht (s.o. für eine Lösung mit der ID des Players) # print(player.photoid) # if player.treat == 'investor': # # random draw of pair of innovators whos creative idea investor will see in decision 1 # innovators_list = list(range(2, Constants.num_participants + 1)) # Teilnehmerzahl + 1, da z.B. 2 bis 4 nur 2 und 3 ausgiebt # dec1 = (random.sample(innovators_list, 2)) # random.sample zieht 2 aus innovators_list ohne zurücklegen # player.dec1_i1 = dec1[0] # ziehen der zahl die das erste bild bestimmt das dem investor gezeigt wird in decicion 1 # player.dec1_i2 = dec1[1] # ziehen der zahl die das zweite bild bestimmt... (die zahl + session nr ergibt die photo id, so kann man die bilder aufrufen) # dec_list = random.sample(innovators_list, len(innovators_list)) # Die innovators_list in geshuffelt # player.dec1_i1 = dec_list[0] # player.dec1_i2 = dec_list[1] # player.dec2_i1 = dec_list[2] # ... # player.dec8_i1 = dec_list[14] # player.dec8_i2 = dec_list[15] #Ende bei 17 Teilnehmern (mit einem Investor) # Dann allerdings nicht variabel hinsichtlich der Teilnehmerzahl. # Oder später in Schleife setzen und mit previous round arbeiten. (Gibt es Runden?) # (Also Element aus vorheriger Runde entfernen oder so) # -> Es kann keine Runden geben, da Innovatoren und Investoren in gleicher Runde wären und # Innovatoren damit auch in nächste Runde kämen. Die müssen die Aufgabe allerdings nur einmal machen. # Außerdem hat jede Runde eine eigene Subsession. Der Code müsste komplett neu angepasst werden, # da er nicht von Anfang an darauf ausgelegt wurde (falls er überhaupt damit vereinbar ist). # Eine Möglichkeit, die zufällige Teilnehmerwahl für die Investitionsentscheidungen aus dec_list in # einem Dictionary namens decisions (statt vielen vordefinierten Variablen) zu speichern. # Dabei wird für alle Einträge in dec_list für alle Entscheidungen (die Hälfte der # Innovatorenanzahl) für 2 verschiedene Ideen ein Eintrag in decisions angelegt (key), der den Wert # von dem entsprechenden Eintrag der dec_list hat (value). # Also ein Eintrag bspw. {'player.dec.1_i1': 3}, wobei 3 dann dec_list[0] entspricht. # Allerdings scheint der Code entweder nur meinen PC/Browser zu überfordern oder generell zu # komplex(?) für Otree/Python/was auch immer zu sein. Das Experiment lädt dann nicht mehr. # decisions = {} # j = 1 # k = 1 # i = 0 # for i in range(len(dec_list)): # while j < ((Constants.num_participants - 1) / 2) + 1: # while k < 3: # decisions['player.dec{j}_i{k}'.format(j=j, k=k)] = dec_list[i] # k = k+1 # j = j+1 # TODO: erweitern indem statt 2 kreative ideen, so viele wie gemacht wurden gezogen werden # dann paarweise vergleichen, die ersten zwei in die erste entscheidung, die zweiten zwei in die zweite etc. # ist random weil die reihenfolge random gezogen wurde class Group(BaseGroup): dec1_i1 = models.IntegerField() dec1_i2 = models.IntegerField() # ID des teilnehmers 2 dessen creative idee angezeigt wird for decision 1 (randomly selected) dec2_i1 = models.IntegerField() dec2_i2 = models.IntegerField() dec3_i1 = models.IntegerField() dec3_i2 = models.IntegerField() dec4_i1 = models.IntegerField() dec4_i2 = models.IntegerField() dec5_i1 = models.IntegerField() dec5_i2 = models.IntegerField() dec6_i1 = models.IntegerField() dec6_i2 = models.IntegerField() dec7_i1 = models.IntegerField() dec7_i2 = models.IntegerField() dec8_i1 = models.IntegerField() dec8_i2 = models.IntegerField() invest_dec1_i1 = models.CurrencyField( # max=10, # Kann weggelassen werden, da error message angezeigt wird, wenn Beträge sich zu mehr als 10 summieren label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) # what investor invested in player dec_p1's creative idea invest_dec1_i2 = models.CurrencyField( # max=10, # siehe invest_dec1_i1 label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) # what investor invested in player dec_p2's creative idea invest_dec2_i1 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec2_i2 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec3_i1 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec3_i2 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec4_i1 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec4_i2 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec5_i1 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec5_i2 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec6_i1 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec6_i2 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec7_i1 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec7_i2 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec8_i1 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) invest_dec8_i2 = models.CurrencyField( label='Bitte tragen Sie ein, wie viel Sie in die kreative Idee investieren wollen' ) #def set_payoffs(self): # Ist in Player definiert, folgend nur die ersten Ideen, die mir dazu kamen. # Folgend der Anfang einer Idee mit einer Liste, in die die Investitionswerte eingefügt werden, um sie später # auszulesen und dabei den Playern zuzuordnen, die zu dieser decision gehörten. Funktioniert nicht, da ich nicht # herausfinden konnte, wie die Werte der Variablen (invest_dec_x_iy) in die Liste angefügt werden können. # investments = [] # investments.append() # Folgender Code funktioniert nicht, da es sich bei invest_decx_iy um Currency Felder handelt. #for player in self.get_players(): # player.payoff = [ # other.invest_dec1_i1 for other in player.get_others_in_subsession() if # other.dec1_i1 == player.id_in_subsession # ] # player.payoff = [ # other.invest_dec1_i2 for other in player.get_others_in_subsession() if # other.dec1_i2 == player.id_in_subsession # ] # Folgender Code funktioniert auch nciht, da die Variablen decx_iy nur für den Investor abgespeichert werden, # die Bedingungen für die Innovatoren dementsprechend nie erfüllt sein können. # if player.id_in_subsession == dec1_i1: # player.payoff = self.invest_dec1_i1 # elif player.id_in_subsession == dec1_i2: # player.payoff = self.invest_dec1_i2 #p1 = self.get_player_by_id(2) # das ist falsch, da id nicht gleich dec id #p2 = self.get_player_by_id(3) # das auch #p1.payoff = self.invest_dec1_i1 #p2.payoff = self.invest_dec1_i2 class Player(BasePlayer): # Wenn Player ID (treat_aux2) und Decision ID gleich sind, erhält der Player das Investment der entsprechenden # Decision ID. def set_payoffs(self): if self.treat_aux2 == self.group.dec1_i1: self.payoff = self.group.invest_dec1_i1 elif self.treat_aux2 == self.group.dec1_i2: self.payoff = self.group.invest_dec1_i2 elif self.treat_aux2 == self.group.dec2_i1: self.payoff = self.group.invest_dec2_i1 elif self.treat_aux2 == self.group.dec2_i2: self.payoff = self.group.invest_dec2_i2 elif self.treat_aux2 == self.group.dec3_i1: self.payoff = self.group.invest_dec3_i1 elif self.treat_aux2 == self.group.dec3_i2: self.payoff = self.group.invest_dec3_i2 elif self.treat_aux2 == self.group.dec4_i1: self.payoff = self.group.invest_dec4_i1 elif self.treat_aux2 == self.group.dec4_i2: self.payoff = self.group.invest_dec4_i2 elif self.treat_aux2 == self.group.dec5_i1: self.payoff = self.group.invest_dec5_i1 elif self.treat_aux2 == self.group.dec5_i2: self.payoff = self.group.invest_dec5_i2 elif self.treat_aux2 == self.group.dec6_i1: self.payoff = self.group.invest_dec6_i1 elif self.treat_aux2 == self.group.dec6_i2: self.payoff = self.group.invest_dec6_i2 elif self.treat_aux2 == self.group.dec7_i1: self.payoff = self.group.invest_dec7_i1 elif self.treat_aux2 == self.group.dec7_i2: self.payoff = self.group.invest_dec7_i2 elif self.treat_aux2 == self.group.dec8_i1: self.payoff = self.group.invest_dec8_i1 elif self.treat_aux2 == self.group.dec8_i2: self.payoff = self.group.invest_dec8_i2 photoid = models.StringField() treat_aux1 = models.IntegerField() treat_aux2 = models.IntegerField() treat = models.StringField() treat_investor_aux = models.StringField() treat_investor = models.StringField() full_path_to_image = models.LongStringField() image_info = models.LongStringField() word = models.StringField( label='Welches Wort haben Sie mit Ihrer kreativen Idee illustriert?' ) promotion_verbal = models.LongStringField( label='Bitte beschreiben Sie Ihre Idee.' ) promotion_grade = models.IntegerField( label='Wie bewerten Sie Ihre Idee?' ) # TODO: min, max? Welche Zahlen kann Score annehmen? float statt int? # Bei den folgenden formfields sind die Attribute (choices, label, widget...) egal, wenn sie als # Likert-Skala ausgegeben werden sollen. In dem Falle müssen die Attribute im HTML-form bestimmt werden. # (Bei fast allen formfields unten steht allerdings schon etwas, da sie bereits vor dem Programmieren der # Likert Skalen erstellt und danach erst in HTML angepasst wurden.) gender = models.IntegerField( choices=[ [0, 'männlich'], [1, 'weiblich'], [2, 'divers'] ], label='• Bitte geben Sie an, welchem Geschlecht Sie sich zuordnen.', widget=widgets.RadioSelect ) age = models.IntegerField( # TODO: Altersgenzen so passend? min=18, max=100, label='• Bitte geben Sie Ihr Alter an.' ) study_field = models.IntegerField( choices=[ [0, 'Jura'], [1, 'Wirtschaft'], [2, 'Geisteswissenschaften'], [3, 'Naturwissenschaften'], [4, 'Ingenieurswesen/IT'], [5, 'Kunst'] ], label='• Bitte geben Sie Ihr Studienfach an.' ) colourblindness = models.IntegerField( choices=[ [0, 'Nein'], [1, 'Ja'] ], label="• Haben Sie eine Rot-Grün-Farbenblindheit?" ) risk_preference = models.IntegerField( choices=[ [0, 'Gar nicht risikobereit'], [1, 'Eher nicht risikobereit'], [2, 'Mittelmäßig risikobereit'], [3, 'Eher risikobereit'], [4, 'Sehr risikobereit'] ], label='• Wie sehen Sie sich selbst: Sind Sie bereit, Risiken einzugehen, oder versuchen Sie sie zu verhindern?', widget=widgets.RadioSelectHorizontal ) competition_preference = models.IntegerField( choices=[ [0, 'Ich mag Wettbewerbe gar nicht'], [1, 'Ich mag Wettbewerbe eher nicht'], [2, 'Ich stehe Wettbewerben neutral gegenüber'], [3, 'Ich mag Wettbewerbe'], [4, 'Ich mag Wettbewerbe sehr gerne'] ], label='• Mögen Sie es, mit anderen im Wettbewerb zu stehen?', widget=widgets.RadioSelectHorizontal ) advantage = models.IntegerField( choices=[ [0, 'Weibliche Teilnehmer'], [1, ''], [2, ''], [3, 'Neutral'], [4, ''], [5, ''], [6, 'Männliche Teilnehmer'] ], label='• Denken Sie, dass eher weibliche oder dass eher männliche Teilnehmer bei dieser Aufgabe begünstigt sind?', widget=widgets.RadioSelectHorizontal ) tournaments = models.IntegerField( choices=[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, # TODO: mehr als 10 auch möglich ], label='• Wie viele Turniere haben Sie ungefähr gewonnen?' ) creativity = models.IntegerField( choices=[ [0, 'Gar nicht kreativ'], [1, 'Eher nicht kreativ'], [2, 'Mittelmäßig kreativ'], [3, 'Eher kreativ'], [4, 'Sehr kreativ'] ], label='• Wie kreativ sind Sie?', widget=widgets.RadioSelectHorizontal ) difficulty = models.IntegerField( choices=[ [0, 'Gar nicht schwierig'], [1, 'Eher nicht schwierig'], [2, 'Mittelmäßig schwierig'], # oder weder schwierig noch leicht? [3, 'Eher schwierig'], [4, 'Sehr schwierig'] ], label='• Wie schwierig war die Aufgabe für Sie?', widget=widgets.RadioSelectHorizontal ) stereotypes = models.IntegerField( choices=[ [0, 'Stereotypisch weiblich'], [1, 'Eher stereotypisch weiblich'], [2, 'Gering stereotypisch weiblich'], [3, 'Neutral'], [4, 'Gering stereotypisch männlich'], [5, 'Eher stereotypisch männlich'], [6, 'Stereotypisch männlich'] ], label='• Denken Sie, dass die Aufgabe eher stereotypisch weiblich oder eher stereotypisch männlich ist?', widget=widgets.RadioSelectHorizontal ) investment_likelihood = models.IntegerField( choices=[ [0, 'Sehr unwahrscheinlich'], [1, 'Unwahrscheinlich'], [2, 'Eher unwahrscheinlich'], [3, 'Mittlmäßig wahrscheinlich'], [4, 'Eher wahrscheinlich'], [5, 'Wahrscheinlich'], [6, 'Sehr wahrscheinlich'] ], label='• Wie schätzen Sie die Wahrscheinlichkeit ein, dass ein Investor in ihre kreative Idee investiert?', widget=widgets.RadioSelectHorizontal ) persuasiveness = models.IntegerField( choices=[ [0, 'Sehr unüberzeugend'], [1, 'Unüberzeugend'], [2, 'Eher unüberzeugend'], [3, 'Mittelmäßig überzeugend'], [4, 'Eher überzeugend'], [5, 'Überzeugend'], [6, 'Sehr überzeugend'] ], label='• Wie schätzen Sie die Überzeugungskraft ihrer Werbung ein?', widget=widgets.RadioSelectHorizontal ) estimate_identification = models.IntegerField( min=0, max=10, label='• Wie viele von 10 Bewertern werden Ihrer Einschätzung nach anhand des Bildes ihrer kreativen Idee ' 'das Wort erraten?' ) estimate_same_CI = models.IntegerField( min=0, max=100, label='• Wie viele von 100 zufällig ausgewählten Bildern von kreativen Ideen aus einem zuvorigen Experiment ' 'illustrieren ihrer Einschätzung nach das gleiche Wort wie Ihre kreative Idee?' )