from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range, ) import random import itertools import numpy as np class Constants(BaseConstants): name_in_url = 'sellers2' players_per_group = 4 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) p3 = self.get_player_by_id(3) p4 = self.get_player_by_id(4) for i in range(1, Constants.num_rounds +1): p1.in_round(i).type = 'seller' p2.in_round(i).type = 'seller' p3.in_round(i).type = 'buyer' p4.in_round(i).type = 'C' def T1_payoff_calc(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p3 = self.get_player_by_id(3) p4 = self.get_player_by_id(4) self.seller_selection = random.randint(1, 2) if self.seller_selection == 1: if p1.T1_product == 1: #[1, "X"; 0, "Y"] if p1.T1_price <= p3.WTP_X: p1.T1_payoff = 80 + p1.T1_price p2.T1_payoff = 80 p3.T1_payoff = 80 + 50 - p1.T1_price p4.T1_payoff = 20 else: p1.T1_payoff = 80 p2.T1_payoff = 80 p3.T1_payoff = 80 p4.T1_payoff = 80 else: if p1.T1_price <= p3.WTP_Y: p1.T1_payoff = 80 + p1.T1_price p2.T1_payoff = 80 p3.T1_payoff = 80 + 50 - p1.T1_price p4.T1_payoff = 80 else: p1.T1_payoff = 80 p2.T1_payoff = 80 p3.T1_payoff = 80 p4.T1_payoff = 80 else: if p2.T1_product == 1: #[1, "X"; 0, "Y"] if p2.T1_price <= p3.WTP_X: p1.T1_payoff = 80 p2.T1_payoff = 80 + p2.T1_price p3.T1_payoff = 80 + 50 - p2.T1_price p4.T1_payoff = 20 else: p1.T1_payoff = 80 p2.T1_payoff = 80 p3.T1_payoff = 80 p4.T1_payoff = 80 else: if p2.T1_price <= p3.WTP_Y: p1.T1_payoff = 80 p2.T1_payoff = 80 + p2.T1_price p3.T1_payoff = 80 + 50 - p2.T1_price p4.T1_payoff = 80 else: p1.T1_payoff = 80 p2.T1_payoff = 80 p3.T1_payoff = 80 p4.T1_payoff = 80 ##### TEIL 2 ##### offer_order = models.IntegerField() def set_offer_order(self): self.offer_order = random.randint(0, 1) def product_offered(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p1.T2_product = random.choice('XY') if p1.T2_product == 'Y': p2.T2_product = 'X' else: p2.T2_product = random.choice('XY') def T2_payoff_calc(self): p1 = self.get_player_by_id(1) p2 = self.get_player_by_id(2) p3 = self.get_player_by_id(3) p4 = self.get_player_by_id(4) if p3.buyer_choice == 0: p1.T2_payoff = 80 p2.T2_payoff = 80 p3.T2_payoff = 80 p4.T2_payoff = 80 elif p3.buyer_choice == 1: if self.offer_order == 0: if p1.T2_product == 'X': p1.T2_payoff = 80 + p1.seller_price_X p2.T2_payoff = 80 p3.T2_payoff = 80 + 50 - p1.seller_price_X p4.T2_payoff = 20 else: p1.T2_payoff = 80 + p1.seller_price_Y p2.T2_payoff = 80 p3.T2_payoff = 80 + 50 - p1.seller_price_Y p4.T2_payoff = 80 else: if p2.T2_product == 'X': p1.T2_payoff = 80 p2.T2_payoff = 80 + p2.seller_price_X p3.T2_payoff = 80 + 50 - p2.seller_price_X p4.T2_payoff = 20 else: p1.T2_payoff = 80 p2.T2_payoff = 80 + p2.seller_price_Y p3.T2_payoff = 80 + 50 - p2.seller_price_Y p4.T2_payoff = 80 elif p3.buyer_choice == 2: if self.offer_order == 0: if p2.T2_product == 'X': p1.T2_payoff = 80 p2.T2_payoff = 80 + p2.seller_price_X p3.T2_payoff = 80 + 50 - p2.seller_price_X p4.T2_payoff = 20 else: p1.T2_payoff = 80 p2.T2_payoff = 80 + p2.seller_price_Y p3.T2_payoff = 80 + 50 - p2.seller_price_Y p4.T2_payoff = 80 else: if p1.T2_product == 'X': p1.T2_payoff = 80 + p1.seller_price_X p2.T2_payoff = 80 p3.T2_payoff = 80 + 50 - p1.seller_price_X p4.T2_payoff = 20 else: p1.T2_payoff = 80 + p1.seller_price_Y p2.T2_payoff = 80 p3.T2_payoff = 80 + 50 - p1.seller_price_Y p4.T2_payoff = 80 ##### 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(choices=[[0, "Y"], [1, "X"]]) T1_price = models.IntegerField(min=0, max=50, label="") 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 # control1 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, "findet der Kauf statt."], [1, "findet der Kauf nicht statt."] ], label="") control2 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, "behält er seine Anfangsausstattung von 80 Punkten."], [1, "erhält er seine Anfangsausstattung von 80 Punkten plus den Preis, den er für sein Produkt verlangt."] ], label="") control3 = models.IntegerField(widget=widgets.RadioSelect, choices=[0, 20, 80, 100], 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="") cont1_false = models.IntegerField(initial=0) cont2_false = models.IntegerField(initial=0) cont3_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) 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, den der zufällig ausgewählte Verkäufer dafür verlangt, findet der Kauf statt. Der Käufer zahlt dem zufällig ausgewählten Verkäufer den Angebotspreis, den er für sein Produkt verlangt.' def control2_error_message(player, value): if value != 1: player.cont2_false += 1 return 'Wenn ein Verkäufer sein Produkt verkauft, erhält der Verkäufer seine Anfangsausstattung von 80 Punkten plus den Preis, den er für sein Produkt verlangt.' def control3_error_message(player, value): if value != 80: player.cont3_false += 1 return 'Da ein nicht zufällig ausgewählter Verkäufer nicht am Handel beteiligt ist und somit sein Produkt nicht verkaufen kann, behält er seine Anfangsausstattung von 80 Punkten.' 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 C. Der Teilnehmer C 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 C. Somit ist die Auszahlung von Teilnehmer C: 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 C. Der Teilnehmer C behält also seine Anfangsausstattung von 80 Punkten.' ##### Teil2 ##### # Control questions # control1_T2 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, "Sie können Ihre Rolle als Verkäufer, Käufer oder Teilnehmer C während der Gesamtdauer der Studie wechseln."], [1, "Sie behalten Ihre Rolle als Verkäufer, Käufer oder Teilnehmer C für die Gesamtdauer der Studie."] ], label="") control2_T2 = models.IntegerField(widget=widgets.RadioSelect, choices=[ [0, "Jede Gruppe bestehend aus zwei Verkäufern, einem Käufer und einem Teilnehmer C wird in jeder der 24 Runden nach dem Zufallsprinzip neu zusammengestellt."], [1, "Jede Gruppe bestehend aus zwei Verkäufern, einem Käufer und einem Teilnehmer C bleibt während der 24 Runden bestehen."] ], label="") control4_T2 = models.IntegerField(widget=widgets.RadioSelect, choices=[0, 20, 50, 60], label="") cont1_T2_false = models.IntegerField(initial=0) cont2_T2_false = models.IntegerField(initial=0) cont4_T2_false = models.IntegerField(initial=0) def control1_T2_error_message(player, value): if value != 1: player.cont1_false += 1 return 'Sie behalten Ihre Rolle als Verkäufer, Käufer oder Teilnehmer C für die Gesamtdauer der Studie.' def control2_T2_error_message(player, value): if value != 0: player.cont2_false += 1 return 'Jede Gruppe bestehend aus zwei Verkäufern, einem Käufer und einem Teilnehmer C wird in jeder der 24 Runden nach dem Zufallsprinzip neu zusammengestellt.' def control4_T2_error_message(player, value): if value != 20: player.cont4_false += 1 return 'Das Produkt Y, welches keinen Verlust für Teilnehmer C verursacht, hat einen Mindestpreis von 20 Punkten.' T2_product = models.StringField(initial='') seller_price_X = models.IntegerField(min=0, max=50, label='') seller_price_Y = models.IntegerField(min=20, max=50, label='') 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"]]) belief_buyer_sellers1 = models.IntegerField(initial=None, choices=[ [1, "R0"], [2, "R1"], [3, "R2"], [4, "R3"], [5, "R4"], [6, "R5"]]) belief_buyer_sellers2 = 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()