import random from otree.api import * from otree import settings import csv from json import JSONDecodeError import math import decimal import os doc = """ Your app description """ def idread_csv(csv_path='', delimiter=';'): import csv path = os.path.join(__name__,csv_path) with open(path , encoding='utf-8-sig') as d: reader = csv.DictReader(d, delimiter=delimiter) ids = [int(row['IDs']) for row in reader] return ids class C(BaseConstants): NAME_IN_URL = 'social_proximity_part2' PLAYERS_PER_GROUP = None # should be 3 but is not coorect cause of variable NUM_ROUNDS = 10 #10 use 5 for testing SWAP_SELLER_ROUND = 8 # change if necessary CSV_PATH = "csv_thursday_utf8.csv" #"csv_wednesday_utf8.csv" LIST_OF_IDs = idread_csv(csv_path=CSV_PATH) NO_TRANS_PAYOFF = 8 #if kunde decides for no transaction with anbieter INSTRUCTION_TEMPLATE = __name__ + '/instruction_template.html' TIMER_TEXT = "Verbleibende Zeit:" TREATMENTS_NAMES = ['Base','Similar'] MODE_NAME = ['Test','Normal'] FAC_FORANBIETER = 1.25 UTIL_FORKUNDE = 2.4 FAC_FORKUNDE = 1.5 def read_csv(): f = open(__name__ + '/Analogien2.csv', encoding='utf-8-sig') rows = list(csv.DictReader(f)) # print(rows) return rows def aread_csv(): d = open(__name__ + '/NumberSequences2.csv', encoding='utf-8-sig') srows = list(csv.DictReader(d)) #print("Secondfile",srows) return srows def cread_csv(csv_path = '', delimiter=';'): d = open(f'{__name__}/{csv_path}', encoding='utf-8-sig') srows = list(csv.DictReader(d, delimiter=delimiter)) # print("list",srows) return srows class Subsession(BaseSubsession): TREATMENT = models.StringField(initial='Similar') MODE = models.StringField(initial='Test') AVERAGE_SIMILARITY_PLAYER_X_PLAYER = models.IntegerField(initial= -1) def creating_session(subsession: Subsession): subsession.TREATMENT = 'Similar' subsession.MODE ='Test' if 'sp_treatment' in subsession.session.config: subsession.TREATMENT = subsession.session.config['sp_treatment'] subsession.session.vars['treatment'] = subsession.TREATMENT if 'mode' in subsession.session.config: subsession.MODE = subsession.session.config['mode'] # Split stimuli into first 20 and last 20 questions stimuli = read_csv() stimuli_first_20 = stimuli[:20] stimuli_last_20 = stimuli[20:40] # Assign the number of trials for each player for p in subsession.get_players(): p.num_trials = len(stimuli_first_20) # Get the used indices from session variables, or initialize an empty list used_indicesA = p.participant.vars.get('used_indicesA', []) # Generate a unique random index if there are available questions if len(used_indicesA) < len(stimuli_first_20): available_indices = [i for i in range(len(stimuli_first_20)) if i not in used_indicesA] random_index = random.choice(available_indices) used_indicesA.append(random_index) p.participant.vars['used_indicesA'] = used_indicesA # Create the trial using the random index Trial.create(player=p, **stimuli_first_20[random_index]) # Assign the number of trials for each player for r in subsession.get_players(): r.num_trials = len(stimuli_last_20) # Get the used indices from session variables, or initialize an empty list used_indicesA = r.participant.vars.get('used_indicesA', []) # Generate a unique random index if there are available questions if len(used_indicesA) < len(stimuli_last_20): available_indices = [i for i in range(len(stimuli_last_20)) if i not in used_indicesA] random_index = random.choice(available_indices) used_indicesA.append(random_index) r.participant.vars['used_indicesA'] = used_indicesA # Create the trial using the random index Trial1.create(player=r, **stimuli_last_20[random_index]) astimuli = aread_csv() # einschub philip for player in subsession.get_players(): #todo: 20 is hardcoded as behnud needed the code, use a constant for this in the future indices_seller = list(range(0, 24)) indices_customer = list(range(0,24)) random.shuffle(indices_seller) random.shuffle(indices_customer) for i in list(range(0,10)): num_seq_seller = astimuli[indices_seller[i]] num_seq_customer = astimuli[indices_customer[i]] num_seq_seller2 = astimuli[indices_seller[i+10]] #seller Numb.create( player = player, round_number = i+1, question = num_seq_seller['question'], solution = num_seq_seller['solution'] )#customer Numb2.create( player=player, round_number=i + 1, question=num_seq_customer['question'], solution=num_seq_customer['solution'] ) #Anbieter Numb1.create( player = player, round_number = i+1, question = num_seq_seller2['question'], solution = num_seq_seller2['solution'] ) ## ende einschub # Assign the number of trials for each player for r in subsession.get_players(): r.num_trials = len(stimuli) # Get the used indices from session variables, or initialize an empty list used_indicesC = r.participant.vars.get('used_indicesC', []) # Generate a unique random index if there are available questions if len(used_indicesC) < len(stimuli): available_indices = [i for i in range(len(stimuli)) if i not in used_indicesC] random_index = random.choice(available_indices) used_indicesC.append(random_index) r.participant.vars['used_indicesC'] = used_indicesC # Create the trial using the random index Trial2.create(player=r, **stimuli[random_index]) data = cread_csv(C.CSV_PATH) for row in data: ScoresComplete.create( IDs=row['IDs'], Scores=row['Scores'], Politik=row['Politik'], Kultur=row['Kultur'], Technik=row['Technik'], Sport=row['Sport'], Familie=row['Familie'], Wellness=row['Wellness'], Philosophie=row['Philosophie'], Tiere=row['Tiere'], Ballsport=row['Ballsport'], Wintersport=row['Wintersport'], Wassersport=row['Wassersport'], Kraftsport=row['Kraftsport'], Yoga=row['Yoga'], Reiten=row['Reiten'], Klettern=row['Klettern'], Leichtathletik=row['Leichtathletik'], Kampfsport=row['Kampfsport'], Motorsport=row['Motorsport'], Tanzsport=row['Tanzsport'], NoSport=row['NoSport'], Klassik=row['Klassik'], Deutsche=row['Deutsche'], Pop=row['Pop'], Rap=row['Rap'], Rock=row['Rock'], Reggae=row['Reggae'], Jazz=row['Jazz'], Electronic=row['Electronic'], Krimi=row['Krimi'], THorror=row['THorror'], Liebesfilme=row['Liebesfilme'], Action=row['Action'], comedy=row['comedy'], Fiction=row['Fiction'], Dokus=row['Dokus'], Animation=row['Animation'], Meer=row['Meer'], Bergen=row['Bergen'], Stadte=row['Stadte'], Party=row['Party'], Hauptsache=row['Hauptsache'], abschalten=row['abschalten'], Umso=row['Umso'], Hause=row['Hause'], karrierebewusst=row['karrierebewusst'], kinderlieb=row['kinderlieb'], sportlich=row['sportlich'], zuruckhaltend=row['zuruckhaltend'], sparsam=row['sparsam'], warmherzig=row['warmherzig'], zuverlassig=row['zuverlassig'], humorvoll=row['humorvoll'], aufgelegt=row['aufgelegt'], gute=row['gute'], ernsthaft=row['ernsthaft'], vertraumt=row['vertraumt'], sachlich=row['sachlich'], Losung=row['Losung'], bringen=row['bringen'], lebhaft=row['lebhaft'], Freundschaft=row['Freundschaft'], Liebe=row['Liebe'], Ruhe=row['Ruhe'], Erfolg=row['Erfolg'], Menschen=row['Menschen'], Soziale=row['Soziale'], Selbstverwirklichung=row['Selbstverwirklichung'], Partner=row['Partner'], Religion=row['Religion'], diskutiert=row['diskutiert'], Trust=row['Trust'], vorgenommen=row['vorgenommen'], ublicherweise=row['ublicherweise'], Impuls=row['Impuls'], geschieht=row['geschieht'], Stellen=row['Stellen'], Stellen17=row['Stellen17'], Stellen18=row['Stellen18'], Stellen19=row['Stellen19'], Geschlecht20=row['Geschlecht20'], Year=row['Year'], Studienfeld=row['Studienfeld'], Studiengang=row['Studiengang'], country=row['country'], Stadt=row['Stadt'], subsession=subsession ) # amount = entries csv # Print to check CSV data # print("csvdata",data) subsession.session.vars['social_proximity_anbieter'] = [] subsession.session.vars['social_proximity_kunde'] = [] subsession.session.vars['social_proximity_anbieter_not_chosen_round1'] = [] class Group(BaseGroup): seller_first = models.IntegerField(initial=-1) seller_second = models.IntegerField(initial=-1) seller_third = models.IntegerField(initial=-1) class Player(BasePlayer): min_score_before_chosen = models.FloatField() max_score_before_chosen = models.FloatField() performance_info_group = models.StringField(initial='') social_score = models.FloatField(initial=0) transaction_score = models.FloatField(initial=0) #how much in common with current transactionpartner rating = models.FloatField(initial=0) avg_rating = models.FloatField(initial=0) match = models.IntegerField(initial=-1) top = models.BooleanField(initial=False) number_part1 = models.IntegerField(label="Suchen Sie bitte Ihre persönliche dreistellige Nummer aus der Liste und gehen Sie auf Weiter.") number_part1_textinput = models.IntegerField(label="Tippen Sie Ihre persönliche dreistellige Nummer nun zur weiteren Sicherstellung ein und gehen Sie auf Weiter. Falls Sie eine inkorrekte Nummer ausgewählt haben, gehen Sie bitte auf Zurück.") type = models.IntegerField(initial=0) # customer, lowest , middle, highest seller Anbieter_utilityA = models.FloatField(initial=0) Kunde_utilityk = models.FloatField(initial=0) Utility_c = models.FloatField(initial=0) cost = models.FloatField(initial=0) total = models.FloatField(initial=0) utility_top = models.FloatField(initial=0) estimatedpoints = models.IntegerField(label="Ihre Einschätzung zwischen 0 und 24 Punkten:",initial=0, min=0, max=24) period_over = models.BooleanField(label="Bitte treffen Sie Ihre Auswahl:",widget=widgets.RadioSelect, choices=[ [True, "Ich möchte mit dem mir zugeordneten Anbieter keine Transaktion eingehen."], [False, "Ich möchte mit dem mir zugeordneten Anbieter eine Transaktion eingehen."], ]) #decision if Kunde wants a transaction with matched Anbieter or not #(Tested with live working fine ) chooser_first = models.IntegerField(label="Bitte geben Sie den Anbieter an, mit dem Sie am liebsten eine Transaktion eingehen möchten:", initial=1, choices=[ [1, "Anbieter X"], [2, "Anbieter Y"], [3, "Anbieter Z"] ]) chooser_second = models.IntegerField(label="Bitte geben Sie den Anbieter an, mit dem Sie am zweitliebsten eine Transaktion eingehen möchten:", initial=2, choices=[ [1, "Anbieter X"], [2, "Anbieter Y"], [3, "Anbieter Z"] ]) chooser_third = models.IntegerField(label="Bitte geben Sie den Anbieter an, mit dem Sie am wenigsten eine Transaktion eingehen möchten:", initial=3, choices=[ [1, "Anbieter X"], [2, "Anbieter Y"], [3, "Anbieter Z"] ]) q1 = models.IntegerField(label="Bitte geben Sie jetzt an, ob und welchen Aufgabentyp Sie bearbeiten möchten", widget=widgets.RadioSelect, choices=[ [1, "Ich möchte in dieser Runde keine Aufgabe selbst bearbeiten."], [2, "Ich möchte in dieser Runde eine Aufgabe des Typs A (7er zählen) selbst bearbeiten."], [3, "Ich möchte in dieser Runde zwei Aufgaben des Typs B (1 Analogie und 1 Zahlenreihe) selbst bearbeiten. "] ]) rate_group_member = models.IntegerField() #perceived similarity sim1 = models.IntegerField(label="Wie ähnlich sind Sie und Ihr aktueller Transaktionspartner sich?", widget=widgets.RadioSelectHorizontal, choices=[ [1,"überhaupt nicht ähnlich"], [2, "kaum ähnlich"], [3, "teils/teils"], [4, "eher ähnlich"], [5, "sehr ähnlich"], ]) sim2 = models.IntegerField(label="Was denken Sie, wie sehr würden Sie die Person mögen?", widget=widgets.RadioSelectHorizontal, choices=[ [1, "überhaupt nicht"], [2, "eher nicht"], [3, "neutral"], [4, "eher gern"], [5, "sehr gern"], ]) sim3 = models.IntegerField(label="Wie nah fühlen Sie sich der anderen Person?", widget=widgets.RadioSelectHorizontal, choices=[ [1, "überhaupt nicht nah"], [2, "eher nicht nah"], [3, "neutral"], [4, "eher nah"], [5, "sehr nah"], ]) #-----Task Variables-- # Analogy num_correct = models.IntegerField(initial=0) num_correct1 = models.IntegerField(initial=0) raw_responses = models.LongStringField() raw_responses1 = models.LongStringField() raw_responses2 = models.LongStringField() num_trials = models.IntegerField() num_trials_1 = models.IntegerField() total_user_input = models.IntegerField(initial=0) user_input = models.IntegerField(label="Bitte geben Sie hier Ihre Antwort ein:") user_input1 = models.IntegerField(label="Bitte geben Sie hier Ihre Antwort ein:") total_Apoints = models.IntegerField(initial=0) Apoints = models.IntegerField(initial=0) Apoints2 = models.IntegerField(initial=0) # 7Counting Variables num7 = models.IntegerField() num7_1 = models.IntegerField() num7_2 = models.IntegerField() num7_3 = models.IntegerField() count_7num = models.IntegerField(label="Bitte geben Sie hier Ihre Antwort ein:") count_7num1 = models.IntegerField(label="Bitte geben Sie hier Ihre Antwort ein:") count_7num2 = models.IntegerField(label="Bitte geben Sie hier Ihre Antwort ein:") count_7num3 = models.IntegerField(label="Bitte geben Sie hier Ihre Antwort ein:") sum_7points = models.IntegerField(initial=0) total_7_points = models.IntegerField(initial=0) count_7_points = models.IntegerField(initial=0) count_7_points1 = models.IntegerField(initial=0) count_7_points2 = models.IntegerField(initial=0) count_7_points3 = models.IntegerField(initial=0) number_points = models.IntegerField(initial=0) number_points2 = models.IntegerField(initial=0) sum_7 = models.IntegerField(initial=0) sum_user = models.IntegerField(initial=0) sum_correct = models.IntegerField(initial=0) total_user_sum = models.IntegerField() #------Task Variables Ended----- ## übergabe speicher seller_first = models.IntegerField(initial=-1) seller_second = models.IntegerField(initial=-1) seller_third = models.IntegerField(initial=-1) ### PCDS hier einfügen todo matched_pref = models.IntegerField(initial=-1) matched_index = models.IntegerField(initial=-1) match_letter = models.StringField(initial="") def get_timeout_seconds1(player: Player): participant = player.participant import time return participant.expiry - time.time() def is_displayed1(player: Player): """only returns True if there is time left.""" return get_timeout_seconds1(player) > 0 class Numb(ExtraModel): player = models.Link(Player) round_number = models.IntegerField() question = models.StringField() solution = models.StringField() class Numb1(ExtraModel): player = models.Link(Player) round_number = models.IntegerField() question = models.StringField() solution = models.StringField() class Numb2(ExtraModel): player = models.Link(Player) round_number = models.IntegerField() question = models.StringField() solution = models.StringField() def to_dict_num(tnumb: Numb): # print("nummmm", tnumb) return dict( round_number=tnumb.round_number, questions=tnumb.question, solutions=tnumb.solution, ) def to_dict_num1(tnumb1: Numb1): # print("nummmm1", tnumb1) return dict( round_number=tnumb1.round_number, questions=tnumb1.question, solutions=tnumb1.solution, ) def to_dict_num2(tnumb2: Numb2): # print("nummmm1", tnumb1) return dict( round_number=tnumb2.round_number, questions=tnumb2.question, solutions=tnumb2.solution, ) class Trial(ExtraModel): player = models.Link(Player) round_number = models.IntegerField() question = models.StringField() optionA = models.StringField() optionB = models.StringField() optionC = models.StringField() optionD = models.StringField() optionE = models.StringField() solution = models.StringField() choice = models.StringField() is_correct = models.BooleanField() class Trial1(ExtraModel): player = models.Link(Player) round_number = models.IntegerField() question = models.StringField() optionA = models.StringField() optionB = models.StringField() optionC = models.StringField() optionD = models.StringField() optionE = models.StringField() solution = models.StringField() choice = models.StringField() is_correct = models.BooleanField() class Trial2(ExtraModel): player = models.Link(Player) round_number = models.IntegerField() question = models.StringField() optionA = models.StringField() optionB = models.StringField() optionC = models.StringField() optionD = models.StringField() optionE = models.StringField() solution = models.StringField() choice = models.StringField() is_correct = models.BooleanField() def to_dict(trial: Trial): return dict( question=trial.question, round_number=trial.round_number, optionA=trial.optionA, optionB=trial.optionB, optionC=trial.optionC, optionD=trial.optionD, optionE=trial.optionE, solution=trial.solution, id=trial.id, ) def to_dict1(trial1: Trial1): return dict( question=trial1.question, round_number=trial1.round_number, optionA=trial1.optionA, optionB=trial1.optionB, optionC=trial1.optionC, optionD=trial1.optionD, optionE=trial1.optionE, solution=trial1.solution, id=trial1.id, ) def to_dict2(trial2: Trial2): return dict( question=trial2.question, round_number=trial2.round_number, optionA=trial2.optionA, optionB=trial2.optionB, optionC=trial2.optionC, optionD=trial2.optionD, optionE=trial2.optionE, solution=trial2.solution, id=trial2.id, ) ## variable constraints def number_part1_choices(player: Player): choices = sorted(idread_csv(csv_path=C.CSV_PATH)) return choices class PlayerScores(ExtraModel): player = models.Link(Player) id_part_one = models.IntegerField() Scores = models.FloatField() ## isnt right here, but structure of data says this, better would be score extra and read it roundwise for each player Politik = models.IntegerField() Kultur = models.IntegerField() Technik = models.IntegerField() Sport = models.IntegerField() Familie = models.IntegerField() Wellness = models.IntegerField() Philosophie = models.IntegerField() Tiere = models.IntegerField() Ballsport = models.IntegerField() Wintersport = models.IntegerField() Wassersport = models.IntegerField() Kraftsport = models.IntegerField() Yoga = models.IntegerField() Reiten = models.IntegerField() Klettern = models.IntegerField() Leichtathletik = models.IntegerField() Kampfsport = models.IntegerField() Motorsport = models.IntegerField() Tanzsport = models.IntegerField() NoSport = models.IntegerField() Klassik = models.IntegerField() Deutsche = models.IntegerField() Pop = models.IntegerField() Rap = models.IntegerField() Rock = models.IntegerField() Reggae = models.IntegerField() Jazz = models.IntegerField() Electronic = models.IntegerField() Krimi = models.IntegerField() THorror = models.IntegerField() Liebesfilme = models.IntegerField() Action = models.IntegerField() comedy = models.IntegerField() Fiction = models.IntegerField() Dokus = models.IntegerField() Animation = models.IntegerField() Meer = models.IntegerField() Bergen = models.IntegerField() Stadte = models.IntegerField() Party = models.IntegerField() Hauptsache = models.IntegerField() abschalten = models.IntegerField() Umso = models.IntegerField() Hause = models.IntegerField() karrierebewusst = models.IntegerField() kinderlieb = models.IntegerField() sportlich = models.IntegerField() zuruckhaltend = models.IntegerField() sparsam = models.IntegerField() warmherzig = models.IntegerField() zuverlassig = models.IntegerField() humorvoll = models.IntegerField() aufgelegt = models.IntegerField() gute = models.IntegerField() ernsthaft = models.IntegerField() vertraumt = models.IntegerField() sachlich = models.IntegerField() Losung = models.IntegerField() bringen = models.IntegerField() lebhaft = models.IntegerField() Freundschaft = models.IntegerField() Liebe = models.IntegerField() Ruhe = models.IntegerField() Erfolg = models.IntegerField() Menschen = models.IntegerField() Soziale = models.IntegerField() Selbstverwirklichung = models.IntegerField() Partner = models.IntegerField() Religion = models.IntegerField() diskutiert = models.IntegerField() Trust = models.IntegerField() vorgenommen = models.IntegerField() ublicherweise = models.IntegerField() Impuls = models.IntegerField() geschieht = models.IntegerField() Stellen = models.IntegerField() Stellen17 = models.IntegerField() Stellen18 = models.IntegerField() Stellen19 = models.IntegerField() Geschlecht20 = models.IntegerField() Year = models.IntegerField() Studienfeld = models.StringField() Studiengang = models.StringField() country = models.StringField() Stadt = models.StringField() ### idea: class ComparisonScore(ExtraModel): player = models.Link(Player) id_other_player = models.IntegerField() ## id des anderen spielers score_matching = models.IntegerField() ## after giving all the data, check for #Linking Real Data class ScoresComplete(ExtraModel): player = models.Link(Player) subsession = models.Link(Subsession) IDs = models.IntegerField() Scores = models.FloatField() Politik = models.IntegerField() Kultur = models.IntegerField() Technik = models.IntegerField() Sport = models.IntegerField() Familie = models.IntegerField() Wellness = models.IntegerField() Philosophie = models.IntegerField() Tiere = models.IntegerField() Ballsport = models.IntegerField() Wintersport = models.IntegerField() Wassersport = models.IntegerField() Kraftsport = models.IntegerField() Yoga = models.IntegerField() Reiten = models.IntegerField() Klettern = models.IntegerField() Leichtathletik = models.IntegerField() Kampfsport = models.IntegerField() Motorsport = models.IntegerField() Tanzsport = models.IntegerField() NoSport = models.IntegerField() Klassik = models.IntegerField() Deutsche = models.IntegerField() Pop = models.IntegerField() Rap = models.IntegerField() Rock = models.IntegerField() Reggae = models.IntegerField() Jazz = models.IntegerField() Electronic = models.IntegerField() Krimi = models.IntegerField() THorror = models.IntegerField() Liebesfilme = models.IntegerField() Action = models.IntegerField() comedy = models.IntegerField() Fiction = models.IntegerField() Dokus = models.IntegerField() Animation = models.IntegerField() Meer = models.IntegerField() Bergen = models.IntegerField() Stadte = models.IntegerField() Party = models.IntegerField() Hauptsache = models.IntegerField() abschalten = models.IntegerField() Umso = models.IntegerField() Hause = models.IntegerField() karrierebewusst = models.IntegerField() kinderlieb = models.IntegerField() sportlich = models.IntegerField() zuruckhaltend = models.IntegerField() sparsam = models.IntegerField() warmherzig = models.IntegerField() zuverlassig = models.IntegerField() humorvoll = models.IntegerField() aufgelegt = models.IntegerField() gute = models.IntegerField() ernsthaft = models.IntegerField() vertraumt = models.IntegerField() sachlich = models.IntegerField() Losung = models.IntegerField() bringen = models.IntegerField() lebhaft = models.IntegerField() Freundschaft = models.IntegerField() Liebe = models.IntegerField() Ruhe = models.IntegerField() Erfolg = models.IntegerField() Menschen = models.IntegerField() Soziale = models.IntegerField() Selbstverwirklichung = models.IntegerField() Partner = models.IntegerField() Religion = models.IntegerField() diskutiert = models.IntegerField() Trust = models.IntegerField() vorgenommen = models.IntegerField() ublicherweise = models.IntegerField() Impuls = models.IntegerField() geschieht = models.IntegerField() Stellen = models.IntegerField() Stellen17 = models.IntegerField() Stellen18 = models.IntegerField() Stellen19 = models.IntegerField() Geschlecht20 = models.IntegerField() Year = models.IntegerField() Studienfeld = models.StringField() Studiengang = models.StringField() country = models.StringField() Stadt = models.StringField() ## own methods: def link_player(player: Player): ## or make this part in an extra app, and let it run 15 rounds, if there is no duplicates & the dropdown is the same as a confirmation page where they have to input themselves u let them through row = ScoresComplete.filter(subsession=player.subsession, IDs=player.number_part1)[0] ## PlayerScores.create( player=player, id_part_one=row.IDs, Scores=row.Scores, Politik=row.Politik, Kultur=row.Kultur, Technik=row.Technik, Sport=row.Sport, Familie=row.Familie, Wellness=row.Wellness, Philosophie=row.Philosophie, Tiere=row.Tiere, Ballsport=row.Ballsport, Wintersport=row.Wintersport, Wassersport=row.Wassersport, Kraftsport=row.Kraftsport, Yoga=row.Yoga, Reiten=row.Reiten, Klettern=row.Klettern, Leichtathletik=row.Leichtathletik, Kampfsport=row.Kampfsport, Motorsport=row.Motorsport, Tanzsport=row.Tanzsport, NoSport=row.NoSport, Klassik=row.Klassik, Deutsche=row.Deutsche, Pop=row.Pop, Rap=row.Rap, Rock=row.Rock, Reggae=row.Reggae, Jazz=row.Jazz, Electronic=row.Electronic, Krimi=row.Krimi, THorror=row.THorror, Liebesfilme=row.Liebesfilme, Action=row.Action, comedy=row.comedy, Fiction=row.Fiction, Dokus=row.Dokus, Animation=row.Animation, Meer=row.Meer, Bergen=row.Bergen, Stadte=row.Stadte, Party=row.Party, Hauptsache=row.Hauptsache, abschalten=row.abschalten, Umso=row.Umso, Hause=row.Hause, karrierebewusst=row.karrierebewusst, kinderlieb=row.kinderlieb, sportlich=row.sportlich, zuruckhaltend=row.zuruckhaltend, sparsam=row.sparsam, warmherzig=row.warmherzig, zuverlassig=row.zuverlassig, humorvoll=row.humorvoll, aufgelegt=row.aufgelegt, gute=row.gute, ernsthaft=row.vertraumt, vertraumt=row.vertraumt, sachlich=row.sachlich, Losung=row.Losung, bringen=row.bringen, lebhaft=row.lebhaft, Freundschaft=row.Freundschaft, Liebe=row.Liebe, Ruhe=row.Ruhe, Erfolg=row.Erfolg, Menschen=row.Menschen, Soziale=row.Soziale, Selbstverwirklichung=row.Selbstverwirklichung, Partner=row.Partner, Religion=row.Religion, diskutiert=row.diskutiert, Trust=row.Trust, vorgenommen=row.vorgenommen, ublicherweise=row.ublicherweise, Impuls=row.Impuls, geschieht=row.geschieht, Stellen=row.Stellen, Stellen17=row.Stellen17, Stellen18=row.Stellen18, Stellen19=row.Stellen19, Geschlecht20=row.Geschlecht20, Year=row.Year, Studienfeld=row.Studienfeld, Studiengang=row.Studiengang, country=row.country, Stadt=row.Stadt, ) #Print Statment to check Linking # print("row",row) def change_playerscore_to_id(input_list): output_list = [] for inner_list in input_list: inner_output_list = [] for obj in inner_list: inner_output_list.append(obj.player.id) output_list.append(inner_output_list) return output_list def append_type_list(lst, type, session): id_in_group = [player.id_in_group for player in lst] if type == 0: # anbieter session.vars['social_proximity_anbieter'].append(id_in_group) else: session.vars['social_proximity_kunde'].append(id_in_group) def change_seller_order(session): anbieter = session.vars['social_proximity_anbieter'][0] if len(anbieter) == 18: ## nur in dem 36er sublists = [anbieter[i:i+6] for i in range(0, len(anbieter), 6)] anbieter = [] for sublist in sublists: sublist[1], sublist[4] = sublist[4],sublist[1] anbieter += sublist else : ## wenn wir weniger haben random.shuffle(anbieter) session.vars['social_proximity_anbieter'] = [anbieter] def get_sorted_players(subsession: Subsession): player_list = subsession.get_players() player_scores = [] for player in player_list: scores = PlayerScores.filter(player=player)[0] player_scores.append((scores.player, scores)) ## 2nd entry is the playerscore object sorted_scores = sorted(player_scores, key=lambda ps: ps[1].Scores, reverse=True) return sorted_scores def group_generator(subsession: Subsession): ## +2 dürfte nichts kaputt machen, für 18 : 16,17,18 +2 = 18,19,20 //6 = 3 ## für 36 : 34,35,36 +2 => 36,37,38 //6 = 6 seller_group_size = (subsession.session.num_participants+2)//6 sorted_tuple = get_sorted_players(subsession) sorted_players = [x[0] for x in sorted_tuple] sorted_player_scores = [x[1] for x in sorted_tuple] lower_group = sorted_players[3:3+seller_group_size] middle = len(sorted_players) // 2 half_group_size = seller_group_size // 2 lowest_middle = middle - half_group_size highest_middle = middle + half_group_size if seller_group_size%2 == 1: ## odd onces like 3 (with 18 test) highest_middle +=1 middle_group = sorted_players[lowest_middle:highest_middle] highest_group = sorted_players[-3-seller_group_size:-3] mark_seller_types(lower_group, 1) mark_seller_types(middle_group, 2) mark_seller_types(highest_group, 3) anbieter_players = [p for p in sorted_players if p.type != 0] kunde_players = [p for p in sorted_players if p not in anbieter_players] append_type_list(anbieter_players, 0, subsession.session) append_type_list(kunde_players, 1, subsession.session) # build anbieter sublist anbieter_sublists = [lower_group[:3], lower_group[3:], middle_group[:3],middle_group[3:], highest_group[:3],highest_group[3:]] kunde_sublists = create_customer_sublists(kunde_players) return anbieter_sublists, kunde_sublists def build_score(link_player, other_player): score_matching = 0 ## calculate Matching Score here ComparisonScore.create( player = link_player, id_other_player= other_player.id_in_group, ## initial die id in subsession score_matching = score_matching ) ## in similarity later, order player1 & 2 by id in subsession, use smaller as linkPlayer & bigger as idother ## take score_matching for everyround while calculate it just once def check_for_matrix_errors(numbers): flat_numbers = [num for sublist in numbers for num in sublist] # Check for duplicates error = "" if len(flat_numbers) != len(set(flat_numbers)): error = ("check_for_matrix_errors - Error: Duplicate numbers found!") else: # Check for missing numbers expected_numbers = list(range(1,len(flat_numbers)+1)) missing_numbers = list(set(expected_numbers) - set(flat_numbers)) if missing_numbers: error = ("check_for_matrix_errors - Error: Missing numbers found!", missing_numbers) else: error = ("check_for_matrix_errors : No errors found.") ## Show only in Debug mode if settings.DEBUG: print(error) def group_swap(roundNumber, subsession, anbieter_=None, kunde_=None): matrix_initial = subsession.get_group_matrix() anbieter = subsession.session.vars['social_proximity_anbieter'] kunde = subsession.session.vars['social_proximity_kunde'] matrix = generate_matching(anbieter=anbieter, kunde=kunde, roundNumber=roundNumber , subsession=subsession) check_for_matrix_errors(matrix) if settings.DEBUG: print('RUNDE', roundNumber, matrix) subsession.set_group_matrix(matrix) def generate_one_to_one_matching(subsession): for group in subsession.get_groups(): player = group.get_players() X = group.seller_first Y = group.seller_second Z = group.seller_third seller_list = [X,Y,Z] ## Reihenfolge der Groupids der Verkäufer seller_list_letter = ["X","Y","Z"] ### std Reihenfolge für Buchstaben ## Index von X,Y,Z => seller_list_letter customers = player[3:] random.shuffle(customers) if settings.DEBUG: print(f'seller list: {seller_list}' ) counts = { 'X': 0, 'Y': 0, 'Z': 0, } for p in customers: list_ = [p.chooser_first, p.chooser_second, p.chooser_third] counts['X'] += 7 if list_[0] == 1 else 3 if list_[1] == 1 else 1 if list_[2] == 1 else 0 counts['Y'] += 7 if list_[0] == 2 else 3 if list_[1] == 2 else 1 if list_[2] == 2 else 0 counts['Z'] += 7 if list_[0] == 3 else 3 if list_[1] == 3 else 1 if list_[2] == 3 else 0 spieler_id = (p.id_in_group, p.number_part1) for i,choose in enumerate(list_): if settings.DEBUG: print(f'{spieler_id} - {list_} ') #op = group.get_player_by_id(choose) op = group.get_player_by_id(seller_list[choose-1]) if op.match == -1: #not chosen yet op.match = p.id_in_group p.match = choose p.matched_pref = i p.match_letter = seller_list_letter[choose-1] p.matched_index = seller_list.index(choose) if settings.DEBUG: print(f'match - {p.matched_index} - bekommen: {choose} - pref/loopcounter - {p.matched_pref} - Letter: {p.match_letter}' ) break most_chosen = max(counts, key=counts.get) player_top = None if most_chosen == 'X': player_top =group.get_player_by_id(X) elif most_chosen == 'Y': player_top =group.get_player_by_id(Y) elif most_chosen == 'Z': player_top =group.get_player_by_id(Z) player_top.top = True # #Getting Top Choosen # for i, mc in enumerate(list_): # print("listfortop",mc) # counts[i]+= rating_place[mc - 1] # # most_chosen = seller_order[counts.index(max(counts))] # print("mostchosen",most_chosen) # group.get_player_by_id(most_chosen).top = True # def generate_one_to_one_grp_matrix(subsession): matrix_before = subsession.get_group_matrix() anbieter = subsession.session.vars['social_proximity_anbieter'][0] output = [] not_chosen = [] for a in anbieter:# player = subsession.get_players()[a-1] x = player.id_in_subsession match = [x] if player.match != -1: opposite = player.group.get_player_by_id(player.match).id_in_subsession match = [x,opposite] player.period_over = False ## erstmal setzen player.group.get_player_by_id(player.match).period_over = False else: not_chosen.append(x) ## add periodover player.period_over = True output.append(match) if settings.DEBUG: print('matching before', matrix_before, '\nmatching after', output) if subsession.round_number==1: subsession.session.vars['social_proximity_anbieter_not_chosen_round1'] = not_chosen if settings.DEBUG: print("not chosen:", subsession.session.vars['social_proximity_anbieter_not_chosen_round1']) ## save group_seller in player_seller and rewrite it after groupmatrix set for group in subsession.get_groups(): real_numbers = find_real_seller_numbers(group) for player in group.get_players(): player.seller_first, player.seller_second, player.seller_third = group.seller_first, group.seller_second, group.seller_third #player.seller_first, player.seller_second, player.seller_third = real_numbers pscore1= PlayerScores.filter(player=group.get_player_by_id(group.seller_first).in_round(1))[0].Scores pscore2=PlayerScores.filter(player=group.get_player_by_id(group.seller_second).in_round(1))[0].Scores pscore3=PlayerScores.filter(player=group.get_player_by_id(group.seller_third).in_round(1))[0].Scores player.min_score_before_chosen = min(pscore1,pscore2,pscore3) player.max_score_before_chosen = max(pscore1, pscore2, pscore3) subsession.set_group_matrix(output) for group in subsession.get_groups(): player = group.get_players()[0] group.seller_first, group.seller_second, group.seller_third = player.seller_first, player.seller_second, player.seller_third def find_real_seller_numbers(group:Group): p1,p2,p3 = group.seller_first, group.seller_second, group.seller_third return group.get_player_by_id(p1).number_part1 , \ group.get_player_by_id(p2).number_part1, \ group.get_player_by_id(p3).number_part1 def find_player_by_number(subsession: Subsession, number): for p in subsession.get_players(): if p.number_part1 == number: return p return None def generate_matching(anbieter, kunde, roundNumber , subsession): anbieter = anbieter[0] split = len(anbieter) // 3 ## round 2 extra not chosen anbieter with priority if roundNumber == 2: # not chosen wird nicht gefüllt not_chosen = subsession.session.vars['social_proximity_anbieter_not_chosen_round1'] ##maybe directly anbieter_reverse = [x for x in anbieter if x not in not_chosen][::-1] anbieter = not_chosen + anbieter_reverse anbieter_ = [create_providers_sublists(anbieter[:split], roundNumber), create_providers_sublists(anbieter[split:2 * split], roundNumber), create_providers_sublists(anbieter[2 * split:], roundNumber)] ## todo: shuffe anbieter_ ab runde 3 anbieter_sublists = [item for sublist in anbieter_ for item in sublist] kunden_sublists = create_customer_sublists(kunde[0]) return [a + k for a, k in zip(anbieter_sublists, kunden_sublists)] def mark_seller_types(playerList, type=0): ##0 kunde, 1 low, 2 mid , 3 high for player in playerList: player.type = type ## B def create_providers_sublists(lst, roundNumber): arr = lst.copy() if len(arr) == 3: return [arr] return [arr[:3],arr[3:]] def create_customer_sublists(arr): random.shuffle(arr) n = len(arr) n_extra = n % 3 sublists = [arr[i:i + 3] for i in range(0, n - n_extra, 3)] if n_extra != 0: # nicht restlos teilbar durch 3 sublists.append(arr[n - (n_extra):]) if n_extra == 1: # 7 oder 16 sublists[-1].append(sublists[-2][-1]) del sublists[-2][-1] return sublists assigned_ids = set() def fill_empty_numbers(player: Player, number_p1): if player.number_part1 == 0: global assigned_ids if isinstance(number_p1, list) and len(number_p1) > 0: for id in number_p1: if id not in assigned_ids: player.number_part1 = id assigned_ids.add(id) break # PAGES class WelcomePage(Page): def is_displayed(player: Player): return player.round_number==1 class NumberEntry(Page): form_model = 'player' form_fields = ['number_part1', 'number_part1_textinput'] @staticmethod def is_displayed(player: Player): rn = player.round_number if rn > 1: player.number_part1 = player.in_previous_rounds()[0].number_part1 return rn == 1 @staticmethod def before_next_page(player: Player, timeout_happened): if settings.DEBUG: fill_empty_numbers(player, idread_csv(csv_path=C.CSV_PATH)) @staticmethod def error_message(player, values): ## error message if values['number_part1_textinput'] != values['number_part1']: return "Die eingegebenen Nummern stimmen nicht überein. Wiederholen Sie bitte die Nummerneingabe." class LinkPlayer(Page): @staticmethod def vars_for_template(player: Player): ## here link the player to the data before link_player(player) @staticmethod def is_displayed(player: Player): return player.round_number == 1 ''' class CalculateScoreMatrixPlayerXPlayer(WaitPage): wait_for_all_groups = True @staticmethod def after_all_players_arrive(subsession: Subsession): for id_player_one, link_player in enumerate(subsession.get_players()): for other_player in subsession.get_players()[id_player_one:]: pass ## uncomment as soon as build_score is finished todo haris #build_score(link_player,other_player ) ''' class Instruction(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 timeout_seconds = 900 timer_text = "Verbleibende Zeit:" def vars_for_template(player: Player): return dict( baseline=player.subsession.TREATMENT=='Base', ) class RoleAssignment(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 class GroupMatchingWaitPage(WaitPage): wait_for_all_groups = True @staticmethod def after_all_players_arrive(subsession: Subsession): if subsession.round_number == 1: ## Erste Runde group_generator(subsession) elif subsession.round_number == C.SWAP_SELLER_ROUND: change_seller_order(subsession.session) group_swap(roundNumber=subsession.round_number, subsession=subsession) #if subsession.round_number >= 3: ## das muss raus denk ich ### For Group order for group in subsession.get_groups(): ## wenn knallt dann filtenr player = [] for p in group.get_players(): player.append(p.id_in_group)#player.append(p.id_in_subsession) player = player[:3] random.shuffle(player) group.seller_first = player[0] group.seller_second = player[1] #group.get_player_by_id(player[1]).id_in_group group.seller_third = player[2] #group.get_player_by_id(player[2]).id_in_group if settings.DEBUG: print("Seller reinfolge setzen:", player) class RoleAssignmentKunde(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 and player.type == 0 class RoleAssignmentAnbieter(Page): @staticmethod def is_displayed(player: Player): return player.round_number == 1 and player.type != 0 class StartNextRound(Page): @staticmethod def is_displayed(player: Player): return player.round_number >=2 timeout_seconds = 15 timer_text = "Verbleibende Zeit:" def vars_for_template(player: Player): type = player.participant.vars.get('type') #print("type",type) #print("idnum",player.number_part1) if type is not None: player.type = type else: # set default value if player_type is not found in session player.type = 0 class WaitForallPlayers(WaitPage): ## not correct if u only wanna wait for group member wait_for_all_groups = True # if C.NUM_ROUNDS >=2: # def vars_for_template(player: Player): # player.type = player.participant.vars.get('type') # print("type",player.type) def title_text(self): return "Bitte warten" def body_text(self): return "Bitte warten Sie, bis das Experiment weitergeht" class AnbieterInfo(Page): @staticmethod def vars_for_template(player: Player): return dict( round_number=player.round_number, first_part=player.round_number < 3, ppayoff=player.participant.payoff, player_id=player.number_part1 ) @staticmethod def is_displayed(player: Player): return player.type != 0 def before_next_page(player: Player, timeout_happened): player.participant.vars['type'] = player.type class KundeInfo(Page): #form_model = 'player' #form_fields = [ # 'chooser_option', # 'q1','estimatedpoints'] @staticmethod def vars_for_template(player: Player): return dict( round_number=player.round_number, first_part = player.round_number <3, ppayoff = player.participant.payoff, player_id=player.number_part1 ) def is_displayed(player: Player): # why round number return player.round_number and player.type == 0 return player.type == 0 def before_next_page(player: Player, timeout_happened): player.participant.vars['type'] = player.type class MatchingInfoKunde(Page): form_model = 'player' form_fields = ['chooser_first', 'chooser_second', 'chooser_third'] @staticmethod def vars_for_template(player: Player): grp = player.group first = grp.get_player_by_id(grp.seller_first) second = grp.get_player_by_id(grp.seller_second) third = grp.get_player_by_id(grp.seller_third) # Accessing player IDs first_seller_id = first.number_part1 second_seller_id = second.number_part1 third_seller_id = third.number_part1 previous_round = player.round_number - 1 first_rating, second_rating, third_rating = 0,0,0 if player.round_number >= 2: first_rating = first.in_round(previous_round).avg_rating second_rating = second.in_round(previous_round).avg_rating third_rating = third.in_round(previous_round).avg_rating #getting minimum and maximun score of the 3 players first_score = PlayerScores.filter(player=first.in_round(1))[0].Scores second_score = PlayerScores.filter(player=second.in_round(1))[0].Scores third_score = PlayerScores.filter(player=third.in_round(1))[0].Scores min_score = min(first_score, second_score, third_score) max_score = max(first_score, second_score, third_score) return dict( first_part = player.round_number < 3, x = first_rating, y = second_rating, z = third_rating, min=min_score, max=max_score, p1 = first_seller_id, p2 = second_seller_id, p3 = third_seller_id, Normal = player.subsession.MODE == 'Normal' ) @staticmethod def is_displayed(player: Player): return player.type == 0 and player.round_number >= 3 # # @staticmethod # def before_next_page(player: Player, timeout_happened): # if settings.DEBUG: # player.chooser_first, player.chooser_second, player.chooser_third = 1,2,3 # # # @staticmethod # def error_message(player, values): # if settings.DEBUG: # print(values) # len(set([chosenfirst,chosensecond,chcosenthird])) < 3: errormessage # comment all above and Uncomment this for the live (I have tested it and its working perfectly) @staticmethod def before_next_page(player: Player, timeout_happened): input_customer = [player.chooser_first, player.chooser_second, player.chooser_third] #print("selected pref", input_customer) if set(input_customer) != {1, 2, 3}: return "Ihre Präferenzangaben sind fehlerhaft. Bitte weisen Sie jedem Anbieter genau einen Präferenzrang zu. " class OneToOneMatching(WaitPage): wait_for_all_groups = True def after_all_players_arrive(subsession: Subsession): if settings.DEBUG: print("\n ONE TO ONE MATCHING START \n") generate_one_to_one_grp_matrix(subsession) def title_text(self): return "Bitte warten" def body_text(self): return "Bitte warten Sie, bis das Experiment weitergeht." class AfterMatchingInfoKunde(Page): form_model = 'player' form_fields = ['period_over'] @staticmethod def is_displayed(player: Player): return player.type == 0 @staticmethod def vars_for_template(player: Player): '' match = player.match #1 #print("match",match) first_part = player.round_number < 3 player.performance_info_group = 'Zur Erinnerung: Aus der Anbietergruppe ist bekannt, dass die von einem Anbieter in Termin 1 erzielte niedrigste durchschnittliche Punktzahl ' + str(player.min_score_before_chosen) + ' Punkte betrug. Die durch einen anderen Anbieter in der Gruppe erzielte höchste durchschnittliche Punktzahl betrug ' + str(player.max_score_before_chosen) + ' Punkte.' #print("period_over1",player.period_over) # print(f'match - {p.matched_index} - bekommen: {choose} - # pref/loopcounter - {p.matched_pref} - Letter: {p.match_letter}' ) return dict( first_part=first_part, anbieter_match = player.match_letter, preference = player.matched_pref+1, min=player.min_score_before_chosen, max=player.max_score_before_chosen, ) @staticmethod def before_next_page(player: Player, timeout_happened): # if settings.DEBUG: # player.period_over=False ## ## Transaction setzen für alle player player.get_others_in_group()[0].period_over = player.period_over ## anbieter #print("period_over",player.period_over) class MatchingInfoAnbieter(Page): @staticmethod def vars_for_template(player: Player): return dict( first_part = player.round_number < 3 ) @staticmethod def is_displayed(player: Player): return player.type == 1 class MatchingKundeWaitPage(WaitPage): wait_for_all_groups = True @staticmethod def after_all_players_arrive(subsession: Subsession): generate_one_to_one_matching(subsession) def title_text(self): return "Bitte warten" def body_text(self): return "Bitte warten Sie, bis das Experiment weitergeht." class TransactionInfoKunde(Page): form_model = 'player' form_fields = ['q1'] @staticmethod def is_displayed(player: Player): return player.type == 0 def vars_for_template(player: Player): return dict( periodover=player.period_over==True, similarity = player.subsession.TREATMENT =='Similar', firstpart=player.round_number<3 ) class TransactionInfoAnbieter(Page): @staticmethod def is_displayed(player: Player): return player.type != 0 def vars_for_template(player: Player): return dict( periodover=player.period_over == True, similarity=player.subsession.TREATMENT == 'Similar', firstpart = player.round_number < 3 ) class Similarity(Page): @staticmethod def is_displayed(player: Player): return player.round_number >= 3 and player.subsession.TREATMENT =='Similar' and not player.period_over def vars_for_template(player: Player): # Get current player's data # better use : player_data = PlayerScores.filter(player=player.in_round(1))[0] player_data_list = PlayerScores.filter(player=player.in_round(1)) if not player_data_list: print("Player data not found") player_data = player_data_list[0] all_players = [] attributes_to_skip = ['metadata', 'player', 'player_id', 'id'] scores = 0 total_score = 0 player_count = 0 score_with_partner = 0 # how much in common with current transaction partner # Iterate over all groups for group in player.subsession.get_groups(): group_players = group.get_players() all_players.extend(group_players) for other_player in all_players: if other_player.number_part1 == player.number_part1: continue # Skip the current player all_other_player = PlayerScores.filter(player=other_player.in_round(1)) if not all_other_player: if settings.DEBUG: print("Opponent data not found") continue opponent_data = all_other_player[0] for attribute_name in dir(player_data): if attribute_name.startswith('_'): continue if attribute_name in attributes_to_skip: continue player_attribute = getattr(player_data, attribute_name) opponent_attribute = getattr(opponent_data, attribute_name) if callable(player_attribute) or callable(opponent_attribute): continue if player_attribute == 0 and opponent_attribute == 0: continue if player_attribute == opponent_attribute: scores += 1 player.social_score = round(scores / len(all_players),2) #print("points",player.social_score) player.social_score = float( decimal.Decimal(str(player.social_score)).quantize(0, rounding=decimal.ROUND_HALF_UP)) #print("scores:", scores) #print("total:", total_score) #print("average:", player.social_score) # Get opponent's data # only feasible for the next player in the group, u have no matching yet? opponent_data_list = PlayerScores.filter(player=player.get_others_in_group()[0].in_round(1))[:1] if not opponent_data_list: if settings.DEBUG: print("Opponent data not found") opponent_data = opponent_data_list[0] # Find matching values in both players' PlayerScores attributes_to_skip = ['metadata', 'player','player_id','id'] #mv = dict(hobby=dict(), music=dict(), ) matching_values = {'hobby': {}, 'music': {}, 'sports': {}, 'Film': {}, 'Urlaub': {}, 'Eigenschaften': {}, 'Denken': {}, 'Wichtigsten': {}, 'Religion': {}, 'diskutiert': {}, 'Trust': {}, 'vorgenommen': {}, 'ublicherweise': {}, 'Impuls': {}, 'geschieht': {}, 'Stellen': {}, 'Stellen17': {}, 'Stellen18': {}, 'Stellen19': {}, 'Geschlecht20': {}, 'Year': {}, 'Studienfeld': {}, 'Studiengang': {}, 'country': {}, 'Stadt': {}, } for attribute_name in dir(player_data): if attribute_name.startswith('_'): continue if attribute_name in attributes_to_skip: continue player_attribute = getattr(player_data, attribute_name) opponent_attribute = getattr(opponent_data, attribute_name) if callable(player_attribute) or callable(opponent_attribute): continue # print("list",attribute_name) if player_attribute ==0 and opponent_attribute ==0: continue if attribute_name in ['Politik', 'Kultur', 'Technik', 'Sport','Familie','Wellness','Philosophie','Tiere']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['hobby'][attribute_name] = player_attribute score_with_partner = score_with_partner+1 elif attribute_name in ['Ballsport', 'Wintersport', 'Wassersport', 'Kraftsport','Yoga','Reiten','Klettern','Leichtathletik','Kampfsport','Motorsport','Tanzsport','NoSport']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['sports'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Klassik', 'Deutsche', 'Pop', 'Rap', 'Rock','Reggae','Jazz','Electronic']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['music'][attribute_name] = player_attribute score_with_partner=score_with_partner+1 elif attribute_name in ['Krimi', 'THorror', 'Liebesfilme', 'Action', 'comedy','Fiction','Dokus','Animation']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Film'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Meer', 'Bergen', 'Stadte', 'Party', 'Hauptsache','abschalten','Umso','Hause']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Urlaub'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['karrierebewusst', 'kinderlieb', 'sportlich', 'zuruckhaltend', 'sparsam','warmherzig','zuverlassig','humorvoll']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Eigenschaften'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['aufgelegt', 'gute', 'ernsthaft', 'vertraumt', 'sachlich','Losung','bringen','lebhaft']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Denken'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Freundschaft', 'Liebe', 'Ruhe', 'Erfolg', 'Menschen','Soziale','Selbstverwirklichung','Partner']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Wichtigsten'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Religion']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Religion'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['diskutiert']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['diskutiert'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Trust']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Trust'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['vorgenommen']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['vorgenommen'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['ublicherweise']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['ublicherweise'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Impuls']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Impuls'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['geschieht']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['geschieht'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Stellen']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Stellen'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Stellen17']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Stellen17'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Stellen18']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Stellen18'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Stellen19']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Stellen19'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Geschlecht20']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Geschlecht20'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Year']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Year'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Studienfeld']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Studienfeld'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Studiengang']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Studiengang'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['country']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['country'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 elif attribute_name in ['Stadt']: if player_attribute != 0 and player_attribute == opponent_attribute: matching_values['Stadt'][attribute_name] = player_attribute score_with_partner = score_with_partner + 1 player.transaction_score = score_with_partner return dict( Matched = matching_values, Social_score = int(player.social_score), above_average = player.transaction_score>=player.social_score, player_id = player.number_part1, opponent_data = opponent_data_list[0].id_part_one ) class Estimate_PerceivedSimilarity(Page): form_model = 'player' form_fields = ['sim1', 'sim2', 'sim3', 'estimatedpoints'] def vars_for_template(player: Player): return dict( playerKunde = player.type == 0, similarity = player.subsession.TREATMENT == 'Similar', firstpart = player.round_number<3 ) @staticmethod def is_displayed(player: Player): #if transaction takes place: Kunde enters from round 3 irrespective of treatment; Anbieter enter from round 3 and only in similarity treatment return (player.type==0 and not player.period_over) or (player.type > 0 and player.round_number >= 3 and player.subsession.TREATMENT == 'Similar' and not player.period_over) class CountdownTask(Page): @staticmethod def is_displayed(player: Player): return player.round_number <= C.NUM_ROUNDS and not player.period_over timeout_seconds = 10 timer_text = C.TIMER_TEXT def before_next_page(player: Player, timeout_happened): participant = player.participant import time participant.expiry = time.time() + 160 class RRandomNum(Page): form_model = 'player' form_fields = ['count_7num'] # timeout_seconds = 60 get_timeout_seconds = get_timeout_seconds1 timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): return player.round_number and player.type != 0 and not player.period_over def vars_for_template(player: Player): i = 1 solution = 0 counts_7 = [0] * 15 LINE_LENGTH = 15 numbers = [0] * 15 # // Fill all 16 lines with numbers while (i <= 15): # // Initialize variables j = 1 # val_t = 0 counts_7[i - 1] = 0 innerlist = [0] * 15 # // Fill a line up to LINE_LENGTH while (j <= LINE_LENGTH): val_t = 0 val = random.randint(0, 9) # // val_t = val_t * MULTI; val_t = val_t + val # // Repeat under certain condition, prevent leading 0 if (val_t == 0 and j == 1): j = 0 # // Add solution if value is a 7 if (val == 7): counts_7[i - 1] = counts_7[i - 1] + 1 innerlist[j - 1] = str(val_t) j = j + 1 numbers[i - 1] = ''.join(innerlist) solution = solution + counts_7[i - 1] i = i + 1 # if Player.count_7 == solution: # return { # Player.count_7_points == 2, # print("Points",Player.count_7_points) # } player.num7 = solution return dict( Numbers = numbers, solution = player.num7, Normal = player.subsession.MODE == 'Normal' ) @staticmethod def before_next_page(player: Player, timeout_happened): if player.count_7num == player.num7: player.count_7_points = 4; if player.count_7num == player.num7 +1: player.count_7_points = 3; if player.count_7num == player.num7 -1: player.count_7_points = 3; if player.count_7num == player.num7 +2: player.count_7_points = 2; if player.count_7num == player.num7 -2: player.count_7_points = 2; if player.count_7num == player.num7 +3: player.count_7_points = 1; if player.count_7num == player.num7 - 3: player.count_7_points = 1; # else: # return player.count_7_points == 1 class Analogy(Page): form_model = 'player' form_fields = ['raw_responses'] # timeout_seconds = 60 get_timeout_seconds = get_timeout_seconds1 timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): return player.round_number and player.type != 0 and not player.period_over @staticmethod def js_vars(player: Player): stimuli = [to_dict(trial) for trial in Trial.filter(player=player)] return dict(trials=stimuli ) @staticmethod def vars_for_template(player: Player): return { 'Normal': player.subsession.MODE == 'Normal'} @staticmethod def before_next_page(player: Player, timeout_happened): import json try: responses = json.loads(player.raw_responses) except JSONDecodeError: responses = {} # Set an empty dictionary as the default value if not responses: # Check if responses is empty for trial in Trial.filter(player=player): trial.choice = 0 # Set choice to 0 (or any other value representing no selection) trial.is_correct = False # Set is_correct to False else: for trial in Trial.filter(player=player): trial.choice = responses.get(str(trial.id), 0) # Use get() to retrieve the value, defaulting to 0 if not found trial.is_correct = trial.choice == trial.solution player.num_correct = sum(trial.is_correct for trial in Trial.filter(player=player)) player.Apoints = player.num_correct * 2 player.raw_responses = '' class srandom(Page): form_model = 'player' form_fields = ['count_7num1'] # timeout_seconds = 60 get_timeout_seconds = get_timeout_seconds1 timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): return player.round_number and player.type != 0 and not player.period_over def vars_for_template(player: Player): i = 1 solution = 0 counts_7 = [0] * 15 LINE_LENGTH = 15 numbers = [0] * 15 # // Fill all 16 lines with numbers while (i <= 15): # // Initialize variables j = 1 # val_t = 0 counts_7[i - 1] = 0 innerlist = [0] * 15 # // Fill a line up to LINE_LENGTH while (j <= LINE_LENGTH): val_t = 0 val = random.randint(0, 9) # // val_t = val_t * MULTI; val_t = val_t + val # // Repeat under certain condition, prevent leading 0 if (val_t == 0 and j == 1): j = 0 # // Add solution if value is a 7 if (val == 7): counts_7[i - 1] = counts_7[i - 1] + 1 innerlist[j - 1] = str(val_t) j = j + 1 numbers[i - 1] = ''.join(innerlist) solution = solution + counts_7[i - 1] i = i + 1 player.num7_1 = solution return dict( Numbers = numbers, solution = player.num7_1, Normal=player.subsession.MODE == 'Normal' ) @staticmethod def before_next_page(player: Player, timeout_happened): if player.count_7num1 == player.num7_1: player.count_7_points1 = 4; if player.count_7num1 == player.num7_1 + 1: player.count_7_points1 = 3; if player.count_7num1 == player.num7_1 - 1: player.count_7_points1 = 3; if player.count_7num1 == player.num7_1 + 2: player.count_7_points1 = 2; if player.count_7num1 == player.num7_1 - 2: player.count_7_points1 = 2; if player.count_7num1 == player.num7_1 + 3: player.count_7_points1 = 1; if player.count_7num1 == player.num7_1 - 3: player.count_7_points1 = 1; class NumberSeq(Page): form_model = 'player' form_fields = ['user_input'] # timeout_seconds = 60 get_timeout_seconds = get_timeout_seconds1 timer_text = C.TIMER_TEXT def is_displayed(player: Player): return player.round_number and player.type != 0 and not player.period_over @staticmethod def js_vars(player: Player): astimuli = [to_dict_num(tnumb) for tnumb in Numb.filter(player=player.in_round(1), round_number = player.round_number)] return dict(tnumb=astimuli ) @staticmethod def vars_for_template(player: Player): return { 'Normal': player.subsession.MODE == 'Normal' } @staticmethod def before_next_page(player: Player, timeout_happened): for tnumb in Numb.filter(player=player.in_round(1), round_number = player.round_number): if player.user_input == int(tnumb.solution): player.number_points = 2 class srandom1(Page): form_model = 'player' form_fields = ['count_7num2'] # timeout_seconds = 60 get_timeout_seconds = get_timeout_seconds1 timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): #display only for Anbieter if transaction takes place return player.type != 0 and not player.period_over def vars_for_template(player: Player): i = 1 solution = 0 counts_7 = [0] * 15 LINE_LENGTH = 15 numbers = [0] * 15 # // Fill all 16 lines with numbers while (i <= 15): # // Initialize variables j = 1 # val_t = 0 counts_7[i - 1] = 0 innerlist = [0] * 15 # // Fill a line up to LINE_LENGTH while (j <= LINE_LENGTH): val_t = 0 val = random.randint(0, 9) # // val_t = val_t * MULTI; val_t = val_t + val # // Repeat under certain condition, prevent leading 0 if (val_t == 0 and j == 1): j = 0 # // Add solution if value is a 7 if (val == 7): counts_7[i - 1] = counts_7[i - 1] + 1 innerlist[j - 1] = str(val_t) j = j + 1 numbers[i - 1] = ''.join(innerlist) solution = solution + counts_7[i - 1] i = i + 1 player.num7_2 = solution return dict( Numbers = numbers, solution = player.num7_2, Normal=player.subsession.MODE == 'Normal' ) @staticmethod def before_next_page(player: Player, timeout_happened): if player.count_7num2 == player.num7_2: player.count_7_points2 = 4; if player.count_7num2 == player.num7_2 + 1: player.count_7_points2 = 3; if player.count_7num2 == player.num7_2 - 1: player.count_7_points2 = 3; if player.count_7num2 == player.num7_2 + 2: player.count_7_points2 = 2; if player.count_7num2 == player.num7_2 - 2: player.count_7_points2 = 2; if player.count_7num2 == player.num7_2 + 3: player.count_7_points2 = 1; if player.count_7num2 == player.num7_2 - 3: player.count_7_points2 = 1; class Analogy1(Page): form_model = 'player' form_fields = ['raw_responses1'] # timeout_seconds = 60 get_timeout_seconds = get_timeout_seconds1 timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): ## Display for Anbieter only if transaction takes place return player.type != 0 and not player.period_over @staticmethod def js_vars(player: Player): stimuli1 = [to_dict1(trial1) for trial1 in Trial1.filter(player=player)] return dict(trials1=stimuli1 ) @staticmethod def vars_for_template(player: Player): return { 'Normal': player.subsession.MODE == 'Normal'} def before_next_page(player: Player, timeout_happened): import json try: responses = json.loads(player.raw_responses1) except json.JSONDecodeError: responses = {} # Set an empty dictionary as the default value if not responses: # Check if responses is empty for trial1 in Trial1.filter(player=player): trial1.choice = 0 # Set choice to 0 (or any other value representing no selection) trial1.is_correct = False # Set is_correct to False else: for trial1 in Trial1.filter(player=player): trial1.choice = responses.get(str(trial1.id), 0) # Use get() to retrieve the value, defaulting to 0 if not found trial1.is_correct = trial1.choice == trial1.solution player.num_correct1 = sum(trial1.is_correct for trial1 in Trial1.filter(player=player)) player.Apoints2 = player.num_correct1 * 2 player.raw_responses1 = '' class srandom2(Page): form_model = 'player' form_fields = ['count_7num3'] get_timeout_seconds = get_timeout_seconds1 timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): ## ## Display for Anbieter only if transaction takes place return player.type != 0 and not player.period_over def vars_for_template(player: Player): i = 1 solution = 0 counts_7 = [0] * 15 LINE_LENGTH = 15 numbers = [0] * 15 # // Fill all 16 lines with numbers while (i <= 15): # // Initialize variables j = 1 # val_t = 0 counts_7[i - 1] = 0 innerlist = [0] * 15 # // Fill a line up to LINE_LENGTH while (j <= LINE_LENGTH): val_t = 0 val = random.randint(0, 9) # // val_t = val_t * MULTI; val_t = val_t + val # // Repeat under certain condition, prevent leading 0 if (val_t == 0 and j == 1): j = 0 # // Add solution if value is a 7 if (val == 7): counts_7[i - 1] = counts_7[i - 1] + 1 innerlist[j - 1] = str(val_t) j = j + 1 numbers[i - 1] = ''.join(innerlist) solution = solution + counts_7[i - 1] i = i + 1 player.num7_3 = solution return dict( Numbers = numbers, solution = player.num7_3, Normal=player.subsession.MODE == 'Normal' ) @staticmethod # conditoin for the upper value def before_next_page(player: Player, timeout_happened): if player.count_7num3 == player.num7_3: player.count_7_points3 = 4; if player.count_7num3 == player.num7_3 + 1: player.count_7_points3 = 3; if player.count_7num3 == player.num7_3 - 1: player.count_7_points3 = 3; if player.count_7num3 == player.num7_3 + 2: player.count_7_points3 = 2; if player.count_7num3 == player.num7_3 - 2: player.count_7_points3 = 2; if player.count_7num3 == player.num7_3 + 3: player.count_7_points3 = 1; if player.count_7num3 == player.num7_3 - 3: player.count_7_points3 = 1; class NumberSeq1(Page): form_model = 'player' form_fields = ['user_input1'] # timeout_seconds = 60 get_timeout_seconds = get_timeout_seconds1 timer_text = C.TIMER_TEXT @staticmethod def is_displayed(player: Player): ##Display for Anbieter only if transaction takes place return player.type != 0 and not player.period_over @staticmethod def js_vars(player: Player): astimuli1 = [to_dict_num1(tnumb1) for tnumb1 in Numb1.filter(player=player.in_round(1), round_number = player.round_number)] # print("aaa1",dict(tnumb1=astimuli1)) return dict(tnumb1=astimuli1, ) @staticmethod def vars_for_template(player: Player): return { 'Normal': player.subsession.MODE == 'Normal' } @staticmethod def before_next_page(player: Player, timeout_happened): for tnumb1 in Numb1.filter(player=player.in_round(1), round_number = player.round_number): if player.user_input1 == int(tnumb1.solution): player.number_points2 = 2 #task if user select option 2 or 3 class SelectRandom(Page): form_model = 'player' form_fields = ['count_7num'] # timeout_seconds = 60 def get_timeout_seconds(self): return 25 # Set the timeout value for SelectRandom page def is_displayed(player: Player): return player.type == 0 and player.q1 == 2 and not player.period_over # def vars_for_template(player: Player): i = 1 solution = 0 counts_7 = [0] * 15 LINE_LENGTH = 15 numbers = [0] * 15 # // Fill all 16 lines with numbers while (i <= 15): # // Initialize variables j = 1 # val_t = 0 counts_7[i - 1] = 0 innerlist = [0] * 15 # // Fill a line up to LINE_LENGTH while (j <= LINE_LENGTH): val_t = 0 val = random.randint(0, 9) # // val_t = val_t * MULTI; val_t = val_t + val # // Repeat under certain condition, prevent leading 0 if (val_t == 0 and j == 1): j = 0 # // Add solution if value is a 7 if (val == 7): counts_7[i - 1] = counts_7[i - 1] + 1 innerlist[j - 1] = str(val_t) j = j + 1 numbers[i - 1] = ''.join(innerlist) solution = solution + counts_7[i - 1] i = i + 1 player.num7 = solution return dict( Numbers = numbers, solution = player.num7, Normal=player.subsession.MODE == 'Normal' ) @staticmethod def before_next_page(player: Player, timeout_happened): if player.count_7num == player.num7: player.count_7_points = 4; if player.count_7num == player.num7 +1: player.count_7_points = 3; if player.count_7num == player.num7 -1: player.count_7_points = 3; if player.count_7num == player.num7 +2: player.count_7_points = 2; if player.count_7num == player.num7 -2: player.count_7_points = 2; if player.count_7num == player.num7 +3: player.count_7_points = 1; if player.count_7num == player.num7 - 3: player.count_7_points = 1; # else: # return player.count_7_points == 1 class SelectAnalogy(Page): form_model = 'player' form_fields = ['raw_responses1'] def get_timeout_seconds(self): return 13 @staticmethod def is_displayed(player: Player): return player.type == 0 and player.q1 == 3 and not player.period_over @staticmethod def js_vars(player: Player): stimuli1 = [to_dict2(trial2) for trial2 in Trial2.filter(player=player)] # print("second",dict(trials1=stimuli1)) return dict(trials2=stimuli1, ) @staticmethod def vars_for_template(player: Player): return { 'Normal': player.subsession.MODE == 'Normal', } @staticmethod def before_next_page(player: Player, timeout_happened): import json try: responses = json.loads(player.raw_responses1) except json.JSONDecodeError: responses = {} # Set an empty dictionary as the default value if not responses: # Check if responses is empty for trial2 in Trial2.filter(player=player): trial2.choice = 0 # Set choice to 0 (or any other value representing no selection) trial2.is_correct = False # Set is_correct to False else: for trial2 in Trial2.filter(player=player): trial2.choice = responses.get(str(trial2.id), 0) # Use get() to retrieve the value, defaulting to 0 if not found trial2.is_correct = trial2.choice == trial2.solution player.num_correct1 = sum(trial2.is_correct for trial2 in Trial2.filter(player=player)) player.Apoints2 = player.num_correct1 * 2 player.raw_responses1 = '' class SelectNumberSeq(Page): form_model = 'player' form_fields = ['user_input1'] def get_timeout_seconds(self): return 13 def is_displayed(player: Player): return player.type == 0 and player.q1 == 3 and not player.period_over @staticmethod def js_vars(player: Player): astimuli1 = [to_dict_num2(tnumb2) for tnumb2 in Numb2.filter(player=player.in_round(1), round_number = player.round_number)] return dict(tnumb2=astimuli1, ) @staticmethod def vars_for_template(player: Player): return { 'Normal': player.subsession.MODE == 'Normal' } @staticmethod def before_next_page(player: Player, timeout_happened): for tnumb2 in Numb2.filter(player=player.in_round(1), round_number = player.round_number): if player.user_input1 == int(tnumb2.solution): player.number_points2 = 2 #end for the optional task class WaitPage(WaitPage): pass class RoundResults(Page): timeout_seconds = 15 timer_text = C.TIMER_TEXT def is_displayed(player: Player): return not player.period_over def vars_for_template(player: Player): player.total_7_points = player.count_7_points + player.count_7_points1 + player.count_7_points2 + player.count_7_points3 player.total_user_input= player.number_points + player.number_points2 player.total_Apoints = player.Apoints + player.Apoints2 player.total_user_sum = player.total_7_points + player.total_user_input + player.total_Apoints return dict( A = player.total_7_points, B= player.total_user_input, C = player.total_Apoints, ) # class SamePage(Page): # def before_next_page(player: Player, timeout_happened): # player.participant.vars['type'] = player.type # # print("type", player.participant.vars['type']) # # # # # class TaskResults(Page): # # pass # # # def vars_for_template(player: Player): # # sum_7 = 0 # # sum_user = 0 # # sum_correct = 0 # # # # for p in player.in_all_rounds(): # # sum_7 += p.total_7_points # # sum_user += p.total_user_input # # sum_correct += p.total_Apoints # # # # # result = player.in_all_rounds() # # # print("result") # # # # player.sum_7 = sum_7 # # player.sum_user = sum_user # # player.sum_correct = sum_correct # # player.total_user_sum = player.sum_7 + player.sum_user + player.sum_correct # # # # # # return { # # "sum_7":player.sum_7, # # "sum_user":player.sum_user, # # "sum_correct":player.sum_correct, # # "total" : player.total_user_sum # # # # } # # # # # # @staticmethod # # def is_displayed(player): # # return player.round_number == 3 # # class CalculatePayoff(WaitPage): wait_for_all_groups = True @staticmethod def after_all_players_arrive(subsession: Subsession): for group in subsession.get_groups(): type_0_players = [p for p in group.get_players() if p.type == 0] other_players = [p for p in group.get_players() if p.type != 0] #print("type 0", type_0_players) #print("type 1", other_players) for player in group.get_players(): if player.period_over==False: if player.type == 0: #Kunde # perform calculation for type 0 player player.Anbieter_utilityA = round(other_players[0].total_user_sum * C.UTIL_FORKUNDE, 2) player.Kunde_utilityk = player.total_user_sum * C.FAC_FORKUNDE player.Utility_c = 1 * (3 if abs(player.estimatedpoints - other_players[0].total_user_sum)<3 else 0) #3 if: Round 3 on & abs(player.Kunde.estimate-other_players[0].total_user_sum)<3; else:0 #range for Kunde-Estimation: 0 until 24 player.cost = other_players[0].total_user_sum * C.FAC_FORANBIETER player.total = round(player.Anbieter_utilityA + player.Kunde_utilityk + player.Utility_c - player.cost,2) player.payoff = player.total #print("type=0",player.Anbieter_utilityA) #print("Kunde_utilityB=0", player.Kunde_utilityk) #print("cost", player.cost) #print("total", player.total) #print("estimatedcost",player.Utility_c) else: #Anbieter player.Anbieter_utilityA = player.total_user_sum * C.FAC_FORANBIETER player.Kunde_utilityk = 0 #if len(player.get_others_in_group()) != 0: #no match plK = type_0_players[0] #retrieve Kunde who is assigned to the Anbieter #print("Spielerpaar", player.number_part1, plK.number_part1) if (plK.q1 is not None and plK.q1>1): #Kunde chose to do some task on his own if (plK.total_user_sum == 4): player.Kunde_utilityk = plK.total_user_sum * C.FAC_FORKUNDE else: player.Kunde_utilityk=(4-plK.total_user_sum)*-0.5 player.utility_top = 0 if player.round_number>=3: player.utility_top = 1 * (3 if player.top == True else 0) player.total = max(0,player.Anbieter_utilityA + player.Kunde_utilityk + player.utility_top) player.payoff = player.total #print("Anbieter_utilityA", player.Anbieter_utilityA) #print("Kunde_utiltiyB", player.Kunde_utilityk) #print("top", player.utility_top) #print("total", player.total) else: player.total = C.NO_TRANS_PAYOFF player.payoff=C.NO_TRANS_PAYOFF def title_text(self): return "Bitte warten" def body_text(self): return "Bitte warten Sie, bis das Experiment weitergeht." class ShowPayoffRound(Page): timeout_seconds = 30 #for testing 500 timer_text = C.TIMER_TEXT # @staticmethod # def is_displayed(player: Player): # return player.round_number >= 3 @staticmethod def vars_for_template(player: Player): return dict( util_seller = player.Anbieter_utilityA, util_customer = player.Kunde_utilityk, choice_result = player.Utility_c if player.type==0 else 0.0, costs = player.cost if player.type == 0 else 0.0, period_winning = player.total, customer = player.type == 0, top = 3.0 if player.top and player.round_number>=3 else 0.0, ## use the top ) @staticmethod def is_displayed(player: Player): return not player.period_over class RatingGroupMember(Page): form_model = 'player' form_fields = ['rate_group_member'] @staticmethod def vars_for_template(player: Player): return dict( opposite = "Anbieter" if player.type == 0 else "Kunde", suffix = "s" if player.type==0 else "n" ) @staticmethod def is_displayed(player: Player): return not player.period_over class WaitRating(WaitPage): wait_for_all_groups = True @staticmethod def after_all_players_arrive(subsession): for group in subsession.get_groups(): rn = group.round_number ## Only if a group is matched, not a single Seller ## nur wenn tatsächlich gespielt wurde if len(group.get_players()) > 1 : for player in group.get_players(): opposite = player.get_others_in_group()[0] if not player.period_over: opposite.rating = player.rate_group_member if rn > 1 : opposite.avg_rating = round((opposite.in_round(rn-1).avg_rating*(rn-1) + opposite.rating)/rn,1) else: opposite.avg_rating = round(opposite.rating,1) else: if rn > 1: opposite.avg_rating = round(opposite.in_round(rn-1).avg_rating,1) else: opposite.avg_rating = round(opposite.rating,1) else: ## nur der anbieter & schauen für not played together player = group.get_players()[0] player.rating = 0 if rn > 1: ## dont destroy the avg rating by a zero rating player.avg_rating = round(player.in_round(rn-1).avg_rating,1) else: player.avg_rating = 0 def title_text(self): return "Bitte warten" def body_text(self): return "Bitte warten Sie, bis das Experiment weitergeht." ## berechne bewertung hier ## not correct if u only wanna wait for group member pass class WaitMyPage(WaitPage): def after_all_players_arrive(group: Group): pass #title and body text for the wait page def title_text(self): return "Bitte warten" def body_text(self): return "Bitte warten Sie, bis das Experiment weitergeht." class EndPeriod(Page): @staticmethod def vars_for_template(player: Player): # calculate average rating for this round return dict( rating="{:.1f}".format(player.rating), avg_rating="{:.1f}".format(player.avg_rating), round_number=player.round_number ) @staticmethod def is_displayed(player: Player): return not player.period_over # return dict( # rating= "{:.1f}".format(player.rating) # ) # # pass class FinalResultsWaitPage(WaitPage): @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS def title_text(self): return "Bitte warten" def body_text(self): return "Bitte warten Sie, bis Ihnen das Gesamtergebnis angezeigt wird." class FinalResults(Page): @staticmethod def is_displayed(player: Player): return player.round_number == C.NUM_ROUNDS def vars_for_template(player: Player): return dict( payoff_Taler = round (player.participant.payoff, 2), payoff_Euro = player.participant.payoff_plus_participation_fee(), ) def before_next_page(player: Player, timeout_happened): player.participant.vars['treatment'] = player.subsession.TREATMENT #print("treatmenmt",player.participant.vars['treatment']) page_sequence = [WelcomePage, NumberEntry, LinkPlayer, WaitMyPage, Instruction, RoleAssignment, GroupMatchingWaitPage, RoleAssignmentKunde, RoleAssignmentAnbieter, #get the type in rounds StartNextRound, WaitForallPlayers, #option page if he want to work on task or not AnbieterInfo, KundeInfo, MatchingInfoKunde, MatchingKundeWaitPage, OneToOneMatching, AfterMatchingInfoKunde, WaitForallPlayers, TransactionInfoKunde, TransactionInfoAnbieter, Similarity, Estimate_PerceivedSimilarity, #task pages #WaitMyPage, CountdownTask, RRandomNum, Analogy, srandom, NumberSeq, srandom1, Analogy1, srandom2, NumberSeq1, SelectRandom, SelectAnalogy, SelectNumberSeq, RoundResults, #task Pages end here same page #WaitRating, CalculatePayoff, ShowPayoffRound, RatingGroupMember, WaitRating, EndPeriod, FinalResultsWaitPage, FinalResults]