Jeremy

Forum Replies Created

Viewing 15 posts - 496 through 510 (of 1,522 total)
  • Author
    Posts
  • in reply to: html layout/event times/selector vs. scale/ compatibility #7978
    Jeremy
    Keymaster

    Hi,

    The code of the blank function you report seem to be missing a few lines, but if I understand its purpose correctly, you can rewrite it in a more concise way, eg:

    blank = sentence => Object({html: 
        sentence.replace(/_+/g, (t,i)=>`<textarea name='blank${i}' rows=1 cols=${t.length+1} style='max-height: 1.7em'></textarea>`)
    });

    Then you can use it the way you discuss, either creating a Form item using the standard Ibex syntax:

    items = [
        ["blank", "Form", blank("It was so ea__ to get lost in an anc__ buil____")]
    ]

    Or injecting a Form controller inside a PennController trial:

    newTrial("blank", 
        newController("Form", blank("It was so ea__ to get lost in an anc__ buil____"))
            .log()
            .print()
            .wait()
    )

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7975
    Jeremy
    Keymaster

    Hi Larissa,

    One issue is that you have at least one case where the log command of the Key element is missing "all" (at least in the current code at https://farm.pcibex.net/r/XSJAnP/, where it concerns the trials labeled “trial_1_no_cue_DOWN”)

    In the absence of a keypress, the line will have Key as its parameter instead of PressedKey, NA as its value and Never in the EventTime column. So filter(Parameter %in% c("Key","PressedKey")) %>% will exclude those lines where the participant never pressed a key. Try replacing it with filter(Parameter %in% c("Key","PressedKey","Key")) %>%

    I’m not sure how to handle the block issue for now. You are correct: having NAs in place of timestamps messes with the block column and will assign block 0 to those NA rows. One solution would be to use the linear order of the rows to assign blocks rather than just the EventTime column, but I can’t think of an immediate way of doing it off the top of my head

    Jeremy

    in reply to: multiple "success" or "failure" feedback options #7966
    Jeremy
    Keymaster

    Hi Sharon,

    Just refer to the column of your table in the test command:

    Template( "table.csv" , row =>
      newTrial(
        newText("Press A or B").print()
        ,
        newKey("AB")
          .wait()
          .test.pressed( row.Correct )
          .success( newText("Correct, the answer is "+row.Correct+"!").print() )
          .failure( newText("No, the answer was "+row.Correct+".").print() )
        ,
        newButton("Next").print().wait()
      )
    )

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7963
    Jeremy
    Keymaster

    Yes: if you want to reset both Var elements before going back to the beginning of the p_trial sequence of trials, you need to call set on both before jump in the callback command

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7960
    Jeremy
    Keymaster

    The Var element named “practiceRTs” (which is the one you brought up in your messageEDIT: my bad, the lines of code that refer to that element in your message actually concern another question) keeps track of reaction times, not of accuracy. You need to reset the Var element that keeps track of accuracy too

    Jeremy

    • This reply was modified 3 years, 4 months ago by Jeremy. Reason: correction
    in reply to: Can we randomize time with newTimer() ? #7957
    Jeremy
    Keymaster

    Hi Larissa,

    The math sounds good to me too: the max duration of timer-D1 is 1600ms, then timer_cue_D2 is 100ms and timer_D3 is 400ms, the max (effective) duration of timer-RT is 1700ms, and you add the 2000ms duration of wait-success, which gives you a max total of 5800ms, so by the time your script reaches getTimer("wait-separacao").wait() it will still still have at least 200ms to wait (or more, if timer-D1 was shorter and/or the participant pressed a key before the end of the 1700ms of timer-RT)

    You need to place newVar("practiceRTs").global().set( [] ) , before before jump(startsWith("p_trial")) in the callback command, not before newButton, but I forgot to include .global() in my message above, so mea culpa

    Jeremy

    in reply to: referring to PCIbex code in separate files #7956
    Jeremy
    Keymaster

    Hi,

    Just create another .js script under Scripts, and start coding there. When the experiment is run, the files in Scripts are concatenated into a single .js file, in an alpha-numeric order, ie. the content of main.js will come after the content of abc.js, so place PennController.ResetPrefix(null) at the top of the first script file (or at the top of all script files would work too)

    It doesn’t matter which file your Sequence command is in, it will see all the trials you create from all the .js files in Scripts

    Jeremy

    in reply to: Different sequence for group? #7952
    Jeremy
    Keymaster

    Hi,

    Use __counter_value_from_server__ to conditionally execute different Sequence commands:

    if (__counter_value_from_server__ % 2)
      Sequence( "Consent",  "block1Instructions", rshuffle("block1"), "block2Instructions", rshuffle("block2"), "block3Instructions", rshuffle("block3"), "block6Instructions", rshuffle("block6"), "block7Instructions", rshuffle("block7"), "block4Instructions", rshuffle("block4"), "block5Instructions", rshuffle("block5"), SendResults() , "Thankyou" )
    else
      Sequence( "Consent",  "block1Instructions", rshuffle("block1"), "block2Instructions", rshuffle("block2"), "block3Instructions", rshuffle("block3"), "block4Instructions", rshuffle("block4"), "block5Instructions", rshuffle("block5"), "block6Instructions", rshuffle("block6"), "block7Instructions", rshuffle("block7"), SendResults() , "Thankyou" )

    Template executes its function after the core of the script, so the Var element “blockorder” will not have received its value by the time your if is executed. Also, getVar("blockorder") returns a pointer to the javascript object that represents the Var element, which PennController knows how to interpret, but if you just reference it inside an if like that, you won’t get what you think (ie. you won’t get "A" or "B"). How-to guide: Using JavaScript

    Jeremy

    in reply to: html layout/event times/selector vs. scale/ compatibility #7951
    Jeremy
    Keymaster

    Hi,

    I’m not sure I’m following everything, but and does not mean “and do something else,” it is used to write a conjunctive test: reference

    The commands success and failure accept subsequences of commands, separated by commas just like the main sequence of commands, eg:

    .test.selected({ V: getImage("inappropriate"), B: getImage("infelicitous"), N: getImage("appropriate") }[variable.Right_Key])
    .success( 
      getVar("exp_score").set(s_exp=>s_exp+1)
      ,
      getVar("item_score").set(sc_i=>sc_i+1)
    )

    And yes, it is possible to have multiple test commands on the same element:

    .test.selected({ V: getImage("inappropriate"), B: getImage("infelicitous"), N: getImage("appropriate") }[variable.Right_Key])
    .success(
      getVar("exp_score").set(s_exp=>s_exp+1)
      ,
      getVar("item_score").set(sc_i=>sc_i+1)
    )
    .test.selected(getImage("inappropriate")).success( getVar("v_score").set( v=> v+1 ) )
    .test.selected(getImage("infelicitous")).success( getVar("b_score").set( v=> v+1 ) )
    .test.selected(getImage("appropriate")).success( getVar("n_score").set( v=> v+1 ) )

    Note that in this example I assume you have created the Var elements named v_score, b_score and n_score earlier

    Feel free to share a link to your experiment with me if you’d like more assistance, so I can see the code as is, in context

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7949
    Jeremy
    Keymaster

    Hi Larissa,

    This should work:

    Template("tabela-target.csv" , row => 
      newTrial("trial_2_center_cue_UP",
        defaultText
            .center()
            .bold()
            .cssContainer({"position": "absolute",
                           "top": "50%",
                           "left": "50%",
                           "transform": "translate(-50%, +50%)",
                           "font-size": "100px",
                           "margin-top": "1em"})
            .print()
        ,
        newText("D1", "+").color("blue")
        ,
        newVar("timer-D1-duration").set( 400+Math.round(1200*Math.random() ) )
        ,
        newTimer("timer-D1", 1).set( getVar("timer-D1-duration") ).start().wait()
        ,
        getText("D1").remove()
        ,
        newText("cue", "*").color("green")
        ,
        newTimer("timer_cue_D2",100).start().wait()
        ,
        getText("cue").remove()
        ,
        newText("D3", "+").color("pink")
        ,
        newTimer("timer_D3",400).start().wait()
        ,
        getText("D3").remove()
        ,
        newVar("newTimerDuration").set( v=>Date.now() )
        ,
        newTimer("timer-RT",1700).start()
        ,
        newText("cruz_central", "+").color("black")
        ,
        //para cima//
        newCanvas("center", 500,200)
            .add( "center at 50%" , "center at 50%" , newImage("imagens", row.imagem).size(500, 200) )
            .log()
            .print("center at 50vw", "top at 85px")
        ,
        newKey("keypress1","SK")
            .log("all")
            .callback( getTimer("timer-RT").stop() )
        ,
        getTimer("timer-RT").wait()
        ,
        getVar("newTimerDuration").set( v=> 3500 - getVar("timer-D1-duration").value - (Date.now()-v) )
        ,
        newTimer("wait-separacao", 1).set( getVar("newTimerDuration") ).start()
        ,
        getKey("keypress1").disable(),
        getText("cruz_central").remove(),
        getCanvas("center").remove()
        ,
        newText("separacao", "+").color("yellow")
        ,
        getTimer("wait-separacao").wait()
      )
      .log("imagens", row.imagem)
      .log("item", row.versao)
    )

    Feel free to edit the command on the Canvas element .print("center at 50vw", "top at 85px") if the image does not appear where you would like it to appear (I suspect that you want instead is "middle at 50vh" in place of "top at 85px", but it’s your call)

    I have tested this with one trial twice, and the total duration of the trial was around 4040ms both times

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7944
    Jeremy
    Keymaster

    The issue I’m raising in my previous message means one needs to revise the approach if one wants to use the Var method. I can’t spend more time on this today, but feel free to look for an alternative method yourself

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7939
    Jeremy
    Keymaster

    400+1200=1600, but 400+1600=2000. I was under the impression that you wanted a random duration between 400ms and 1600ms, not between 400ms and 2000ms

    Also, I’m just realizing that I reference that variable in a function in .set on the Var element, and because timerd1duration is set in a Template environment, by the time the function from set is executed it will always have the value it got in the last generated trial, so my code won’t have the desired outcome. More details on the timeline of javascript code injection on this page

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7937
    Jeremy
    Keymaster

    If you’re referring to the code from this message, it’s not a full code: it’s a streamlined excerpt of your code to which I added the relevant bits to use the Var method

    timerd1duration = 400+Math.round(1200*Math.random()) creates a javascript variable named timerd1duration that will store the generated random value (which, in the code from my message, I use when creating the Timer element named timer-D1 and when calculating the duration of the last Timer element). I took getText("D1").remove() directly from your code, it’s your call to keep it or not, depending on what you want to happen at that time in the trial

    If you use newTimer("timer-D1",400+Math.round(1600*Math.random())) then there’s no point in using timerd1duration = 400+Math.round(1200*Math.random()). You also will get a duration between 400ms and 2000ms (because 400+1600=2000). "timer-D1" is a string (as you can tell by the double quotes) so you don’t want to include that in an arithmetic operation

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7933
    Jeremy
    Keymaster

    Add newVar("practiceRTs").set( [] ) , before jump(startsWith("p_trial")) to reset the Var element, and yes, if you drop /1000 you will have a value in seconds rather than in milliseconds

    Jeremy

    in reply to: Can we randomize time with newTimer() ? #7930
    Jeremy
    Keymaster

    It’s hard to tell, one would have to run a few tests using each method and proceed to comparisons, but my guess would be that, under normal circumstances (ie good performance) the delays associated with the Var method probably shouldn’t exceed a couple tens of milliseconds

    Jeremy

Viewing 15 posts - 496 through 510 (of 1,522 total)