I have a .xlsx file with 48 links to files that I use to get stimuli within a inner loop.
Per inner loop 12 file are presented, in total the inner loop is repeated 4 times in an outer loop.
How can I (in builder) define that stimulis:
1-12 are going to be presented in iteration 1,
13-24 in iteration 2 etc.
I tried with selected row but I can only statically choose 1:12.
Advantage: easy to understand. Disadvantage: many conditions files.
In this case, you need two loops around your routine(s). The outer loop loops over a file with four rows, each containing a conditions file (say, in a column called conditions_file. The inner loop loads these conditions files in turn (enter $conditions_file as file name). So you have five conditions files in total: (1) row 1-12, (2) row 13-24, (3) row 25-36, (4) row 37-48, (5) the names of these four conditions files.
Select rows dynamically
Advantage: only one conditions file. Disadvantage: quite complex.
Create a new routine with a code component in the beginning of your loop.
Under âBegin experimentâ define a variable: this_loop_number = 0.
Then under âBegin Routineâ increment this value on each loop: this_loop_number +=1.
In the loop, set âselect rowsâ to $((this_loop_number-1)*12+1):(this_loop_number*12)
Finally, add a loop around the whole thing which repeats four times to get 1:12, 13:24, 25:36, and 37:48.
I wanted to check that @lindeloevâs âsetting rows dynamicallyâ solution worked (thatâs how it was designed but I donât think this is often tested). It did!
So hereâs an example experiment file showing it in action. Put these 3 files together in a folder and run the blockSubset experiment. A couple of notes:
the entries in the blocks file are '0:5, '5:10, '10:15 and note the ' just at the beginning of each one. That tells Excel to treat this as a string and not be clever and convert it into a date/time. For excel a string is indicated by just one ' at the beginning of the cell.
I set up this to run a single repeat of each trial. The trials within the blocks I made random and the blocks I made sequential (so you get 1-5 shuffled, then 5-10 shuffled etc)
Hi sorry I have a similiar issue, I just wanted to see if it would apply to my problem. I have also created a task looped from an excel file with 50 rows. I currently have it working from a place in which the participant provides a rating at each row. I was hoping to change my task (because it takes too long) to get ratings for the first 10 rows. Then to only trigger a rating for every second row for the next rows that comes through (with odd rows having the stimulus appear for two seconds then moving to the next row). Would I use a simliar method to yours here?
Probably not. In your case, you still want to run through every row in the conditions file, itâs just that on some of those trials you want to skip the rating scale. Probably the best way to do this is instead with a code snippet that decides if the rating scale will run on a given trial. The easiest way to arrange this would be to put the rating scale in its own routine. Insert a code component on that routine, and in its Begin routine tab, put some code something like this, which decides whether the routine will run, depending on the trial number (the default is that the routine will run, so you only need to determine trials where it wonât):
# am assuming your trial loop is called 'trials'. Replace with
# your actual loop name if necessary.
# NB loops are 0-based, so trial index 9 refers to the tenth trial.
if trials.thisN > 9 and trials.thisN % 2 == 0:
continueRoutine = False
The % operator returns the remainder after division. As 10 is even, 10 % 2 returns 0 and 11 % 2 returns 1, and so on, allowing you to flip behaviour between odd and even number trials. NB this is all zero based, so trial # 10 is actually the 11th trial, and so on.
Hi Michael thanks so much for your reply! I appreciate it! I tried inserting a code component and putting in
if bead_loop.thisN > 9 and bead_loop.thisN % 2 == 0:
continueRoutine = False
I copied this into the âbegin routineâ tab and my task continued with no syntax errors but nothing changed it ran through ratings at all 50 iterations. I also tried taking this same code and cutting it into the âend routineâ tab and nothing changed here either. Do I potentially need to change something in the rating component to make it recognise the code. When I open up the rating component âstartâ is set on time(s) â1â, would this override the code?
On updating Psychopy it works!!! Thank you so much!!! One last thing, so for the turns where âcontinueRoutine = Falseâ I was hoping to get the stimuli (beads) from each of those iterations to still display on the screen for 1 second (before it triggers the routine to end). At the moment it immediately triggers routines to end but I would like to get it so the iterations without ratings still have their stimulus appear for a second or so, Is this possible? I tried a few things such as
if bead_loop.thisN > 9 and bead_loop.thisN % 2 ==0 and t > 1:
thisN.time = t
continueRoutine = False
#I also tried this -
while t > 1:
thisN.time = t
if bead_loop.thisN > 9 and bead_loop.thisN % 2 ==0:
continueRoutine = False
None of my attempts worked though (I also made my âratingâ component in this routine to only start at 1.5 seconds hoping that it would mean for the routines that are forced to end it would not have appeared yet)
I would guess that the easiest thing to do is just create another separate routine that shows the stimulus for 1 second, which runs on every trial. Insert it before the routine with the rating scale.
I canât believe I didnât think of that!! Iâve spent so long trying to figure out how to do it via loop. Thank you so so much, this has helped me a real lot!! Cheers again have a great week
Hi everyone. This thread has been very helpful but I have hit a snag. My solution is similar to Jonâs, i.e. I have a separate Excel file that tells PsychoPy which rows to use (from a second Excel file) in each block. The entries of the former file are something like '0:4, '4:8, etc. These entries are in a column named $curr_block_trial_picks_training_phase, and I call this variable in a nested loop using Selected rows.
This works fine when I index the first ten rows (zero to nine). However, whenever I try indexing rows that are greater than a single digit, e.g. '0:10 instead of '0:9 I get the following error:
elif len(selection)>0:
TypeError: object of type âfloatâ has no len()
Note that this does not happen if I e.g. just type 0:10 directly into Selected rows.
What might be going on is that PsychoPy is casting numbers larger than single digits to floats, and then not knowing what to do with them. However, I have no clue how to fix it.
I am having a smiliar problem which canât be fixed with this solution.
I have an images routine and a video routine. They both have loops individually (images picking 3 images at random from its own excel file and videos picking one video randomly from its excel file) I then have an router loop which repeats this 9 times. The problem is for the videos i only want the 1 video that is picked randomly to display once, so 9 different videos are shown. But sometimes the same video shows again. I do not want this but I cannot set rows as I only want it to select one video.
Hi Jon,
Your demo code was the basis for a couple of experiments I ran using PsychoPy2 and PsychoPy v3.0.6 (builder versions). Now, I want to run the experiments on Pavlovia and the behavior is quite different. Instead of presenting all the items of each block, only the first item is presented. The experiment just proceeds. There is no error message.
Hello, I think im trying to do something similar on PsychoPy Builder but I havenât been able to the achieve it with the tips you gave.
I have to make a routine where two images show up at the same time, in a random order.
I created an excel where I have image_1 and image_2 and the pair that they belong to (depends on the row). I need for the images on each row to show up together, and at the same time, for the order to be random.
Could you be a bit more specific?
I just started using this program and im still learning.
I would put another variable as a column? So I would have Pair_practice, New variable, image1, image 2?
My solution was based on the assumption that you want two images side by side.
However, it can still be used if you want two images one after the other. Please could you show your two image components in the situation where image1 comes before image2?