Jeremy

Forum Replies Created

Viewing 15 posts - 436 through 450 (of 1,522 total)
  • Author
    Posts
  • in reply to: Switching between multiple tasks #8144
    Jeremy
    Keymaster

    Hello,

    In the demo that you shared, there is a single newTrial which includes both task types. It is my understanding from what you said (that two tasks of the same type can follow each other) that you want to decouple the two, ie. not have them inside a single newTrial command. That would also mean no longer associating specific sentences with specific sets of flanker images the way your table is currently set up. The most convenient way to start on that would be to use two different CSV tables for each task type

    Then you can create different newTrials inside different Template commands, giving different labels to trials of each task type. Once you have such labeled trials, you can define a custom predicate function to shuffle your trials as you’d like, for example:

    const popAelseB = (a,b) => a.pop()||b.pop()
    function LatinMix(a, b) {
        this.args = [a,b];
    
        this.run = function(arrays) {
            assert(arrays.length == 2, "Wrong number of arguments (or bad argument) to LatinMix");
            let as = arrays[0];
            let bs = arrays[1];
            let newArray = [];
            let i = 0;
            while (as.length || bs.length){
                newArray.push( [
                    i%2 ? popAelseB(as,bs) : popAelseB(bs,as),
                    (i+1)%4<2 ? popAelseB(as,bs) : popAelseB(bs,as)
                ] );
                i++;
            }
            fisherYates(newArray);
            return newArray.flat();
        }
    }
    function latinMix(a, b) { return new LatinMix(a, b); }

    You can use the function in Sequence like this:

    Sequence( latinMix(randomize("sentence"),randomize("flanker")) )
    
    Template("flanker.csv", row => newTrial("flanker", /* ... */ ) )
    Template("sentence.csv", row => newTrial("sentence", /* ... */ ) )

    Jeremy

    in reply to: Unable to randomize fillers and experimental items #8139
    Jeremy
    Keymaster

    Hi,

    The experiment runs the fillers as a separate list because your table has three different values in the LIST column: A, B and .

    What I would do is store the function you pass to Template in a variable, create two different CSV tables for the experimental items (with a LIST column) and for the filler items (without a LIST column) and then use Template twice, once on each CSV table

    experimental.csv:

    ITEM,SENTENCE,COMPATIBILITY,SUBJECT,LIST,TYPE
    101,Sentence 1,1,subject1,A,item
    201,Sentence 2,1,subject1,B,item
    102,Sentence 3,2,subject2,B,item
    202,Sentence 4,2,subject2,A,item

    fillers.csv:

    ITEM,SENTENCE,COMPATIBILITY,SUBJECT,TYPE
    501,Filler 1,.,.,filler
    502,Filler 2,.,.,filler
    503,Filler 3,.,.,filler

    Example of a script:

    function_for_template = row => newTrial( row.TYPE ,
      newText( row.SENTENCE ).print()
      ,
      newScale("answer", "True", "False").button().print().log().wait()
    )
    .log("item", row.ITEM)
    .log("compatibility", row.COMPATIBILITY)
    .log("subject", row.SUBJECT)
    .log("list", (row.LIST===undefined?"filler":row.LIST))
    
    Template("experimental.csv", function_for_template)
    Template("fillers.csv", function_for_template)

    Jeremy

    in reply to: Continuous Sliding Scale #8134
    Jeremy
    Keymaster

    Hi,

    If what you want is provide the user with 7 points visually, you could do that (replace the two occurrences of 10em with whatever width you prefer):

    newText("<span>1</span><span>2</span><span>3</span><span>4</span><span>5</span><span>6</span><span>7</span>")
        .css({display:"flex", "justify-content": "space-between"})
        .size("10em","auto")
        .center()
        .print()
    ,
    newScale(100).size("10em","auto").slider().center().log().print()

    Then in your analyses, you can simply multiply the score by 0.07 and round it if you like

    Jeremy

    in reply to: Prevent long stimuli from splitting in two lines #8133
    Jeremy
    Keymaster

    Hi Daria,

    You can remove .css("white-space","nowrap") and add this to Aesthetics/global_main.css instead:

    .PennController-nowrap .FlashSentence-flashed-sentence, .PennController-nowrap .DashedSentence-sentence {
        white-space: nowrap;
    }

    This will apply the CSS rule to the sentence in your controller as long as you name the element "nowrap":

    newController("nowrap", "AcceptabilityJudgment", {
        s: row.sentence,
        as: ["1", "2", "3", "4", "5", "6", "7"],
        presentAsScale: true,
        leftComment: "Плохо", rightComment: "Хорошо",
        timeout: 10000
    })
        .center()
        .print()
        .wait()
        .log()
        .remove()

    Jeremy

    Jeremy
    Keymaster

    Dear Larissa,

    Both solutions use the same set of four labels, namely "A", "B", "C" and "D"

    The first piece of code creates a total of 100 trials: 70 A trials, 10 B trials, 10 C trials and 10 D trials. The text of the button in the first A trial is “A0”, in the second A trial it is “A1”, etc. and similarly for the “B” trials (“B0”, “B1”, etc.), the “C” trials and the “D” trials

    The second piece of code creates a total of 4 trials: 1 A trial (button text: “A”), 1 B trial (button text: “B”), 1 C trial (button text: “C”) and 1 D trial (button text: “D”). However, the Sequence repeats the A trial 70 times, the B trial 10 times, the C trial 10 times and the D trial 10 times

    Both pieces of code use shuffle in Sequence, resulting in a balanced distribution in both cases

    Jeremy

    Jeremy
    Keymaster

    Hi,

    Using shuffle in the sequence will “specif[y] that items matching the given predicates should be shuffled together in such a way that items matching each predicate are evenly spaced. The original relative ordering between items of the same type is preserved.”

    For example, the following will get as close as possible to separate two B, two C and two D trials with 9 other trials in between, but A trials won’t be separated by more than ~2 trials overall, because of the proportions of trials

    Sequence(shuffle("A","B","C","D"))
    
    for (let i = 0; i<70; i++)  newTrial("A", newButton("A"+i).print().wait())
    for (let i = 0; i<10; i++)  newTrial("B", newButton("B"+i).print().wait())
    for (let i = 0; i<10; i++)  newTrial("C", newButton("C"+i).print().wait())
    for (let i = 0; i<10; i++)  newTrial("D", newButton("D"+i).print().wait())

    That's if you have 4 different labels, and actually create 70/10/10/10 trials. But if you only create a total 4 trials, but want to repeat them following a 70/10/10/10 distribution, you could do that:

    Sequence(shuffle(
        ...[...new Array(70)].map(v=>"A"),
        ...[...new Array(10)].map(v=>"B"),
        ...[...new Array(10)].map(v=>"C"),
        ...[...new Array(10)].map(v=>"D"),
    ))
    
    newTrial("A", newButton("A").print().wait())
    newTrial("B", newButton("B").print().wait())
    newTrial("C", newButton("C").print().wait())
    newTrial("D", newButton("D").print().wait())

    Does that answer your question?

    Jeremy

    in reply to: Prevent long stimuli from splitting in two lines #8126
    Jeremy
    Keymaster

    Hi,

    You could use .css("white-space", "nowrap")

    Also, I see in your code that you have defaultText.css("font-size", "80") but then you don’t create any Text element, instead you use Controller elements to display content: the css command won’t affect those elements. You can try calling .css("font-size", "80") on each Controller element

    Besides, you might want to edit Aesthetics/PennController.css to change width: 40em !important; to width: 60em !important; for example (you would then need to change margin-left: calc(50vw - 20em); to margin-left: calc(50vw - 30em); to keep the content centered)

    Jeremy

    in reply to: Blank spaces before content in HTML files #8123
    Jeremy
    Keymaster

    Hi Jack,

    I would recommend reserving the data-collection link for actual participants, otherwise you might end up with noise submissions from test runs mixed in with valuable submissions from actual participants. The recommended link to share is the demonstration link, which comes with the debugger and a link to edit a copy of the project, which I need to troubleshoot issues. I did look up the database and fetched the demonstration for your project, but you might want to edit your message to not circulate the data collection link

    Regarding the formatting issues, it’s coming from the fact that your HTML document is written as a standalone document, whereas it is actually injected as a part of another document when you include it in your experiment. More specifically, your HTML document contains a body node and applies CSS rules to all h1, header, p, div, etc. nodes in the document, which will necessarily also target those outside your HTML document, ie. including the nodes introduced by IBEX and PCIbex

    What you can do is delete the first 5 lines of your HTML document (from <!DOCTYPE html> through <title>Passage One</title>) as well </html> at the very end. Then replace <body> with <div class="thisDocument"> and </body> at the end with </div>. Finally, prepend every selector in the CSS rules with .thisDocument, eg replace h1 { font-size: 2em; } with .thisDocument h1 { font-size: 2em; } and h2, h3, h4 { font-size: 1.5em; } with .thisDocument h2, .thisDocument h3, .thisDocument h4 { font-size: 1.5em; }, etc. Also make sure to replace body { with .thisDocument { in those rules

    You should be good once you proceed to those edits

    Jeremy

    in reply to: Controller or Timer conditional #8121
    Jeremy
    Keymaster

    Hi Erin,

    There are two issues with the code above: 1) the Timer element is not started, so it will be waited for forever, and 2) there seems to be a bug in the callback command of the Controller element!

    So you’ll need to work around the Controller element’s callback command. Here’s a suggestion, which consists in placing a wait command inside another callback command (this time, a bug-free one, called on a Timer element) so that wait does not block the main thread of execution:

    newTrial("trial-1", 
        defaultText
            .center()
            .print()
        ,
        newAudio("llego-profesora", "La_profesora_llegó_a_la_clase_en_la.mp3")
            .play()
        ,
        newText("llego-profesora-t", "La profesora llegó a la clase en la momento preciso.")
            .center()
            .unfold(3650)
        ,
        getAudio("llego-profesora")
            .wait("first")
        ,
        newTimer("hurry", 3000).start()
        ,
        newTimer("dummy", 1)
            .callback(
                newController("AcceptabilityJudgment", {
                    q: "¿Es esta oración aceptable?",
                    s: "",
                    as : ["SÍ", "NO"], 
                    instructions : "Haz clic, SÍ o NO",
                    presentAsScale : true,
                    leftComment : "es aceptable",
                    rightComment : "no es aceptable"
                })
                    .center()
                    .print()
                    .log()
                    .wait()
                ,
                getTimer("hurry").stop()
            )
            .start()
        ,
        getTimer("hurry").wait()
    )

    Jeremy

    in reply to: Blank spaces before content in HTML files #8119
    Jeremy
    Keymaster

    Hi Jack,

    It’s a little hard to tell out of context. Do you have a link to your experiment that you could share, here or at support@pcibex.net?

    Jeremy

    in reply to: Unable to access server files #8116
    Jeremy
    Keymaster

    Hi Rhosean,

    When I open your certificate, I get these validity dates:

    Validity
    
    Not Before    Sun, 23 Jan 2022 05:41:45 GMT
    Not After     Sat, 23 Apr 2022 05:41:44 GMT

    I’m not sure where the discrepancy lies, but maybe you could try to manually force a certificate refresh on DreamHost?

    Jeremy

    in reply to: Unable to access server files #8113
    Jeremy
    Keymaster

    Hi Rhosean,

    There is a problem with your domain: when I try to open https://www.rhosean.xyz/nsfSESresults/resources/APIMaudio.zip directly in my browser, I get a “Warning: Potential Security Risk Ahead” message. Most likely your SSL certificate has expired. Renew your certificate and the problem should go away

    Jeremy

    in reply to: Continuous Sliding Scale #8111
    Jeremy
    Keymaster

    Hi Larissa,

    True continuity doesn’t really exist in the digital world (does it even exist in the non-digital world?) 😉

    Use a high value for the number of points, eg. 1000: newScale(1000).slider().print()

    Jeremy

    Jeremy
    Keymaster

    Hi Radim,

    FlashSentence and AcceptabilityJudgmentSentence do not introduce a node with a class name of the form CONTROLLERNAME-sentence the way DashedSentence does, but of the form CONTROLLERNAME-flashed-sentence. So do this instead:

    .FlashSentence-flashed-sentence {
        font-size: 30;
    }
    .DashedSentence-sentence {
        font-size: 30;
    }
    .AcceptabilityJudgment-flashed-sentence {
        font-size: 30;
    }

    Jeremy

    in reply to: Implementing test recording #8108
    Jeremy
    Keymaster

    Hi Dod,

    Yes, whichever method you use, one MediaRecorder element means one audio file, containing the most recent recording — you should try it out yourself though to double-check. Zip files containing recordings have non-related, unique filenames and may contain one or more recordings (because trials can contain several MediaRecorder elements, and uploads can take place after several trials too) but the audio files in the zip files are indeed named after the name of the MediaRecorder

    Jeremy

Viewing 15 posts - 436 through 450 (of 1,522 total)