mrhelfrich

Forum Replies Created

Viewing 13 posts - 1 through 13 (of 13 total)
  • Author
    Posts
  • in reply to: Controller Name Column in Results Missing Data #7221
    mrhelfrich
    Participant

    Ok, glad to know it the results thing isn’t just me. I understand not wanting to bring everything down just to fix this so that makes sense. I’ll update my R script to account for it like you mentioned thanks.

    As for the saving the page as a text file, I used to do that but somehow my main browser (Chrome) has decided to let me save as a text file and I get the pop-up bar along the bottom showing it was saved to my downloads folder but when I try to click either the pop-up or open the downloads folder it is no longer there (the popup says “Removed”). I know for certain this is an issue with Chrome as it doesn’t automatically get deleted when I use a different browser. I’d be curious to see if other Chrome users have the same problem as it occurs even if I am not logged in to Google (or using a guest account).

    Thanks for the quick reply,
    Max

    in reply to: Nested callbacks and test.selected conditions problem #7063
    mrhelfrich
    Participant

    Thank you very much, that solves the problem and is also much easier to understand than what I had written!

    mrhelfrich
    Participant

    It appears to have worked, I cannot be certain until the experiment actually launches since I cannot complete it as a dummy participant but I get same result when testing the integration with Qualtrics only so it appears to be receiving the correct survey code.

    Thank you very much for your help!

    in reply to: Adding break trials #5659
    mrhelfrich
    Participant

    This was very helpful but I am encountering a minor problem with the the Break trial as it was described in this thread and the linked one. My experiment has 63 trials and the number of breaks I want to include doesn’t cleanly fit into that number (I also don’t need to give the participant a break after they have completed all 63 trials, they can just reach the end of the experiment at that point.
    I first tried to give breaks every 16 trials in the hopes that it would give a break at 16, 32, and 48, and since my .csv file only has 63 trials it would skip doing a fourth break since no 64th trial exists but I still get the break occurring. I even tried 17 just to see if it had something to do with 63 being so close to 64 and it still occurred.

    For reference, the code I am using is

    function SepWithN(sep, main, n) {
        this.args = [sep,main];
    
        this.run = function(arrays) {
            assert(arrays.length == 2, "Wrong number of arguments (or bad argument) to SepWithN");
            assert(parseInt(n) > 0, "N must be a positive number");
            let sep = arrays[0];
            let main = arrays[1];
    
            if (main.length <= 1)
                return main
            else {
                let newArray = [];
                while (main.length){
                    for (let i = 0; i < n && main.length>0; i++)
                        newArray.push(main.shift());
                    for (let j = 0; j < sep.length; ++j)
                        newArray.push(sep[j]);
                }
                return newArray;
            }
        }
    }
    function sepWithN(sep, main, n) { return new SepWithN(sep, main, n); }

    And my sequence looks like this:
    Sequence(sepWithN("break",randomize("exptrial"),17),"endexp")

    Thanks for the help,
    Max

    • This reply was modified 3 years, 4 months ago by Jeremy. Reason: replaced main.pop() with main.shift()
    in reply to: DashedSentence in a PennController trial #5604
    mrhelfrich
    Participant

    Hello again,

    I’ve got another question about the code you have written to display words one at a time behind an underscore mask. The items I plan on displaying have various lengths and therefore will probably wrap at least once on a participant’s screen, especially since we don’t know what resolution they will have. To try and make the text wrapping uniform across participants, I was hoping to restrict the area where the text can display to a set size in the hopes that the text would always wrap at the same position for all participants.

    My attempted solution was to use a canvas element to set the dimensions for where the text is displayed, but since I know next to nothing about the code you have written, adding the dashed function as you have written it doesn’t work properly within a canvas.

    Here’s a simplified version of the code I was trying.

    PennController.ResetPrefix(null); 
    showWord = (arrayOfWords,showIndex) => "<p>" + 
      arrayOfWords.map( (word,n) => {
        const letters = word;  
        if (n==showIndex) return "<span>"+letters+"</span>";
        else return "<span style=\'border-bottom:solid 1px black;\'><span style='visibility: hidden;'>"+letters+"</span></span>";
      } ).join(" ") + "</p>"; 
    
    dashed = (name, sentence) => {
        const words = sentence.split(" ");  
        return [  
            [ newText(name,showWord(words)).print() ], 
            ...words.map( (word,index) => [
                newKey(name+"-"+index+"-"+word," ").log().wait(), 
                getText(name).text( showWord(words,index) ) 
            ]),
            [ newKey(name+"-last"," ").log().wait() ]
        ].flat(1);
    }
    newTrial("experiment",
        newCanvas("ItemDisp",700,300)
            .css("border","solid 1px black").css("font-size","24px") 
            .add(0,0,...dashed("SampleItem","Test item to verify that the text wraps within the border, doesn't break during a word, still looks readable." +
            "The actual border is temporary and will not appear during the actual experiment so text that touches it is fine.")),
        
        getCanvas("ItemDisp")
            .print().wait()
    )

    If using a canvas doesn’t work, is there some way to modify the dashed function to limit the length of the displayed text before it wraps? Right now it wraps when it runs out of space in the window so that will vary between displays and window sizes.

    The basic effect I am trying to end up with is this:

    newTrial("experiment",
        newCanvas("ItemDisp",700,300)
            .css("border","solid 1px black").css("font-size","24px")
            .add(0,0,newText("SampleItem","This text needs to be masked and displayed one " +
            "word at a time like it is when using the dashed function.  Also the black border " +
            "is just temporary to see what the dimensions are, it will be removed after testing.")),
        
        getCanvas("ItemDisp")
            .print().wait()
    )

    Thanks again for all of your help,
    Max

    in reply to: Using if statements during a trial #5586
    mrhelfrich
    Participant

    Unable to edit my reply but I figured out how to resolve the problem, I just needed to call getText("FullText") again and then use .remove().

    in reply to: Using if statements during a trial #5584
    mrhelfrich
    Participant

    Okay, that seems to have solved the problem. I have one minor question now that the code is executing properly.
    The way my code is currently set-up, it draws the text I want and immediately after it draws the button to continue, and depending on the what you helped me with that button will be one of two different buttons. When the test fails, button drawn ends the loop and the next trial occurs and all of the old text gets removed, but when the test succeeds, clicking the button to go to the comprehension question draws the comprehension question and then a different button that will end the loop. I was previously hoping that by specifying what items I wanted removed inside the parentheses of the .remove() line would make it remove those items but now that the code is executing properly that doesn’t do anything and the .remove() command just removes whatever it is attached to. When the test succeeds and getButton("FTButton2") appears, upon clicking it I want both the button itself to be removed as well as the previous command getText("FullText") to be removed. Is there a command to remove previously drawn text sort of like what happens when a trial completes and a new loop starts?

    Thanks again for all of the help,
    Max

    in reply to: Using if statements during a trial #5579
    mrhelfrich
    Participant

    Thank you for the quick reply, unfortunately the code you posted is throwing syntax errors when I copy it over. I am not great at understanding the error messages but it seems like it by default after the test ? error checker only allows one get command. I added parentheses to envelop all of the commands that I wanted to run before the : and this gets rid of the syntax errors but when I run the code it doesn’t execute properly (I also had to change row.CompYN==Y ? to row.CompYN=="Y" ? since it was treating it as an expression. I am not certain but it appears that putting parentheses around the multiple commands only stops the syntax errors and the conditional operator you showed me will only run the last command listed before the colon. I changed the text displayed on the buttons to make it easier to see but it looks like the test itself functions properly but it doesn’t execute all of the code when row.CompYN=="Y" is true.

    Here’s the code I have been running that at doesn’t give syntax errors but doesn’t run as expected.

    PennController.ResetPrefix(null);
    // for the sake of forum posting
    AddTable( "IfTable" , 
    "TrialNum,FullText,CompYN,CompQ,CompR,CompTF\n"+
    "1,Trial 1 does not have a comprehension question.,N,,,\n"+
    "2,Trial 2 does have a comprehension question.,Y,Placeholder question for Trial 2 click button to continue no response needed correct answer will be 1 or True.,2,F\n"+
    "3,Trial 3 does have a comprehension question.,Y,Placeholder question for Trial 3 click button to continue no response needed correct answer will be 2 or False.,2,F\n"+
    "4,Trial 4 does not have a comprehension question.,N,,,\n"+
    "5,Trial 5 does have a comprehension question.,Y,Placeholder question for Trial 5 click button to continue no response needed correct answer will be 1 or True.,1,T\n"
    );
    Template( "IfTable" , row =>
        newTrial( "experiment" ,
            newText ("FullText", row.FullText),
            newButton("FTButton1","Proceed to next Trial"),
            newButton("FTButton2","SHOULD DISPLAY IMMEDIATELY AFTER TRIAL 1 AND 4"),
            newText("CompQ",row.CompQ),
            newButton("CQButton","SHOULD DISPLAY WITH COMPQ TEXT ABOVE"),
            getText("FullText").print(),
                (row.CompYN=="Y" ?  // functions like an if statement based on the specified test, if row.CompYN==Y, then the following code is executed, if not, run code after the colon
                  ( // parentheses needed to include multiple commands as part of the 'success' branch of the above test  
                    getButton("FTButton2")
                        .print()
                        .wait()
                        .remove("FTButton2","FullText"),
                    getText("CompQ")
                        .print(),
                    getButton("CQButton")
                        .print()
                        .wait()
                        .remove("CompQ","CQButton")
                  ):  // close parentheses and then colon marks the change to the 'failure' branch of the test
            getButton("FTButton1")
                .print()
                .wait()
                .remove("FTButton1","FullText")       
                )  // closes the 'test'
        ) // closes newTrial
    )  // closes Template
    

    Thanks again for all of your help,
    Max

    in reply to: DashedSentence in a PennController trial #5540
    mrhelfrich
    Participant

    Hello again,

    I am trying to learn something about the code that has been posted here and would like to try and understand how the code you have previously posted that forces special characters to always appear outside of the masks works so that I can remove it or make changes to it in the future. I have two pieces of code that may be useful for my experiment except they have they don’t mask special characters and I have no idea why. The first one should be the same as the code posted previously:

    showWord = (s,i) => ‘<p>’+s.map((w,n)=>`
    <span${(i===n?””:’ style=\’border-bottom:solid 1px black;\’><span style=\’visibility:hidden;\”)}’>
    ${w.replace(/^\s*(\w+).*$/,”$1″)}${(i===n?””:'</span>’)}</span>${w.replace(/^\s*\w+/,”)}`).join(‘ ‘)+'</p>’

    dashed = (name, sentence) => {
    let words = sentence.split(‘ ‘);
    return [
    [newText(name, showWord(words)).print()],
    …words.map( (w,i) => [newKey(${name}-${i}-${w},” “).log().wait() , getText(name).text(showWord(words,i))] ),
    [newKey(${name}-last,” “).log().wait()]
    ].flat(1);
    }

    (Sorry about the formatting, whenever I try using the tilde key to put things into code format it just makes it worse and it appears I have a limited time to edit my replies before the system locks me out)

    The other piece of code I ended up changing was previously for changing the masking character from underscores to hyphens. I was seeing if I could make no mask appear at all, so that participants wouldn’t be able to guess at how long each word was until it appeared on screen but whatever I did ended up breaking everything in a way that could potentially be useful for me in the future since it makes only one word appear on screen at a time, like in a word-by-word style experiment. However it still has the same issue of not masking special characters which looks odd.

    showWord = (s,i) => ‘<p style=”font-family: monospace;”>’+s.map((w,n)=>`
    <span>${w.replace(/^\s*(\w+).*$/,”$1″).replace(/(.)/g,(i===n?”$1″:” “))}</span>${w.replace(/^\s*\w+/,”)}`).join(‘ ‘)+'</p>’

    dashed = (name, sentence) => {
    let words = sentence.split(‘ ‘), maxwidth = 0;
    words.map(w=>maxwidth=Math.max(w.length,maxwidth));
    return [
    [newText(name, showWord(words,null,maxwidth)).print()],
    …words.map( (w,i) => [newKey(${name}-${i}-${w},” “).log().wait() , getText(name).text(showWord(words,i,maxwidth))] ),
    [newKey(${name}-last,” “).log().wait()]
    ].flat(1);
    }

    I would like to at least understand what portion of these two pieces of code causes the special characters to be ignored by the masking.

    Thanks again for all of your help, I really appreciate it,
    Max

    in reply to: DashedSentence in a PennController trial #5447
    mrhelfrich
    Participant

    The stimuli I will be using have set limitations of 30 words total and 12 characters per word (not including punctuation marks). I think having each blank be a set length, possibly 4 or 5 underscores long, would allow all of the information to appear on the page relatively cleanly (29 blanks x 4 underscores, one word <13 characters, 29 spaces, 2 punctuation marks would be 159 characters). The one concern with having the blanks be potentially shorter than the words is when a word gets displayed the entire string will shift around to display the characters which might be disorienting for a participant to follow along with. I’ll need to think about that and weigh that against being able to predict the length of a word before it gets displayed.

    I’ll probably have more questions for you tomorrow but I’ll see what I can do in the mean time with the code you have provided. Thanks again for all of the help, I really appreciate it.
    Max

    in reply to: DashedSentence in a PennController trial #5440
    mrhelfrich
    Participant

    Thank you for such a fast response,

    Looking at the potential items we plan on using, using the longest word length would possibly be a problem. The longest string we may need to display is 30 words long and the largest word allowed would be 12 characters. Testing the code you just posted, 30 blanks at 12 characters each causes the blanks to wrap across the display. I assume there is a way to clean it up but since I will not have control over the size of the screen participants use to complete the task I think it would be best to limit the amount of characters masked.

    If it is too much effort to have the masks be a uniform size despite how large the actual word is that the original way (underscores match character length) is probably fine.

    Thanks again for the quick reply.

    in reply to: DashedSentence in a PennController trial #5437
    mrhelfrich
    Participant

    I’m not sure why but I’m unable to edit my original post and it looks like the copied code has some formatting problem so here is the code copied again:

    showWord = (s,i) => '<p>'+s.map((w,n)=>`
            <span${(i===n?"":' style=\'border-bottom:solid 1px black;\'><span style=\'visibility:hidden;\'')}'>
            ${w.replace(/^\s*(\w+).*$/,"$1")}${(i===n?"":'</span>')}</span>${w.replace(/^\s*\w+/,'')}`).join(' ')+'</p>'
            
    dashed = (name, sentence) => {
        let words = sentence.split(' ');
        return [
            [newText(name, showWord(words)).print()], 
            ...words.map( (w,i) => [newKey(`${name}-${i}-${w}`," ").log().wait() , getText(name).text(showWord(words,i))] ),
            [newKey(`${name}-last`," ").log().wait()]
        ].flat(1);
    }
    in reply to: DashedSentence in a PennController trial #5436
    mrhelfrich
    Participant

    Hello,

    I am trying to adapt the code from some of the replies in this thread for an experiment but I don’t have any coding experience.

    I am currently using the code in response #5236 to display sentences but I do not want to have the punctuation marks be displayed like that code specifically asks for. I tried using the original code in the opening post but when I use that code it doesn’t work with the Template command mentioned in response #5252.

    For clarity the important part of my code is this:

    showWord = (s,i) => '<p>'+s.map((w,n)=>`
            <span${(i===n?"":' style=\'border-bottom:solid 1px black;\'><span style=\'visibility:hidden;\'')}'>
            ${w.replace(/^\s*(\w+).*$/,"$1")}${(i===n?"":'</span>')}</span>${w.replace(/^\s*\w+/,'')}`).join(' ')+'</p>'   
    
    dashed = (name, sentence) => {
        let words = sentence.split(' ');
        return [
            [newText(name, showWord(words)).print()], 
            ...words.map( (w,i) => [newKey(${name}-${i}-${w}," ").log().wait() , getText(name).text(showWord(words,i))] ),
            [newKey(${name}-last`," ").log().wait()]
        ].flat(1);
    }

    I would like it function like the original code in the first post, i.e. not displaying punctuation marks outside of the masked words.

    While I suspect I will have many more questions, one other related thing that I would like to do if possible would be to make the masking that appears (the series of underscores) appear to be the same length for all words so that a participant cannot look at the entirely masked sentence and guess how long each word is. The experiment I am setting up will use two sentence passages that are up to 30 words in length and it is very obvious currently where words like "a" and "to" are.

    Example: instead of a sentence that says "A local man is in a great amount of debt due to gambling." appearing as "_ _____ ___ __ __ _ _____ ______ __ ____ ___ __ _________" it would appear uniform until the words were being unmasked such as "_____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____ _____"

    Thank you very much for your time as well as this very useful tool.
    Max

Viewing 13 posts - 1 through 13 (of 13 total)