Getting variable from csv, based on DropDown selections

PennController for IBEX Forums Support Getting variable from csv, based on DropDown selections

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #8309
    bta
    Participant

    I have a CSV with multiple columns, and I want my template to run trials using different columns depending on DropDown selections.

    To be clearer: I start off asking the participant to select from two DropDown lists, and I’m able to create variables that has that information, and then I try to use a (javascript) variable as the input to a “newImage” construct. And it seems to work — images come up from the CSV! BUT the problem is that the script always pulls values from the last column in the CSV, instead of from the column corresponding to the header text stored in the variable.

    Here’s an example:
    https://farm.pcibex.net/r/zObmeL/

    Any thoughts on what’s going on here?

    #8312
    Jeremy
    Keymaster

    Hi,

    Javascript is immediate, PennController is delayed. More specifically, you cannot dynamically pass values to newImage (also, how would PennController be able to preload the image file if it had to wait until the trial starts to know which file to use?)

    What happens in your case is, as soon as the experiment page is open, all the javascript code is executed immediately (top down). First it creates the varForImg variable, it creates the setvarForImg and getvarForImg functions, it sets the Sequence, it creates the trial labeled "whoareyou", and runs the Template function to create as many newTrials as there are lines in fullList.csv. Because you call setvarForImg 9 times in that newTrial function, it is called 9 times with each newTrial creation, and when the script gets to newImage("comicstrip", varForImg) when creating a trial, the value of varForImg is always set to the value of variable.P3C, because that’s the value passed to the most recently executed setvarForImg function

    Then, when you progress through the experiment, as you get to a trial labeled "demo", that trial already contains an Image element named "comicstrip" that points to a file whose name is the value in the P3C cell for the row from which the trial was created. The first PennController commands to be run as you start a new trial are the tests on the Var element, whose success commands have no actual effect (because setvarForImg returns undefined, which success will simply ignore: undefined is not a PennController command). When the trial’s execution reaches the Image element, it will simply display the the file referenced in the P3C cell, regardless of the earlier tests

    What you can do instead is delete all references to varForImg (including the javascript functions) and include all 9 possible newImage commands in the trial (then PennController will effectively create, and preload, all 9 Image elements per trial) but only execute one of those in the tests on the Var element:

    Template("fullList.csv",
        variable => newTrial("demo",
            newText("head", " ")
                .text(getVar("asdf"))
                .before(newText("b","").text(getVar("namelist")).after(newText(": ")))
                .center()
                .print()
            ,
            defaultImage.center().print()
            ,
            getVar("namelist")
                .test.is("P1A").success( newImage(variable.P1A) )
                .test.is("P1B").success( newImage(variable.P1B) )
                .test.is("P1C").success( newImage(variable.P1C) )
                .test.is("P2A").success( newImage(variable.P2A) )
                .test.is("P2B").success( newImage(variable.P2B) )
                .test.is("P2C").success( newImage(variable.P2C) )
                .test.is("P3A").success( newImage(variable.P3A) )
                .test.is("P3B").success( newImage(variable.P3B) )
                .test.is("P3C").success( newImage(variable.P3C) )
            ,
            newButton("moveOn", "Continue")
                .center()
                .print()
                .wait()
        )
    )

    Jeremy

    #8314
    bta
    Participant

    Oh great, thanks! This is very helpful. I did not know that all JS functions are run from the start, even when the calls to those functions are made within instances of PennController test.is.

    The one thing that I didn’t mention before is that I did want to reuse the image multiple times, which I think would just mean using the series of test.is statements every time I reuse the image. Is that right?
    (i.e., it seems to me that all of these newImages cannot have the same name —something like testerImage— because every time newImage is called it needs to have a unique identifier; and because of that, there’s no way to use a single line of code like getImage("testerImage") to call back that same image.)

    #8315
    Jeremy
    Keymaster

    Hi,

    You could print the image onto a Canvas element, and manipulate that one Canvas element instead—I don’t think there’s anything you can do on an Image element you cannot do on a Canvas element:

    Template("fullList.csv",
        variable => newTrial("demo",
            newText("head", " ")
                .text(getVar("asdf"))
                .before(newText("b","").text(getVar("namelist")).after(newText(": ")))
                .center()
                .print()
            ,
            newCanvas("image").center().print()
            ,
            getVar("namelist")
                .test.is("P1A").success( newImage(variable.P1A).print(getCanvas("image")) )
                .test.is("P1B").success( newImage(variable.P1B).print(getCanvas("image")) )
                .test.is("P1C").success( newImage(variable.P1C).print(getCanvas("image")) )
                .test.is("P2A").success( newImage(variable.P2A).print(getCanvas("image")) )
                .test.is("P2B").success( newImage(variable.P2B).print(getCanvas("image")) )
                .test.is("P2C").success( newImage(variable.P2C).print(getCanvas("image")) )
                .test.is("P3A").success( newImage(variable.P3A).print(getCanvas("image")) )
                .test.is("P3B").success( newImage(variable.P3B).print(getCanvas("image")) )
                .test.is("P3C").success( newImage(variable.P3C).print(getCanvas("image")) )
            ,
            newButton("Flicker")
                .center()
                .print()
                .wait()
                .remove()
            ,
            getCanvas("image").remove()
            ,
            newTimer(2000).start().wait()
            ,
            getCanvas("image").print()
            ,
            newButton("Finish").center().print().wait()
        )
    )

    Jeremy

    #8316
    bta
    Participant

    Thank you so much, this is so helpful! I find it challenging to think this way, but I’m starting to get used to it.

Viewing 5 posts - 1 through 5 (of 5 total)
  • You must be logged in to reply to this topic.