from otree.api import * doc = """ Your app description """ class C(BaseConstants): NAME_IN_URL = 'Experiment' PLAYERS_PER_GROUP = 4 #auf 5 ändern NUM_ROUNDS = 20 class Subsession(BaseSubsession): pass ###Dieser Abschnitt randomisiert die Zuweisung in Experimental oder Kontrollgruppe konstant über alle Runden hinweg### def creating_session(subsession: Subsession): # Zufällige Zuweisung nur in der ersten Runde vornehmen if subsession.round_number == 1: for group in subsession.get_groups(): import random # Zufällige Zuweisung der Gruppen zu Experimental (True) oder Kontroll (False) group.experimental = random.choice([True, True, True, True, True]) print('Set experimental to', group.experimental) else: # In den folgenden Runden die Zuweisung aus der vorherigen Runde beibehalten for group in subsession.get_groups(): group.experimental = group.in_round(subsession.round_number - 1).experimental print('Set experimental to', group.experimental) ###################################################################################################################### class Group(BaseGroup): experimental = models.BooleanField() #Wird benötigt für die randomisierte Zuweisung in Experimental oder Kontrollgruppe # Initialisiert `lowest_level` mit einem hohen Startwert. # Dieser Wert wird später mit dem tatsächlich niedrigsten Level der Spieler in der Gruppe überschrieben. lowest_level = models.IntegerField(initial=10) def set_lowest_level(self): """ Diese Methode ermittelt den niedrigsten Level-Wert, der von einem Spieler in dieser Gruppe gewählt wurde. Sie durchläuft alle Spieler in der Gruppe, sammelt ihre Level-Werte und aktualisiert `lowest_level` der Gruppe auf den niedrigsten gefundenen Wert. Diese Methode wird in der `Level`-WaitPage nach der Level-Auswahl der Spieler aufgerufen. Der Aufruf erfolgt in der Methode `after_all_players_arrive` der `Level`-WaitPage, um sicherzustellen, dass der niedrigste Wert korrekt erfasst wird, nachdem alle Spieler ihre Entscheidungen getroffen haben. """ levels = [player.level for player in self.get_players()] self.lowest_level = min(levels) class Player(BasePlayer): # Alle benötigten Eingaben prediction = models.IntegerField( label="Was ist Ihre Vorhersage?", choices = list(range(0, 11)), #In Python beginnt range(start, stop) bei start und geht bis, aber nicht einschließlich, stop. Deshalb verwenden wir range(0, 11), um Zahlen von 0 bis 10 zu erhalten. widget=widgets.RadioSelect ) level = models.IntegerField( label="Deine Entscheidung für X:", choices = list(range(0, 11)), #In Python beginnt range(start, stop) bei start und geht bis, aber nicht einschließlich, stop. Deshalb verwenden wir range(0, 11), um Zahlen von 0 bis 10 zu erhalten. widget=widgets.RadioSelect ) # Neue Felder hinzufügen, um die Werte zu speichern matrix_payout_field = models.CurrencyField() prediction_payout_field = models.CurrencyField() total_payout_field = models.CurrencyField() #Sortierte Predictions def other_players_predictions(self): predictions = [p.prediction for p in self.group.get_players() if p.id_in_group != self.id_in_group] return sorted(predictions, reverse=True) # Die Liste wird nun absteigend sortiert zurückgegeben def get_lowest_other_players_level(self): """ Diese Methode ermittelt den niedrigsten Level-Wert, der von den anderen Spielern in der Gruppe gewählt wurde. Sie durchläuft alle Spieler in der Gruppe (ausser dem aktuellen Spieler selbst), sammelt ihre Level-Werte und gibt den niedrigsten dieser Werte zurück. Falls keine anderen Spieler vorhanden sind, gibt sie None zurück. """ other_players_levels = [p.level for p in self.group.get_players() if p != self] return min(other_players_levels) if other_players_levels else None # Für aktuelle Runde def matrix_payout(self): payout_matrix = { 10: [95, 85, 75, 65, 55, 45, 35, 25, 15, 5], 9: [None, 90, 80, 70, 60, 50, 40, 30, 20, 10], 8: [None, None, 85, 75, 65, 55, 45, 35, 25, 15], 7: [None, None, None, 80, 70, 60, 50, 40, 30, 20], 6: [None, None, None, None, 75, 65, 55, 45, 35, 25], 5: [None, None, None, None, None, 70, 60, 50, 40, 30], 4: [None, None, None, None, None, None, 65, 55, 45, 35], 3: [None, None, None, None, None, None, None, 60, 50, 40], 2: [None, None, None, None, None, None, None, None, 55, 45], 1: [None, None, None, None, None, None, None, None, None, 50] } matrix_payout_value = payout_matrix[self.level][10 - self.group.lowest_level] return matrix_payout_value if matrix_payout_value is not None else 0 def prediction_payout(self): # Auszahlung für genaue Vorhersage return 100 if self.prediction == self.get_lowest_other_players_level() else 0 def total_payout(self): # Gesamtauszahlung der aktuellen Runde berechnen return self.matrix_payout() + self.prediction_payout() def calculate_and_store_payouts(self): self.matrix_payout_field = self.matrix_payout() self.prediction_payout_field = self.prediction_payout() self.total_payout_field = self.matrix_payout_field + self.prediction_payout_field self.payoff = self.total_payout_field # PAGES class _1_Vorhersage(Page): form_model = 'player' form_fields = ['prediction'] class Vorhersage(WaitPage): pass import json #wird benötigt um in _2_Level die bereits ausgewählten predictions und experimentalgruppe (ja/nein) nutzen zu können, um die spalten hervorzuheben class _2_Level(Page): form_model = 'player' form_fields = ['level'] @staticmethod def vars_for_template(player: Player): other_players_predictions_json = json.dumps(player.other_players_predictions()) is_experimental_group_json = json.dumps(player.group.experimental) return { 'other_players_predictions_json': other_players_predictions_json, 'is_experimental_group_json': is_experimental_group_json } class Level(WaitPage): def after_all_players_arrive(self): self.group.set_lowest_level() for player in self.group.get_players(): player.calculate_and_store_payouts() class _3_Resultate(Page): @staticmethod def vars_for_template(self): matrix_payout = self.matrix_payout() prediction_payout = self.prediction_payout() total_payout = self.total_payout() """ Diese Methode bereitet zwei Variablen für die Nutzung in der HTML-Vorlage vor: 1. 'lowest_level': Der niedrigste Level-Wert, der von einem Spieler in dieser Gruppe ausgewählt wurde. Dieser Wert wird aus der `Group`-Klasse abgerufen. Der Wert `lowest_level` wird in der `Group`-Klasse berechnet und hier für die Anzeige auf der Seite verwendet. Dies ermöglicht es, den niedrigsten gewählten Level aller Spieler in der Gruppe auf der Ergebnisseite anzuzeigen. 2. 'lowest_other_players_level': Der niedrigste Level-Wert, der von den anderen Spielern in der Gruppe (außer dem aktuellen Spieler) gewählt wurde. Dieser Wert wird durch die Methode `get_lowest_other_players_level` des aktuellen Spielers berechnet und an die HTML-Vorlage übergeben. Diese Methode stellt sicher, dass der berechnete Wert den aktuellen Spieler ausschließt und nur die Auswahl der anderen Spieler berücksichtigt. """ return { 'lowest_level': self.group.lowest_level, 'lowest_other_players_level': self.get_lowest_other_players_level(), 'matrix_payout': matrix_payout, 'prediction_payout': prediction_payout, 'total_payout': total_payout } class Resultate(WaitPage): pass # SEQUENZ page_sequence = [_1_Vorhersage, Vorhersage, _2_Level, Level, _3_Resultate, Resultate]