| Reference | Downloads | Github

Must Click any valid answer object before Clicking next to move onto the next trial: video clip as stimuli

Objective: When a movie stimulus appears, people must click target present (Yes) or target absent (No) before clicking Next to move onto the next trial (accepts two different mouse clicks, 1 that does not end trial and 1 that does). If the next image is not selected, the movie clip will loop three times. People are allowed to change their mind before moving to the next trial. If people click Next without clicking Yes or No, a feedback message will appear.

What did you try to make it work?:

-I tried to put registering Answer (yes or no) in one routine before registering Next Image in the next routine.

The problem with that is that for small images, that may be okay, displaying the same image in both routines. However, it is not viable for movie clips (it would of course, restart). Please note: trials_2 is not labeled well. Trials is uncheckmarked in the popup screen. I added a loop there so that they clip would loop a total of 3 times if they do not respond with a Next Image button.

Overview of Flow:

I tried to experiment with adding a if/elif/else loop to end the routine when people select the nextImageButton_2. At the moment, it is saving the name of the Yes and No buttons correctly and saving 1 additional name if people select a different answer. People must press yes or no before pressing next. The error I get has to do with syntax in parts I commented out.

I don’t know if the yellow boxed area is noting and not saving the positions, but there is no error. Would this info be in a buffer?

Making sure that the video stopping does not end routine

Saving answer if they change it AND trying to do the end routine code component but there is a syntax error in the part I commented out

I greatly appreciate the feedback. Thanks!

Also, at the moment, I am learning how to use Psychopy with the manual and new book. I’m also trying to make a “standard” program that is easy for people to pick up and make minor tweeks for any future experiment permutations (so keeping as much things as I can in the Builder is beneficial at this time). In the future, I hope to move into the coder after using some builder features.

@Miss_Egg, the commented out code has some errors - see code_4 component pic. First, you missed the comma separating the arguments you entered into the isPressedIn function. Second, you are overwriting the setColor function by assigning values to that function. Instead, you need to pass the setColor function those arguments e.g.,

# or
yesButton_2.color = args

As shown in that example, setting opacity like that is ok.

The code in the yellow box is appending the name of the clicked target into a list called clicked_name stored in the mouse object called mouseNextIma.

The final set of syntax errors is found because first you have not ended your if statement with colons, and because you are trying to check whether calling an append function (add to list) is the same as the name of the clicked variable, which does not make sense. Further, append takes exactly 1 argument, and you are passing it None, and that is probably causing one of your syntax errors.

To fix:

if mouseNextIma.isPressedIn(nextImageButton_2, buttons=[0]):
    if in mouseNextIma.clicked_name:
        continueRoutine = False
# etc


Thank you so much for your replies and explaining what some of the items are doing. It is helping my learning process! That is true-that doesn’t make sense xD. I was able to look up “in” and append() to understand it more. For some reason, lens did save the first item in the list instead of the last and seemed to overwrite or not display name and pos (prob because it’s now a list?) and the reaction time doesn’t write in the excel sheet. If I can’t figure that out, I might start a new topic with a different title that is related to this next part.

All in all, the fix did it! Much thanks :slight_smile: !

Hi @Miss_Egg, I am glad its helping. You can amend your code so that the last mouse click appended to the list is written in your datafile. This will give you the name of the final object clicked.

trials_2.addData('mouseNextIma.clicked_name', mouseNextIma.clicked_name[-1])  # [-1] indexes the last item of a list

If your RTs are not saving, create a new list for saving RTs at the beginning of the routine (in the Begin Routine tab of the code component). Then, add the following under each conditional statement you outlined in yellow:

# Begin Routine Tab...
rtList = []  # empty list for storing RTs

# In the Each Frame tab, under your conditional statements outlined in yellow
rtList.append(t)  # add an RT to a list if the objects were clicked. Note, t is already defined by Builder as a trial clock

If you want to add things like pos and RTs to your excel file, add the following:

trials_2.addData('stimX', stimX)
trials_2.addData('stimY', stimY)
if len(rtList):
    trials_2.addData('RT', rtList[0])  # Get the first RT from the list if RTs exist
    trials_2.addData('RT', -1)  # -1 for filtering data - use anything you want


Thank you for the post! I did noticed that in my end routine components tab that I did have 0 to get the first instead of -1! Whew. fyi-I’ll add some extra info for following readers (since my almost finalized program is coming together-just a friendly crash now :smiley: but I’ll make a new thread)

I was curious what builder was calling the list. When the mouse stores parameters, time, they called the list name clicked_time (like clicked_name and clicked_pos). I see that I could have created a new list to start indexing items, but in case the next person looks at my builder/compiled code, I went ahead and used clicked_time. Since I do have a if/ else if/ else loop to allow people to change their answer before going to the next trial and that they must click next before moving next,

#if people end up changing their answer, then allow prog to save the answer before moving on in each frame tab
#saves the button name, time clicked, and position to a list
if mouseYN_2.isPressedIn(yesButton_2, buttons=[0]):

    stimX,stimY = mouseYN_2.getPos() #in case you want to later save the x and y coordinates in end routine

elif mouseYN_2.isPressedIn(noButton_2, buttons=[0]):

    stimX,stimY = mouseYN_2.getPos()#in case you want to later save the x and y coordinates in end routine

Then, in the end routine tab

if len(mouseYN_2.clicked_name):  #if there is a something in length of list (versus nothing in list)
    trials.addData('Answer',mouseYN_2.clicked_name[-1]) #saves last answer in list of clicked Y and N
    trials.addData('Button position', mouseYN_2.clicked_pos[-1]) #saves the last ans's x, y mouse position @ valid obj's center coordinates
    trials.addData('Reaction Time', mouseYN_2.clicked_time[-1]) #reaction time of last clicked answer

I wrote the routine nameClock.getTime() because I was playing with some loops to figure out how to loop a mobie clip within the same routine. I didn’t need an extra loop in the flow, but that routineNameClock.getTime() worked fine still.

Also, if you are trying to loop a movie clip (I can’t believe how many things I tried until this simple code worked!), you do not need “loopSameClip” from my screenshot. Just need the below in the each frame tab:

movie_2.loop=True or your name of movie.loop=True

I wrote the routine nameClock.getTime() because I was playing with some loops to figure out how to loop a mobie clip within the same routine. I didn’t need an extra loop in the flow, but that routineNameClock.getTime() worked fine still.


I`m looking for help regarding my experiment.

Objective: I created a experiment which assignes participants randomly in two different groups. Each group get two different tasks with a possibility to answer by clicking on a „button“. I worked with images to save reaction time and clicked object.

Unfortunatly PsychoPy doesn´t saves the reaction time and the name of the clicked object since I put the code for the randomization in.

I used the code for randomization from this url: Assigning participants randomly to a condition

I tried:

To use the proposed code above

To change the position of the code for randomization

Maybe somebody has suggestion of what I can try next?

Thank you in advance!