Larissa_Cury

Forum Replies Created

Viewing 15 posts - 16 through 30 (of 92 total)
  • Author
    Posts
  • in reply to: Get the previous row of a column #10642
    Larissa_Cury
    Participant

    We have to erase the counter if the answer is right in case a participant get 1 error followed by a correct answer (which is allowed), not in case we have two sequential errors, I wrote it wrong above.

    My attempt in Pcibex was this, but I got stuck…

    
    // CREATE an error count outside "loop" so that it doesn't gets erased whenever a trial starts 
    let errorNum = 0;
    
    Template("newStimuliShort.csv", row =>
      newTrial("listOfNumbers",
      defaultText
      .cssContainer({
               padding: '0.5em',
              'text-align': 'center',
              "justify-content": 'center',
              "align-items": 'center' ,
              'font-size': '50px',
            })
            .center()
            .print()
    ,
        newMediaRecorder("recorder", "audio").log().record()
      //  ,
      //  newTimer("recording", 60000).log().start()
       ,
        newText("words", row.sequence) // Display sequences 
      ,
        newAudio("audio", row.audio)  // play corresponding audio (which is in Portuguese) 
                .play()
        ,
        getAudio("audio").wait("first") // wait audio finishes
        ,
        newAudio("beep", "beep.mp3") 
                .play()
        ,
        getAudio("beep").wait("first") // wait audio finishes
        ,
        newVar("currLen").set(row.lenNumeric) // get current i length of "sequence" 
        ,
         newKey("NEXT", "SK")
                .wait()
                .log()
        ,
         getKey("NEXT")
         .disable() // make sure we only have 1 answer - participant can only answer once
        ,
         getKey("NEXT")
         .test.pressed("S")
          .success(                          
          newText("success", 'yey'),   // if the answer is right, 
          getVar("errorNum").set(0))   // make sure to erase the error count in case a participant get 1 error followed by a correct answer 
        .failure(
            
        newVar("errorCount").set( errorNum + 1)  // Increase error count by 1 ans store it in a variable called 'errorCount' 
        ,
    
        // I would need sth here to store the errors so that k + k generates errorCount = K , then I guess I could use .testIs() to see if errorCount === 2. If yes, then 
                  we should check if the current length equals the last length and break the experiment in case it's TRUE. Otherwise just erase the error count again and the 
              experiment continues
              
      // newText("lastLen", row.lenNumeric).map((w,i) => <code>${w[i - 1]}</code>) // get the last length ---- COULDN'T DO IT!! 
        
    //    ,
        newText("failure")
        //    .text( getVar("errorCount") ) // I was displaying just to see if it was working
            .text(getVar("errorCount")) // I was displaying just to see if it was working
            .cssContainer({"font-size":"30px", "text-align":"center", "margin-top":"255px","font-family":"Comic Sans MS", "color":"red","white-space":"nowrap"})
    
    )
    ,
        newTimer("wait-success",100) //timer for the success or failure messenge
        .start()
        .wait()
    ,
        getText("success")
        .remove()
    ,
        getText("failure")
        .remove()
        // ,
        // getTimer("recording").wait()
        ,
        getMediaRecorder("recorder").stop()
     )
      );
    

    PS: I tried to use 0 and 1 instead of letters for the keypress, but I couldn’t do it. I guess it was interpreting 0 and 1 as strings, not numbers, how would I overcome that as well ?

    • This reply was modified 11 months, 2 weeks ago by Larissa_Cury. Reason: forgot to put block code
    in reply to: How to make keypress add a CSS class to text #10639
    Larissa_Cury
    Participant

    All right! Thank you very much for taking the time to explain that to me!

    in reply to: How to make keypress add a CSS class to text #10633
    Larissa_Cury
    Participant

    Hi, Jeremy! Things are much clearer now, thank you!!

    I’ve read the documentation link you’ve sent me, thanks, but I’m still wondering about one thing:

    If in the doc’s example, newText("dots", "...").print()

    
    .dots {
      text-decoration: underline;
    }
    
    

    equals

    
    newText("dots")
        .css("text-decoration","underline")
        .print()
    

    Then how come the the separed .css manipulation for “words” in the separed file be different from the one we have with the .css in the code? From what I got from the doc, the .css in the code points to the element itself (in the ex case, “dots”, in my case “word”), right? Hence, how can the separed one refer to all individual span classes and the .css one refer to all span classes, shouldn’t they both point to “words” ? (the element to each they’re attached to) ?

    in reply to: How to make keypress add a CSS class to text #10629
    Larissa_Cury
    Participant

    Hi, @Jeremy! Can you help me walk through it?

    # PART 1:

    
    // embed each word in a span, highlight the very first one
    newText("words", row.Words.split('_').map((w,i)=><code><span class='word ${i==0?'highlighted':''}'>${w}</span></code>).join(''))
    

    1) We create newText called “words” which gets each word from the cell. All words are separated by “_”, hence, “a word” equals “a string separed by _”, which is what split(”) is doing
    2) Involve the words in a span HTML class (I’m a bit confused here, but I guess it is to show the words in a box-like way?)
    3) the map function gets the current element (each word (w)) and the current index (i). The condition says “if the current index equals 0, add the highlighted class to .word otherwise, just print the word {w}, which just has the class .word
    4) Join the words back together in a string separed by the empty string

    # part 2:

    
    .cssContainer("width","810px") // 3 times the space reserved for each word + horizontal padding
    .css({
            display: 'flex',            // items contained in the element will be rearranged smartly
            'flex-direction': 'column', // stack items in columns 
            'flex-wrap': 'wrap',        // items that overflow vertically will start on new columns
            'font-size': '50px',
            height: '210px'             // more than 3 times the space reserved for each word + vertical padding
        })
        .print()
    

    I was a bit confused here with the two css elements, the .cssContainer and the .css. At first, I supposed that the .cssContainer would modify the NewText element and the .css would modify the .word or .word highlighted classes, but if I change the font-size, it changes the fontsize of the text element, so I guess I’m wrong. Hence: Why do we have both .css and .cssContainer here?

    Second question: “3 times the space reserved for each word + horizontal padding”. I couldn’t figure out waht “the space reserved for each word” means. Are we talking about the specifications in the .word class in the css file? (if yes, what is precisely the “space” reserved? the padding?)

    # PART 3:

    
    newVar("listOfWords", ""), // we'll update this Var element with the list of words tagged as desired
    newVar("highlightedWord").set(0) // this is the index of the highlighted word
    ,
    newKey("NEXT", " ")
        .callback(
            // first make sure that the next index is within bounds
            getVar("highlightedWord").test.is(v=>v+1<row.Words.split('_').length).success(
                getVar("highlightedWord").set(v=>v+1) // increment the index of the highlighted word
                ,
                getVar("listOfWords") // update listOfWords with appropriate tags
                    .set(getVar("highlightedWord")) // first look up the index
                    .set(v=>row.Words.split('_').map((w,i)=><code><span class='word ${i==v?'highlighted':''}'>${w}</span></code>).join('')) // now set the class as desired
                ,
                getText("words").text( getVar("listOfWords") ) // update the content of the Text element
            )
        )
    

    1) I didn’t get the ‘check’ logic: getVar(“highlightedWord”).test.is(v=>v+1<row.Words.split(‘_’).length).success() ? Shouldn’t we test if i === 0 ? why then v + 1 ?
    2) Ok, we increment the word index by one (to move on to the next word)
    3) I get this part: .set(v=>row.Words.split('_').map((w,i)=><span class=’word ${i==v?’highlighted’:”}’>${w}</span>).join('')) // now set the class as desired
    if the current word is === v, then add the highlight class, otherwise, just print the w , right?

    But I can’t understand the 2 lines before it.
    4) we have to update the textElement, so we update the content of ‘words’ with the ‘list of words’ one.

    # Questions about the styling:

    I also didn’t quite understand what css was updating what element, if I got it right, then:

    # Updates the ‘words’ in general (all words) – then, why do we need the cssContainer back there?

    
    .PennController-words .word {
        width: 230px;
        height: 60px;  
        padding: 5px 15px; # around each word
    }
    

    .word.highlighted this is ok, this is the highlighted class 🙂

    When you mentioned “you could do 12 words as in your example too, just adjust the widths and heights accordingly to fit 4×4 words” which height and weight were you refering too? I changed the height of the .css (originally 210pc), but I don’t know if that was the right place to do so?

    Sorry for the long post, I started learning ‘raw’ Js and now I guess I’m a little bit more able to understand PciBex code better, I really would like to understand it. Thanks in advance!

    in reply to: How to make keypress add a CSS class to text #10617
    Larissa_Cury
    Participant

    Thank you VERY much, Jeremy! I have a few questions, but I’ll work on my own to try to solve them or to come up with more elaborated questions. Thank you very much, this is amazing!

    in reply to: How to make keypress add a CSS class to text #10612
    Larissa_Cury
    Participant

    To illustrate it:

    # Suppose >< represents a CSS border class to highlight the words:

    1) Display n columns of words on the screen at the same time as the words are displayed in the csv file
    2) Highlight the first word (I thought of a CSS class to do it)
    3) When participant hits spacebar, the highlight goes to the next word below

    >Jason< Raheema Chassity
    Oscar Bryce Carlito
    Maleeka Nasreen Maureene
    Janet Hishaam Chidiebere

    PRESS SPACEBAR:

    Jason Raheema Chassity
    >Oscar< Bryce Carlito
    Maleeka Nasreen Maureene
    Janet Hishaam Chidiebere

    4) When the participants finishes the columns, the highlight class moves up to the first word of the next column

    Jason Raheema Chassity
    Oscar Bryce Carlito
    Maleeka Nasreen Maureene
    >Janet< Hishaam Chidiebere

    PRESS SPACEBAR

    Jason >Raheema< Chassity
    Oscar Bryce Carlito
    Maleeka Nasreen Maureene
    Janet Hishaam Chidiebere

    in reply to: Displaying n words on screen #10591
    Larissa_Cury
    Participant

    Hi, @Jeremy! Thank you very much! Could I add a key press too? For example, other than ” ” ? “If you finish before 1min, press K”, for ex? using the same logic with failure

    • This reply was modified 12 months ago by Larissa_Cury. Reason: edit question
    in reply to: Help with recording audio? #10590
    Larissa_Cury
    Participant

    Hi, Jeremy! Thank you very much!

    in reply to: Displaying n words on screen #10586
    Larissa_Cury
    Participant

    Hi, @Jeremy! Thank you very much! Let me ask you something, in case the participant finishes before 60min (which I don’t think will happen, but I have to think about it too, right), can I add a keypress to scape the time?

    PS: I’ve made sure that the index is within bounds doing this in R: https://stackoverflow.com/questions/76244042/how-to-insert-strings-so-that-every-row-has-the-same-pattern?noredirect=1#comment134453942_76244042 🙂

    Thank you once more! It’s working perfectly!

    in reply to: Displaying n words on screen #10579
    Larissa_Cury
    Participant

    I’m trying to come up with a way to loop over the table and dynamically set getText("words").text( row.Column2.split('_').join("<br>") ) so that it displays row.Column{n} as the dataset have, where n is the number of cols in the table and the index of each interation, but I’m really struggling with that, I don’t know if that would be the right way to achieve what I’m trying to achieve above…

    • This reply was modified 12 months ago by Larissa_Cury. Reason: additional comments
    in reply to: Help with recording audio? #10577
    Larissa_Cury
    Participant

    I tried to add a sequence element, https://farm.pcibex.net/r/AqPhcF/ . I guess it worked! 🙂 Is there a better way, tho? I don’t think I can manipulate any of these messages, right?

    in reply to: Help with recording audio? #10576
    Larissa_Cury
    Participant

    Hi, @Jeremy! Considering the error message, is is possible to put a trial before that?
    My idea was: If I cannot change the text, then I’ll display a warning to the kid “Please, wait your teacher”, so that the kid/participant calls the teacher, who will press S and then the message shows up. I tried to do it like this, but the order isn’t changing:

    
    // 👉  Experimental trial: 
    
    Template("new--Items_Wide.csv", row =>
      newTrial("listOfWords",
        fullscreen() //enable full screen
        ,
        newMediaRecorder("recorder", "audio").log().record()
        ,
        newTimer("recording", 3000).log().start()   // Start the timer now
        ,
        newText("words", row.Column1.split('_').join("<br>")) // separate each word with a <br> tag (new line)
            .cssContainer({
               padding: '0.5em',  // add some to not get too close to the border
              'text-align': 'center',   // trying to make the words center on fullscreen -- NOT WORKING :(
              "justify-content": 'center',
              "align-items": 'center' ,
              'font-size': '50px',
            })
            .print()
        ,
        newKey("NEXT", " ")
            .callback(  // use a callback to execute this in parallel to waiting for the timer
                getKey("NEXT").remove() // remove the NEXT button
                ,
                getText("words").text( row.Column2.split('_').join("<br>") ) // update the displayed list of words
            )
            .print()
            // do not wait for a click, otherwise the timer might elapse before the click
        ,
        getTimer("recording").wait() // wait for the timer to end
        ,
        getMediaRecorder("recorder").stop()
        ,
        getKey("NEXT").remove() // make sure to remove the button, in case the participant didn't get to the second list
        ,
        getText("words").remove()
        ,
        newText('time-is-up-msg', "Time is up!").print()
        ,
        newButton('btn--finish--game', 'Finish Game').print().wait()
      )
    );
     
    // 👉 Completion screen -- WAIT THE TEACHER ///////////////////////////////////////// HERE
    newTrial("completion_screen",
    // Exit fullscreen:
    
    exitFullscreen()
    ,
    // Print thank-you msg: 
    
        newText("thankyou-msg", "Good job, now wait your teacher!")
            .center()
            .print()
        ,
        newKey("NEXT", "S")
        // ,
        // newButton("void", "")
        //     .wait()
    );
    
    // 👉 Send results:
    
    SendResults();
    
    // 👉 Check if promise is fullfilled
    // 👉 Manually reject promise => insert dummy link 
    // 👉 Store audio locally
    
    newTrial(
        newFunction("check upload", ()=>PennController.uploadRecordingsError)
            .test.is()
            .success(
                newText("confirmation", "The recordings were sent to the server. ")
                    .print()
            )
            .failure(
                newText("error", "Click on the link below to store data 👇")
                    .color("red")
                    .print()
            )
        // ,
        // newText("download-manually-msg", DownloadRecordingButton("Click here to download an archive of your recordings.") )
        //     .print()
        // ,
        // newTimer("inifinite", 0)
        //     .wait()
    );
    
    
    in reply to: Displaying n words on screen #10573
    Larissa_Cury
    Participant

    Hi, @Jeremy! [EDIT – UPDATE] I can display the words one below the other and the time seems to be ok (the whole trial is lasting the amount of time and not reseting time), but I’d like to avoid hard-coding this part:

    
     newButton("NEXT", "Next words!")
            .callback(  // use a callback to execute this in parallel to waiting for the timer
                getButton("NEXT").remove() // remove the NEXT button
                ,
                getText("words").text( row.Column2.split('_').join("<br>") ) // update the displayed list of words
            )
            .print()
            // do not wait for a click, otherwise the timer might elapse before the click
        ,
    

    A) I’d like to be able to have *n* columns as I want displayed dynamically based on the dataframe number of cols in the wide version. Otherwise, I’ll have to hard-code this part *n* times according to the amount of cols of my dataframe.
    B) Or, in the long version, I’d like to be able to print as many rows as I want, instead of hard-coding each interval manually.

    Is there a way to do acheive either a or b? https://farm.pcibex.net/r/AqPhcF/

    * Data:

    DF: WIDE VERSION: ‘new–Items_Wide.csv”
    DF: LONG VERSION: ‘new–items.csv”

    * Whole code:

    
    Template("new--Items_Wide.csv", row =>
      newTrial("listOfWords",
        newMediaRecorder("recorder").log().record()
        ,
        newTimer("recording", 3000).log().start()   // Start the timer now
        ,
        newText("words", row.Column1.split('_').join("<br>")) // separate each word with a <br> tag (new line)
            .cssContainer({
               padding: '0.5em',  // add some to not get too close to the border
              'text-align': 'center',   // trying to make the words center on fullscreen -- NOT WORKING :(
              'font-size': '50px',
              'position': 'absolute',  
              'top': '50%',
              'bottom': '50%',
              'left': '50%',
              'width': '100%'
            })
            .print()
        ,
        newButton("NEXT", "Next words!")
            .callback(  // use a callback to execute this in parallel to waiting for the timer
                getButton("NEXT").remove() // remove the NEXT button
                ,
                getText("words").text( row.Column2.split('_').join("<br>") ) // update the displayed list of words
            )
            .print()
            // do not wait for a click, otherwise the timer might elapse before the click
        ,
        getTimer("recording").wait() // wait for the timer to end
        ,
        getMediaRecorder("recorder").stop()
        ,
        getButton("NEXT").remove() // make sure to remove the button, in case the participant didn't get to the second list
        ,
        getText("words").remove()
        ,
        newText('a', "Time is up!").print()
        ,
        newButton('btn--finish--game', 'Finish Game').print().wait()
      )
    );
    
    in reply to: Displaying n words on screen #10570
    Larissa_Cury
    Participant

    I fixed letter A, I was using the wrong separator, but I’m still having issues with b)…
    I would like to avoid having to hard code every single column name in the wide version or to use only the single column in the long version, because I’ll have many in the real experiment…

    in reply to: Displaying n words on screen #10569
    Larissa_Cury
    Participant

    Ps: I’ve just added a wide version of the data as well, if it’s better this way, called ‘new–Items_Wide’

Viewing 15 posts - 16 through 30 (of 92 total)