psychopy.org | Reference | Downloads | Github

Builder doesn't translate stimuli start conditions to javascript

OS Win10
PsychoPy version v2020.1.3:
**Standard Standalone? I think so
What are you trying to achieve?:
My experiment has stimulus components that have multiple conditional statements governing their start. For example, I have sound events with start conditions like this:

sound_1.status == FINISHED and expInfo[‘block_rand’] == ‘1’

These work fine in psychopy, but they don’t work in pavlovia, presumably because the “and” has to be replaced by “&&” for javascript. But psychopy won’t let me use the && code in the builder (the “ok” box greys out when I replace “and” with “&&”). It will allow a single ampersand:

sound_1.status == FINISHED & expInfo[‘block_rand’] == ‘1’

But this doesn’t translate properly to javascript:

if (((sound_1.status == (FINISHED & expInfo[‘block_rand’]) == ‘1’)) && sound_2.status === PsychoJS.Status.NOT_STARTED)

Check out the nesting in those parentheses - that can’t be right. So my question is, how can I get psychopy to properly translate conditional statements into javascript? I tried manually editing the .js file but then I got the var missing error (frameDur is not defined error), probably because it couldn’t compile the conditional statement properly in javascript in the first place:

11312.9925 ERROR Line 6066: Unexpected identifier in SL_chords_150_trials.js

(yes, that’s the line with “and” in the javascript). Cheers,

Jon

Try having a code component in Each Frame which has, for example:

if sound_1.status == FINISHED and expInfo[‘block_rand’] == '1':
     startComponent = 1

then put $startComponent as the start condition.

That would allow the code part of the start condition to happen in an auto translated code component.

Ok cool that makes sense. Thanks! The only other problem is that I have close to 200 individual components that will need this treatment, so I was hoping to avoid having to do something individual for each one. Otherwise I’m in for a long day of coding…

If you have 200 individual components the I would recommend considering whether you can also create them in code. Are they all on screen at the same time? If not then you might not need them to be different components anyway and if they are then you might be able to create them within a loop.

e.g.

for Idx in range (9):
    bars.append(visual.ImageStim(
    win=win,
    name='ladder', 
    image='ladder.png', ori=0, 

No they’re mostly sequential, but the result of trying to incorporate branching and looping in one experiment. In fact, if these code components are used in a loop, will I have to have another component to set all the variables back to 0 for the next loop iteration? Thanks again!

I that case I suspect that your experiment could be simplified by using variables and code to manipulate a much smaller number of components.

Please message me if you’d like my help with this.

Cheers,

Wakefield

As an update to this thread, I ended up helping @jonprince with this but couldn’t get if note_x.status==FINISHED to work. I’m not clear why since it did work in an experiment I coded for @jsamper and it auto translated to PsychoJS.Status.FINISHED

So, since all the notes were of the same duration, my solution was:

if t>startTime+noteLength:
    if nowPlaying == 1:
        note_1.stop()
        circle_1.setFillColor(white)
        print('Sound 1 stopped')
    elif nowPlaying == 2:
        note_2.stop()
        circle_2.setFillColor(white)
        print('Sound 2 stopped')
    elif nowPlaying == 3:
        note_3.stop()
        circle_3.setFillColor(white)
        print('Sound 3 stopped')
    elif nowPlaying == 4:
        note_4.stop()
        circle_4.setFillColor(white)
        print('Sound 4 stopped')
    nowPlaying = 0
    Idx +=1


if nowPlaying == 0:
    if Idx == len(Sequence):
        print('End of sequence')
        continueRoutine=False
    else:
        startTime=t
        if Sequence[Idx]=='1':
            nowPlaying=1
            circle_1.setFillColor(blue)
            note_1.play()
            print('Sound 1 started')
        elif Sequence[Idx]=='2':
            nowPlaying=2
            circle_2.setFillColor(blue)
            note_2.play()
            print('Sound 2 started')
        elif Sequence[Idx]=='3':
            nowPlaying=3
            circle_3.setFillColor(blue)
            note_3.play()
            print('Sound 3 started')
        elif Sequence[Idx]=='4':
            nowPlaying=4
            circle_4.setFillColor(blue)
            note_4.play()
            print('Sound 4 started')