log global vs. local variable

PennController for IBEX Forums Support log global vs. local variable

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #6287
    pchen
    Participant

    Dear Jeremy,

    I tried to log three local variables by using PennController .log( “label”, getVar(“xx”)). I hope to get all the logged values within the same line in the result (see the end of the code below).
    However, in the result file, the last three variables were all “undefined”. I tried .global() but then these variables are not updated trial by trial.

    I inherited the following code from my colleague, which used work around June, 2019. I wonder what has changed since and any suggestions will be appreciated.

    Thank you,
    Peiyao

    PennController.Template(
      variable => PennController(
        newImage("1", variable.Image1)
            .settings.size(200,200)
        ,
        newImage("2", variable.Image2)
            .settings.size(200,200)
        ,
        newImage("3", variable.Image3)
            .settings.size(200,200)
        ,
        newImage("4", variable.Image4)
            .settings.size(200,200)
        ,
        newCanvas("images", 1400, 200)
            .settings.center()
            .settings.add(0   , 0 , getImage("1") )
            .settings.add(200 , 0 , getImage("2") )
            .settings.add(1000 , 0 , getImage("3") )
            .settings.add(1200, 0 , getImage("4") )
            .print()
        ,
        newAudio("Instruction", variable.SoundFile)
        ,
        newVar("isEarly", 0)
            .settings.log()
        ,
        newTooltip("earlyWarning", "STARTED TOO EARLY. You moved your mouse from the Go button before it was possible to guess the correct option. Please don't move your mouse until you're about to click.")
            .settings.position("center")
        ,
        newVar("slowClick", 0)
            .settings.log()
        ,
        newTooltip("slowClickWarning", "CLICKED TOO LATE. You took too long to click on your selection. Please try to click faster next time!")
            .settings.position("center")
        ,
        newTimer(2000) // 2000 ms to preview images
            .start()
            .wait()
        ,
        newButton("Go")
            .print( "center at 50vw" , "center at 90vh" )
            .wait()
            .remove()
        ,
        newTimer("earlyStart", (parseInt(variable.AnimOn) - 200) )
        ,
        newTimer("timeLimit", (parseInt(variable.AccOff) + 800) )
        ,
    
        getAudio("Instruction")
            .play()
        ,
        getTimer("earlyStart")
            .start()
        ,
        getTimer("timeLimit")
            .start()
        ,
        
        newMouseTracker("mouse")
            .settings.log()
            .settings.callback( getTimer("earlyStart").test.running().success(getVar("isEarly").set(1)) )
            .start()
        ,
        
        newSelector("choice")
            .settings.add( getImage("1") , getImage("2") , getImage("3") , getImage("4"))
            .settings.callback( getTimer("timeLimit").test.ended().success(getVar("slowClick").set(1)) )
            .wait()
            .settings.log()
            
        ,
        getAudio("Instruction")
           .wait("first")
        ,
        getMouseTracker("mouse")
            .stop()
        ,
        getVar("isEarly")
            .test.is(1).success(getTooltip("earlyWarning").print().wait())
        ,
        
        getVar("slowClick")
            .test.is(1).success(getTooltip("slowClickWarning").print().wait())
            
      )
      .log( "ID", getVar("ID")    )
      .log( "Group", variable.Group  )
      .log( "Label", variable.Label )
      .log( "Target" , variable.true_target)
      .log( "selected", getVar("choice"))  // undefined in the result
      .log( "Early", getVar("isEarly"))  // undefined in the result
      .log( "Slow", getVar("slowClick"))  // undefined in the result
    )
    #6288
    Jeremy
    Keymaster

    Hello Peiyao,

    Simply replace .settings.log() on your newVar elements with .global().set(0) and you’ll see the values reported at the end of all of the trial’s lines in the results file, without the cross-trial value contamination

    However you never create a Var element named choice so the line .log( "selected", getVar("choice")) will always report undefined. If having the selection reported in the line corresponding to your Selector element is not enough and you want it to also appear on every other lines as well, you’ll have to create a dedicated Var element and set it accordingly. You normally should be able to set that Var element by referring to the Selector element directly, but there seems to be a bug with recent versions of PennController, so you’ll need to test the Selector and set each value manually:

    // ...
    newVar("selection").global()
    ,
    newSelector("choice")
        .add( getImage("1") , getImage("2") , getImage("3") , getImage("4"))
        .callback( getTimer("timeLimit").test.ended().success(getVar("slowClick").set(1)) )
        .wait()
        .log()
        .test.selected(getImage('1')).success( getVar("selection").set(1) )
        .test.selected(getImage('2')).success( getVar("selection").set(2) )
        .test.selected(getImage('3')).success( getVar("selection").set(3) )
        .test.selected(getImage('4')).success( getVar("selection").set(4) )
    // ...

    Of course replace .log( "selected", getVar("choice")) with .log( "selected", getVar("selection")) (it’s better not to name two elements the same)

    Let me know if you have questions

    Jeremy

    #6289
    pchen
    Participant

    It worked perfectly. Thank you so much!

    #6316
    mschrumpf
    Participant

    Hello everyone.
    If you don’t mind me barging in, I have the same problem. Either the fix is not working for me, or I am doing something wrong. Either way, I would appreciate some feedback on this.
    I want to record some demographic data at the start of the experiment:

    newTrial( "Angaben" , 
        newText("Ueberschrift", "<h2>Stichproben-relevante Angaben</h2>").center().print()
        ,
        newTextInput("inputAlter")
        .size("100px")
        ,
        newScale("inputGeschlecht", "m&auml;nnlich", "weiblich", "divers")
        ,
        newScale("inputHaendigkeit", "linksh&auml;ndig", "rechtsh&auml;ndig")
        ,
        newTextInput("inputGeboren")
        ,
        newTextInput("inputWohnsitz")
        ,
        newScale("inputDeutsch", "ja", "nein")
        ,
        newTextInput("inputMuttersprache")
        ,
        newTextInput("inputProlific-ID")
        ,
        newCanvas("Canvas", 600, 320)
            .add( 0,    0,  newText("Alter:"))
            .add( 400,  0,  getTextInput("inputAlter").log())
            .add( 0,    40,  newText("Geschlecht:"))
            .add( 400,  40,  getScale("inputGeschlecht").log())
            .add( 0,    80,  newText("H&auml;ndigkeit"))
            .add( 400,  80,  getScale("inputHaendigkeit").log())
            .add( 0,    120,  newText("Geboren in (Bundesland/Staat):"))
            .add( 400,  120,  getTextInput("inputGeboren").log())
            .add( 0,    160,  newText("Derzeitiger Wohnsitz (Bundesland/Staat):"))
            .add( 400,  160,  getTextInput("inputWohnsitz").log())
            .add( 0,    200, newText("Deutsch als Muttersprache?"))
            .add( 400,  200, getScale("inputDeutsch").log())
            .add( 0,    240, newText("Muttersprachen (au&szlig;er Deutsch):"))
            .add( 400,  240, getTextInput("inputMuttersprache").log())
            .add( 0,    280, newText("Prolific-ID:"))
            .add( 400,  280, getTextInput("inputProlific-ID").log())
            .print()
        ,
        newText("Warnung1", "Bitte f&uuml;llen Sie die Pflichtangaben aus.")
            .color("red")
            .italic()
            .center()
            .hidden()
            .print()
        ,
        newButton("Weiter") 
            .center()
            .print()
            .wait(
                getTextInput("inputAlter").test.text(/.+/)
                .and(getTextInput("inputGeboren").test.text(/.+/))
                .and(getTextInput("inputWohnsitz").test.text(/.+/))
                .and(getTextInput("inputProlific-ID").test.text(/.+/))
                .and(getScale("inputGeschlecht").test.selected())
                .and(getScale("inputHaendigkeit").test.selected())
                .and(getScale("inputDeutsch").test.selected())
                    .failure( 
                        getText("Warnung1")
                        .hidden()
                        ,
                        newTimer(100)
                        .start()
                        .wait()
                        ,
                        getText("Warnung1").visible() )
        ,
        newVar("Alter")
            .global()
            .set( getTextInput("inputAlter") )
        ,
        newVar("Geboren")
            .global()
            .set( getTextInput("inputGeboren") )
        ,
        newVar("Wohnsitz")
            .global()
            .set( getTextInput("inputWohnsitz") )
        ,
        newVar("Muttersprache")
            .global()
            .set( getTextInput("inputMuttersprache") )
        ,
        newVar("Prolific-ID")
            .global()
            .set( getTextInput("inputProlific-ID") )
            ,
        newVar("Geschlecht")
            .global()
            .set( getScale("inputGeschlecht") )
        ,
        newVar("Haendigkeit")
            .global()
            .set( getScale("inputHaendigkeit") )
        ,
        newVar("Deutsch")
            .global()
            .set( getScale("inputDeutsch") )
        
                )
        .log("Alter", getVar("Alter"))
        .log("Geschlecht", getVar("Geschlecht"))
        .log("Haendigkeit", getVar("Haendigkeit"))
        .log("Geboren", getVar("Geboren"))
        .log("Wohnsitz", getVar("Wohnsitz"))
        .log("Deutsch", getVar("Deutsch"))
        .log("Muttersprache", getVar("Muttersprache"))
        .log("Prolific-ID", getVar("Prolific-ID"))
    )
    .setOption("countsForProgressBar", false)
    .setOption("hideProgressBar", true);

    Then in a later trial, I want to call back to the variables entered here to write them into each line of the results file:

    Template( "itemlist_1_1.csv" , //Aufbau parallel zu "exercise.csv"
        row => newTrial( "Experiment" ,
            newKey("Enter", "Enter")
                .callback(
                    getButton("Weiter").click()
                    )
            ,
            newText("")
            .settings.css({
            "padding-top": "100px"
            })
            .print()
            ,
            newText("prompt", row.prompt)
            .settings.cssContainer({
            "background-color": "lightgrey",
            "width": "800px",
            "border-radius": "5px",
            "margin": "auto",
            "align": "center",
            "text-align": "center",
            "padding": "5px",
            "font-size": "large"})
            .print()
            .log()
            ,
            newText("Line", "<hr>")
            .settings.css({
            "width": "100%",
            "margin": "auto",  
            })
            .print()
            ,
            newTextInput("Continuation", "")
            .lines(1)
            .center()
            .settings.css({
                "border": "solid 2px royalblue",
                "border-radius": "5px",
                "width": "75%",
                "align": "center",
                "text-align": "left",
                //"padding": "10px 5px 0px 5px",
                "font-size": "large",
                "margin": "auto"
            })
            .print()
            .log()
            ,
            newText("Line", "<hr>")
            .settings.css({
            "width": "100%",
            "margin": "auto",  
            })
            .print()
            ,
            newText("Warnung3", "Bitte geben Sie eine Fortsetzung ein.")
            .color("red")
            .italic()
            .center()
            .hidden()
            .print()
            ,
            newButton("Weiter")
            .center()
            .print()
            .wait( getTextInput("Continuation").testNot.text("")
                .failure( 
                    getText("Warnung3")
                    .hidden()
                    ,
                    newTimer(100)
                    .start()
                    .wait()
                    ,
                    getText("Warnung3").visible() ) 
            )
        )
        .log("Alter", getVar("Alter"))
        .log("Geschlecht", getVar("Geschlecht"))
        .log("Haendigkeit", getVar("Haendigkeit"))
        .log("Geboren", getVar("Geboren"))
        .log("Wohnsitz", getVar("Wohnsitz"))
        .log("Deutsch", getVar("Deutsch"))
        .log("Muttersprache", getVar("Muttersprache"))
        .log("Prolific-ID", getVar("Prolific-ID"))
        //Zeichnet demografische Angaben aus Folie 2 in jeder Ergebniszeile auf
        .log("id", row.id)
        .log("cond", row.cond)
        .log("np1", row.np1)
        .log("np2", row.np2)
        .log("coref", row.coref)
        .log("vclass", row.vclass)
        .log("verb", row.verb)
        .log("list", row.list)
        .log("prompt", row.prompt)
        //Zeichnet Werte aus den angegebenen Tabellenspalten fuer die aktuelle Tabellenzeile auf 
        .log("Continuation", getVar("Continuation"))
    )

    But just like in Peiyao’s case, the lines .log("Alter", getVar("Alter")) and so on only insert “undefined” into the results file each time. The logging works fine on the demographic information trial. But later in the actual experiment, all variables are “undefined”. What can I do to fix this?

    #6318
    Jeremy
    Keymaster

    Hello,

    You have a problem with the parentheses of your first trial: all your newVar blocks are inside the wait command of the Button, and all your .log(...,getVar(...)) are attached to the closing bracket of that wait command, when they should be attached to the closing parenthesis of newTrial:

    newTrial( "Angaben" , 
        newText("Ueberschrift", "<h2>Stichproben-relevante Angaben</h2>").center().print()
        ,
        newTextInput("inputAlter").size("100px")
        ,
        newScale("inputGeschlecht", "männlich", "weiblich", "divers")
        ,
        newScale("inputHaendigkeit", "linkshändig", "rechtshändig")
        ,
        newTextInput("inputGeboren")
        ,
        newTextInput("inputWohnsitz")
        ,
        newScale("inputDeutsch", "ja", "nein")
        ,
        newTextInput("inputMuttersprache")
        ,
        newTextInput("inputProlific-ID")
        ,
        newCanvas("Canvas", 600, 320)
            .add( 0,     0, newText("Alter:"))
            .add( 400,   0, getTextInput("inputAlter").log())
            .add( 0,    40, newText("Geschlecht:"))
            .add( 400,  40, getScale("inputGeschlecht").log())
            .add( 0,    80, newText("Händigkeit"))
            .add( 400,  80, getScale("inputHaendigkeit").log())
            .add( 0,   120, newText("Geboren in (Bundesland/Staat):"))
            .add( 400, 120, getTextInput("inputGeboren").log())
            .add( 0,   160, newText("Derzeitiger Wohnsitz (Bundesland/Staat):"))
            .add( 400, 160, getTextInput("inputWohnsitz").log())
            .add( 0,   200, newText("Deutsch als Muttersprache?"))
            .add( 400, 200, getScale("inputDeutsch").log())
            .add( 0,   240, newText("Muttersprachen (außer Deutsch):"))
            .add( 400, 240, getTextInput("inputMuttersprache").log())
            .add( 0,   280, newText("Prolific-ID:"))
            .add( 400, 280, getTextInput("inputProlific-ID").log())
            .print()
        ,
        newText("Warnung1", "Bitte füllen Sie die Pflichtangaben aus.")
            .color("red")
            .italic()
            .center()
            .hidden()
            .print()
        ,
        newButton("Weiter") 
            .center()
            .print()
            .wait( getTextInput("inputAlter").test.text(/.+/)
                .and(getTextInput("inputGeboren").test.text(/.+/))
                .and(getTextInput("inputWohnsitz").test.text(/.+/))
                .and(getTextInput("inputProlific-ID").test.text(/.+/))
                .and(getScale("inputGeschlecht").test.selected())
                .and(getScale("inputHaendigkeit").test.selected())
                .and(getScale("inputDeutsch").test.selected())
                .failure( 
                    getText("Warnung1").hidden()
                    ,
                    newTimer(100).start().wait()
                    ,
                    getText("Warnung1").visible() 
                )
            )
        ,
        newVar("Alter").global().set( getTextInput("inputAlter") )
        ,
        newVar("Geboren").global().set( getTextInput("inputGeboren") )
        ,
        newVar("Wohnsitz").global().set( getTextInput("inputWohnsitz") )
        ,
        newVar("Muttersprache").global().set( getTextInput("inputMuttersprache") )
        ,
        newVar("Prolific-ID").global().set( getTextInput("inputProlific-ID") )
            ,
        newVar("Geschlecht").global().set( getScale("inputGeschlecht") )
        ,
        newVar("Haendigkeit").global().set( getScale("inputHaendigkeit") )
        ,
        newVar("Deutsch").global().set( getScale("inputDeutsch") )
    )
    .log("Alter", getVar("Alter"))
    .log("Geschlecht", getVar("Geschlecht"))
    .log("Haendigkeit", getVar("Haendigkeit"))
    .log("Geboren", getVar("Geboren"))
    .log("Wohnsitz", getVar("Wohnsitz"))
    .log("Deutsch", getVar("Deutsch"))
    .log("Muttersprache", getVar("Muttersprache"))
    .log("Prolific-ID", getVar("Prolific-ID"))
    .setOption("countsForProgressBar", false)
    .setOption("hideProgressBar", true)

    Jeremy

    #6329
    mschrumpf
    Participant

    Hello Jeremy,
    thank you very much. I had checked those parentheses but never double-checked them because I expected the whole script to throw an error if there was something off there. I put the parentheses in the right spot and it works as expected now.
    Matthias

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