import numpy as np import os import pandas as pd import random # LOGIC ---------------------------------------------------------------------------------------------------------------- # IV: number of same/different trials; same number of full-info, choice-only and reward-only trials # need to align two sequences # what I need to align are trial-types (not queries; but what do I have to take care of when it comes to the queries?) # so it seems like I first have to generate one page + query sequence # and then there are multiple options, I think. # I could generate X trial sequences and then find a way to match those (ohne zuruecklegen) dependent on how many same/different trials there are. # then I would have a list that shows the number for "same" and I could "manually" select a range # what is the range? I have 50 participants per group. And I could have 40 trials that are the same. I'm not sure what the minimum same is # are there any queries that cannot happen across the two participants? --> no # different note to self: I can't just use page sequence + 1 for partner, because the participants will have codes and players always the same number... # ---------------------------------------------------------------------------------------------------------------------- def number_of_choice_only_trials(total_no_trials, full_info_trial, number_minimum_inferences): # the number of choice_only_trials is dependent on how often we will ask about reward inferences and choice inferences. # the lowest number of choice_only_trials determines how often we can ask for reward inferences # the highest number of choice_only trials limits how often we can ask for choice_inferences because the number of full_info_trials stays the same number_choice_only_trials = np.random.randint(low=number_minimum_inferences, high=total_no_trials-number_minimum_inferences-full_info_trial) # In case I want to manually try stuff: #number_choice_only_trials = np.random.randint(low=18, high=25) # this setup would mean return number_choice_only_trials def order_trials(total_no_trials, full_info_trial, number_choice_only_trials): number_reward_only_trials = total_no_trials-full_info_trial-number_choice_only_trials trial_type = [1, 2, 3] # manually converting full_info_trial=1, number_choice_only_trials=2, number_reward_only_trials=3 frequencies = [full_info_trial, number_choice_only_trials, number_reward_only_trials] trial_sequence = [] # create a list with trial_type numbers that are included however many times they are supposed to be included for trial_type, frequencies in zip(trial_type, frequencies): trial_sequence.extend([trial_type] * frequencies) random.shuffle(trial_sequence) # randomly shuffled list of trials return trial_sequence def order_trial_and_queries(trial_sequence, number_minimum_inferences, df): while True: number_choice_inferences = number_minimum_inferences number_reward_inferences = number_minimum_inferences number_choice_predictions = number_minimum_inferences number_reward_predictions = number_minimum_inferences # APPROACH # identify the index of every trial that can have a certain query # then randomly select the index of however many queries of that type I need # and then I somehow have to add the query number behind each index. but I need to do all of them at the same time as otherwise the indexes will move # I also think that there are more chances for prediction queries than inference queries. Therefore, I'll first place the inference queries and then set the prediction queries # REWARD INFERENCE # reward inference queries can happen only after choice_only trials save_index = [] for index in range(len(trial_sequence)): # I can only ask for a reward inference if the next trial is not a reward_only trial or the last trial # can be asked about first trial if trial_sequence[index] == 2 and not index == (len(trial_sequence)-1): # 2=choice_only_trial; because len=40, but index starts at 0 if not trial_sequence[index+1] == 3: # 3= reward_only_trial save_index.append(index) #needed to put on other level and not in same if loop as otherwise index+1 refers to something outside of list else: continue # if there are more possible positions in the trial sequence that a reward inference can be asked, randomly select some positions # if there are less possible positions in the trial sequence that a reward inference can be asked, please start again if len(save_index) < number_minimum_inferences: #print('not enough reward inferences') # I hope this is the right way to start again break else: chosen_indices_reward_inference = random.sample(save_index, number_reward_inferences) # and now save these results in dataframe df['reward_inference_query'] = 0 for i in chosen_indices_reward_inference: df.loc[i, 'reward_inference_query'] = 1 # first row then column, df.loc[row, column] # CHOICE INFERENCE # choice inferences queries can happen only after a reward_only trial # can be asked on first (?) and last trial save_index = [] for index in range(len(trial_sequence)): if trial_sequence[index] == 3: # 3= reward_only_trial save_index.append(index) else: continue # save index gives the index/position after which choice_inference_queries can be inserted # but it may be that there are more reward_only trials than choice_inference_queries should be asked # so a random number of indices need to be selected if len(save_index) < number_minimum_inferences: print('not enough choice inferences') break else: chosen_indices_choice_inference = random.sample(save_index, number_choice_inferences) # and now the new approach with pandas is to put a 0 in all rows except those that are part of chosen index df['choice_inference_query'] = 0 for i in chosen_indices_choice_inference: df.loc[i, 'choice_inference_query'] = 1 # .loc[first row, then column] # now add predictions, but no "cross reward/choice inference/prediction" (NoNo cases) # but now the question is _where_ I can indicate that they are asked before information is shared although they are associated with a trial that follows? # identify all possible trials _on_ which prediction question can be asked # and to make sure everything is correct, I took the easy route and went through reward and choice prediction indices separately # REWARD PREDICTION # no sequence like this: missing choice --> predict reward --> reward --> choice inference NoNo save_index = [] for index in range(len(trial_sequence)): # index=trial and the trial should not appear in chosen_indices_choice_inference list if (trial_sequence[index] == 1 or trial_sequence[index] == 2 or trial_sequence[index] == 3) and (index not in chosen_indices_choice_inference): # full_info_trial=1, number_choice_only_trials=2, number_reward_only_trials=3 save_index.append(index) else: continue if len(save_index) < number_minimum_inferences: print('not enough reward predictions') break else: chosen_indices = random.sample(save_index, number_reward_predictions) df['reward_prediction_query'] = 0 for i in chosen_indices: df.loc[i, 'reward_prediction_query'] = 1 #first row then column # CHOICE PREDICTIONS # no reward inference if choice predcition first. choice --> missing reward --> choice prediction --> choice --> reward inference NoNo save_index = [] for index in range(len(trial_sequence)): # but here the index=trial is not allowed to appear in the trial BEFORE/prior to the chosen_indices_reward_inference chosen_indices_reward_inference_previous_trial = [element - 1 for element in chosen_indices_reward_inference] # now that I allow inferences on first trial, it could happen that chosen_indices_reward_inference_previous_trial contains a -1 but that should be fine. if (trial_sequence[index] == 1 or trial_sequence[index] == 2 or trial_sequence[index] == 3) and (index not in chosen_indices_reward_inference_previous_trial): # full_info_trial=1, number_choice_only_trials=2, number_reward_only_trials=3 save_index.append(index) else: continue if len(save_index) < number_minimum_inferences: print('not enough choice predictions') break else: chosen_indices = random.sample(save_index, number_choice_predictions) df['choice_prediction_query'] = 0 for i in chosen_indices: df.loc[i, 'choice_prediction_query'] = 1 #first row then column print('DONE') return df # RUN------------------------------------------------------------------------------------------------------------------- total_no_trials = 40 full_info_trial = 5 number_minimum_inferences = 7 counter_trial_sequences = 1 num_page_sequences = 300 # this should lead to 50 sequences (one per participant in each condition but the same across conditions) in the end plus a couple extra just in case # Here I'm trying to create the page sequences for all participants while counter_trial_sequences < num_page_sequences: number_choice_only_trials = 16#number_of_choice_only_trials(total_no_trials, full_info_trial, number_minimum_inferences) results = None result_counter = 0 while results is None: #SOMETHING trial_sequence = order_trials(total_no_trials, full_info_trial, number_choice_only_trials) #number_choice_only_trials # create a dataframe to save in df = pd.DataFrame(trial_sequence, columns=['trial_type']) # I'm planning to add 4 columnds to this data frame for choice_prediction, reward_prediction, choice_inference, reward_inference # adding the number_choice_only trials for each row (i.e. so that I have it by trial not only by participant) df['IV_number_choice_only_trials'] = number_choice_only_trials df.index.name = 'trial_index' results = order_trial_and_queries(trial_sequence, number_minimum_inferences, df) # Not sure where I can test how many sequences didn't work out if results is None: print('result is none', result_counter) result_counter += 1 df = results # Save dataframe df.to_csv('01_PageSequences/SI_PageSequence_' + str(counter_trial_sequences) + '.csv') #print('df', df) counter_trial_sequences +=1 """ # Save list page_sequence = str([num for sublist in page_sequence for num in sublist]) file1 = open("SI_PageSequence_1.txt","w") #print('page_sequence', page_sequence) file1.write(page_sequence) file1.close() # Test current_working_directory = os.getcwd() filename = current_working_directory + '\SI_PageSequence_' + str(1) + '.txt' page_sequence = open(filename, "r") content = page_sequence.read() # Read the content of the file page_sequence.close() # Close the file after reading print('page sequence in custom function:', type(list(content)), content) """