from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random class Constants(BaseConstants): name_in_url = 'nosellers2' players_per_group = 2 num_rounds = 2 class Subsession(BaseSubsession): pass class Group(BaseGroup): seller_selection = models.IntegerField() def set_roles(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) for i in range(1, Constants.num_rounds +1): p1.in_round(i).type = 'buyer' p2.in_round(i).type = 'C' def set_seller_selection(self): self.seller_selection = random.randint(0, 1) def T1_offer(self): groups = self.subsession.get_group_matrix() g = 0 while self.id_in_subsession not in groups[g]: g = g + 1 group_products = self.li_T1_products[g] group_prices = self.li_T1_prices[g] self.get_player_by_id(1).T1_product = group_products[self.seller_selection] self.get_player_by_id(1).T1_price = group_prices[self.seller_selection] def T1_payoff_calc(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) if p1.T1_product == 1: #[1, "X"; 0, "Y"] if p1.T1_price <= p1.WTP_X: p1.T1_payoff = 80 + 50 - p1.T1_price p2.T1_payoff = 20 else: p1.T1_payoff = 80 p2.T1_payoff = 80 else: if p1.T1_price <= p1.WTP_Y: p1.T1_payoff = 80 + 50 - p1.T1_price p2.T1_payoff = 80 else: p1.T1_payoff = 80 p2.T1_payoff = 80 # Data Storage # !!! ONLY SAMPLE DATA !!! @property def li_T1_products(self): return [[0, 0], [1, 1], [0, 1], [0, 0]] @property def li_T1_prices(self): return [[20, 35], [30, 40], [50, 25], [30, 30]] ##### TEIL 2 ##### def T2_offer(self): groups = self.subsession.get_group_matrix() g = 0 while self.id_in_subsession not in groups[g]: g = g + 1 group_products = self.li_T2_products[g] group_prices = self.li_T2_prices[g] round_products = group_products[self.round_number - 1] round_prices = group_prices[self.round_number - 1] self.get_player_by_id(1).T2_product1 = round_products[0] self.get_player_by_id(1).T2_price1 = round_prices[0] self.get_player_by_id(1).T2_product2 = round_products[-1] self.get_player_by_id(1).T2_price2 = round_prices[-1] def T2_payoff_calc(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) if p1.buyer_choice == 0: p1.T2_payoff = 80 p2.T2_payoff = 80 elif p1.buyer_choice == 1: if p1.T2_product1 == 1: p1.T2_payoff = 80 + 50 - p1.T2_price1 p2.T2_payoff = 20 else: p1.T2_payoff = 80 + 50 - p1.T2_price1 p2.T2_payoff = 80 elif p1.buyer_choice == 2: if p1.T2_product2 == 1: p1.T2_payoff = 80 + 50 - p1.T2_price2 p2.T2_payoff = 20 else: p1.T2_payoff = 80 + 50 - p1.T2_price2 p2.T2_payoff = 80 # Data Storage # !!! ONLY SAMPLE DATA !!! @property def li_T2_products(self): return [ [[0, 0], [0, 0], [0, 0], [1, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], #1 [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [1, 0], [0, 0], [0, 0], [0, 0]], [[1, 1], [0, 1], [1, 1], [1, 0], [0, 1], [1, 0], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], #2 [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1], [1, 1]], [[0, 1], [1, 0], [0, 0], [0, 0], [0, 1], [1, 0], [1, 0], [0, 0], [0, 0], [1, 0], [1, 0], [0, 0], [0, 0], #3 [0, 1], [0, 0], [1, 1], [0, 0], [0, 0], [0, 0], [0, 0], [1, 0], [0, 0], [0, 0], [0, 0]], [[0, 0], [0, 0], [0, 0], [0, 1], [1, 1], [1, 0], [1, 0], [1, 1], [1, 1], [1, 1], [1, 0], [1, 1], [1, 1], #4 [1, 1], [1, 0], [1, 0], [0, 1], [0, 1], [0, 0], [0, 1], [0, 1], [1, 0], [0, 1], [0, 1]] ] @property def li_T2_prices(self): return [ [[20, 35], [30, 25], [30, 21], [20, 30], [30, 21], [30, 25], [30, 45], [30, 40], [45, 50], [50, 45], [48, 50], [45, 47], [45, 44], [35, 30], [35, 30], [35, 30], [30, 29], [50, 29], [45, 50], [45, 44], [50, 40], [45, 45], [45, 40], [38, 35]], [[30, 40], [50, 25], [40, 30], [35, 30], [40, 30], [40, 30], [30, 30], [30, 30], [25, 30], [30, 20], [25, 25], [20, 25], [25, 20], [20, 20], [20, 20], [15, 20], [20, 15], [15, 15], [10, 10], [10, 10], [10, 10], [10, 10], [10, 10], [10, 10]], [[50, 25], [10, 40], [35, 40], [40, 35], [34, 30], [50, 32], [35, 35], [40, 35], [35, 32], [25, 29], [35, 35], [40, 33], [32, 3], [35, 25], [25, 33], [20, 30], [30, 35], [30, 33], [30, 25], [31, 30], [10, 28], [30, 50], [40, 35], [35, 30]], [[30, 30], [25, 30], [25, 30], [25, 15], [15, 40], [30, 20], [40, 30], [40, 20], [25, 40], [30, 25], [30, 30], [30, 30], [25, 25], [28, 25], [24, 20], [35, 30], [30, 20], [25, 24], [25, 30], [25, 20], [25, 20], [20, 20], [25, 20], [20, 20]] ] ##### TEIL 4 ##### part_payed = models.IntegerField() round_payed = models.IntegerField() def set_payoff(self): self.part_payed = random.randint(1, 2) self.round_payed = random.randint(1, Constants.num_rounds) for p in self.get_players(): if self.part_payed == 1: p.payoff = c(p.in_round(1).T1_payoff) else: p.payoff = c(p.in_round(self.round_payed).T2_payoff) class Player(BasePlayer): type = models.StringField() ##### Teil 1 ##### t_order = models.IntegerField() T1_product = models.IntegerField() T1_price = models.IntegerField() WTP_X = models.IntegerField() WTP_Y = models.IntegerField() T1_payoff = models.IntegerField() T1_p02x = models.IntegerField() T1_p04x = models.IntegerField() T1_p08x = models.IntegerField() T1_p12x = models.IntegerField() T1_p16x = models.IntegerField() T1_p20x = models.IntegerField() T1_p24x = models.IntegerField() T1_p28x = models.IntegerField() T1_p32x = models.IntegerField() T1_p36x = models.IntegerField() T1_p40x = models.IntegerField() T1_p44x = models.IntegerField() T1_p48x = models.IntegerField() T1_p50x = models.IntegerField() T1_p02y = models.IntegerField() T1_p04y = models.IntegerField() T1_p08y = models.IntegerField() T1_p12y = models.IntegerField() T1_p16y = models.IntegerField() T1_p20y = models.IntegerField() T1_p24y = models.IntegerField() T1_p28y = models.IntegerField() T1_p32y = models.IntegerField() T1_p36y = models.IntegerField() T1_p40y = models.IntegerField() T1_p44y = models.IntegerField() T1_p48y = models.IntegerField() T1_p50y = models.IntegerField() def table_sequence(self): if self.type == 'buyer': self.t_order = random.choice([1, 2]) else: pass def set_WTP(self): if self.type == 'buyer': if self.T1_p50x == 1: self.WTP_X = 50 elif self.T1_p48x == 1: self.WTP_X = 48 elif self.T1_p44x == 1: self.WTP_X = 44 elif self.T1_p40x == 1: self.WTP_X = 40 elif self.T1_p36x == 1: self.WTP_X = 36 elif self.T1_p32x == 1: self.WTP_X = 32 elif self.T1_p28x == 1: self.WTP_X = 28 elif self.T1_p24x == 1: self.WTP_X = 24 elif self.T1_p20x == 1: self.WTP_X = 20 elif self.T1_p16x == 1: self.WTP_X = 16 elif self.T1_p12x == 1: self.WTP_X = 12 elif self.T1_p08x == 1: self.WTP_X = 8 elif self.T1_p04x == 1: self.WTP_X = 4 elif self.T1_p02x == 1: self.WTP_X = 2 else: self.WTP_X = 0 ######### if self.T1_p50y == 1: self.WTP_Y = 50 elif self.T1_p48y == 1: self.WTP_Y = 48 elif self.T1_p44y == 1: self.WTP_Y = 44 elif self.T1_p40y == 1: self.WTP_Y = 40 elif self.T1_p36y == 1: self.WTP_Y = 36 elif self.T1_p32y == 1: self.WTP_Y = 32 elif self.T1_p28y == 1: self.WTP_Y = 28 elif self.T1_p24y == 1: self.WTP_Y = 24 elif self.T1_p20y == 1: self.WTP_Y = 20 elif self.T1_p16y == 1: self.WTP_Y = 16 elif self.T1_p12y == 1: self.WTP_Y = 12 elif self.T1_p08y == 1: self.WTP_Y = 8 elif self.T1_p04y == 1: self.WTP_Y = 4 elif self.T1_p02y == 1: self.WTP_Y = 2 else: self.WTP_Y = 0 else: pass # Control questions # cont1_false = models.IntegerField(initial=0) cont4_false = models.IntegerField(initial=0) cont5_false = models.IntegerField(initial=0) cont6_false = models.IntegerField(initial=0) cont7_false = models.IntegerField(initial=0) control1 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, "findet der Kauf statt."], [1, "findet der Kauf nicht statt."] ], label="") control4 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, "erhöht sich seine Auszahlung um 50 Punkte abzüglich des Produktpreises."], [1, "erhöht sich seine Auszahlung um 50 Punkte."] ], label="") control5 = models.IntegerField(widget=widgets.RadioSelect, choices=[0, 20, 60, 80], label="") control6 = models.IntegerField(widget=widgets.RadioSelect, choices=[0, 20, 60, 80], label="") control7 = models.IntegerField(widget=widgets.RadioSelect, choices=[0, 20, 60, 80], label="") def control1_error_message(player, value): if value != 0: player.cont1_false += 1 return 'Wenn ein Käufer bereit ist, für das Produkt einen höheren Preis als den Angebotspreis zu zahlen, findet der Kauf statt. Der Käufer zahlt den Angebotspreis.' def control4_error_message(player, value): if value != 0: player.cont4_false += 1 return 'Wenn ein Käufer ein Produkt X oder ein Produkt Y kauft, erhöht sich seine Auszahlung um 50 Punkte abzüglich des Produktpreises.' def control5_error_message(player, value): if value != 80: player.cont5_false += 1 return 'Wenn der Käufer kein Produkt kauft, entsteht kein Verlust für Teilnehmer 2. Der Teilnehmer 2 behält seine Anfangsausstattung von 80 Punkten.' def control6_error_message(player, value): if value != 20: player.cont6_false += 1 return 'Wenn der Käufer ein Produkt X kauft, entsteht ein Verlust von 60 Punkten für Teilnehmer 2. Somit ist die Auszahlung von Teilnehmer 2: 80 Punkte - 60 Punkte = 20 Punkte.' def control7_error_message(player, value): if value != 80: player.cont7_false += 1 return 'Wenn der Käufer ein Produkt Y kauft, entsteht kein Verlust für Teilnehmer 2. Der Teilnehmer 2 behält also seine Anfangsausstattung von 80 Punkten.' ##### Teil2 ##### # Control questions # cont1_T2_false = models.IntegerField(initial=0) cont2_T2_false = models.IntegerField(initial=0) cont4_T2_false = models.IntegerField(initial=0) control1_T2 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, "Sie können Ihre Rolle als Käufer oder Teilnehmer 2 während der Gesamtdauer der Studie wechseln."], [1, "Sie behalten Ihre Rolle als Käufer oder Teilnehmer 2 für die Gesamtdauer der Studie."] ], label="") control2_T2 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, "Jede Gruppe bestehend aus einem Käufer und einem Teilnehmer 2 wird in jeder der 24 Runden nach dem Zufallsprinzip neu zusammengestellt."], [1, "Jede Gruppe bestehend aus einem Käufer und einem Teilnehmer 2 bleibt während der 24 Runden bestehen."] ], label="") control4_T2 = models.IntegerField(widget=widgets.RadioSelect, choices=[0, 20, 50, 60], label="") def control1_T2_error_message(player, value): if value != 1: player.cont1_T2_false += 1 return 'Sie behalten Ihre Rolle als Käufer oder Teilnehmer 2 für die Gesamtdauer der Studie.' def control2_T2_error_message(player, value): if value != 0: player.cont2_T2_false += 1 return 'Jede Gruppe bestehend aus einem Käufer und einem Teilnehmer 2 wird in jeder der 24 Runden nach dem Zufallsprinzip neu zusammengestellt.' def control4_T2_error_message(player, value): if value != 20: player.cont4_T2_false += 1 return 'Das Produkt Y, welches keinen Verlust für Teilnehmer 2 verursacht, hat einen Mindestpreis von 20 Punkten.' T2_product1 = models.IntegerField() T2_price1 = models.IntegerField() T2_product2 = models.IntegerField() T2_price2 = models.IntegerField() buyer_choice = models.IntegerField(min=0, max=2) T2_payoff = models.IntegerField() ##### TEIL 3 ###### age = models.IntegerField(min=16, max=99, label="") sex = models.IntegerField(initial=None, widget=widgets.RadioSelect, label="", choices=[[0, "weiblich"], [1, "männlich"], [2, "divers"]]) experience = models.IntegerField(initial=None, widget=widgets.RadioSelect, label="", choices=[[0, "noch nie"], [1, "1 bis 2 mal"], [2, "3 bis 5 mal"], [3, "öfter"]]) studies = models.StringField(label="") markets1 = models.IntegerField(initial=None, choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) markets2 = models.IntegerField(initial=None, choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) markets3 = models.IntegerField(initial=None, choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) markets4 = models.IntegerField(initial=None, choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) markets5 = models.IntegerField(initial=None, choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) markets6 = models.IntegerField(initial=None, choices=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) verstanden = models.IntegerField(initial=None, blank=True, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) not_harming_member = models.IntegerField(initial=None, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) ownpayoff = models.IntegerField(initial=None, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) utilitarian = models.IntegerField(initial=None, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) quality_check = models.IntegerField(initial=None, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) wtp_x_buyer = models.IntegerField(initial=None, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) wtp_y_buyer = models.IntegerField(initial=None, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) x_tendency_buyer = models.IntegerField(initial=None, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) partei = models.IntegerField(initial=None, widget=widgets.RadioSelect, choices=[ [1, "SPD"], [2, "Grüne"], [3, "CSU"], [4, "CDU"], [5, "LINKE"], [6, "FDP"], [7, "AfD"], [8, "Andere Partei"]]) pol_selbstein = models.IntegerField(initial=None, widget=widgets.RadioSelectHorizontal, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"], [7, "R6"], [8, "R7"], [9, "R8"], [10, "R9"]]) allocation1 = models.FloatField() allocation2 = models.FloatField() allocation3 = models.FloatField() allocation4 = models.FloatField() allocation5 = models.FloatField() allocation6 = models.FloatField() ### Payment Info ### name = models.StringField(label="Vorname:") surname = models.StringField(label="Nachname:") method = models.StringField(widget=widgets.RadioSelect, choices=["Banküberweisung", "PayPal"], label="Zahlungsmethode:", initial=0) IBAN = models.StringField() mail = models.StringField()