Jeremy

Forum Replies Created

Viewing 15 posts - 841 through 855 (of 1,522 total)
  • Author
    Posts
  • in reply to: control flow #6969
    Jeremy
    Keymaster

    Hi Symon,

    Is this what you’re describing? https://farm.pcibex.net/r/aDjqIb/

    Jeremy

    in reply to: Choosing subet of items to present #6968
    Jeremy
    Keymaster

    Hi Ana,

    I’m not sure what you have in mind about the pick function but I doubt it would be very helpful. Any group manipulation is most straightforwardly handled using the Group/List column. Using the pick function to assign different trials to different participants would require accessing the internal counter and using plain javascript conditional logic to execute different pick functions depending on the counter value. Which would eventually just reproduce the Group/List behavior. You use pick to select the first N trials from a set, for example pick(randomize("experiment"), 5) will pick the first five trials from the randomized set of all trials labeled “experiment” that were generated by your script

    If you want your participants to see repetitions of the same condition, I’d say it’s something you need to consider ahead of the actual implementation of your experiment: say you have a factor with 2 levels, you want a latin-square design, and you want each participant to see 2 repetitions of each condition. If you don’t want a participant to see the same item multiple times in two different conditions within the same experiment, you will need to have at least 4 different items: your participants will see the first 2 items in a different condition each, and same thing for the last 2 items, making for a total of 2 items per condition. Which means you will need to define 4 items*2 conditions = 8 item-variants. With some designs you can define derive the two conditions from an algorithm, so if equipped with such an algorithm, the minimal amount of information you would ultimately need to hard-code would be the two main items. But most of the time you need to manually define the specifics of each condition for each main item. For example, items 1 and 2 might consist of two completely different sentences, and the two conditions might vary names and pronouns: unless those name/pronoun variations are completely deterministic, you still need to list the 8 variants. Then, just use a Group/List column to make sure you have a latin-square design with repetition. Here’s an example:

    Item,Name,Pronoun,Sentence,Group
    1,Philip,himself,Philip thinks about himself a lot,A
    1,Ana,herself,Ana thinks about herself a lot,B
    2,Gregory,himself,Gregory rarely talks about himself,B
    2,Susan,herself,Susan rarely talks about herself,A
    3,Peter,himself,Peter gives himself too much credit,A
    3,Melody,herself,Melody gives herself too much credit,B
    4,Harry,himself,Harry introduces himself as an entrepreneur,B
    4,Shelly,herself,Shelly introduces herself as an entrepreneur,A

    Here I need to list all eight proper names to define the 8 variants resulting from crossing the two conditions with the four items. Each sentence is different, so the 8 variants could not be generated from a table with fewer rows. Each participants will see two repetitions of each condition: for example, participants in group A will see items 1 and 3 in the masculine-grammatical-gender condition, and items 2 and 4 in the feminine-grammatical-gender condition

    I hope my explanations were clear enough. Let me know if you have questions

    Jeremy

    in reply to: DashedSentence in a PennController trial #6959
    Jeremy
    Keymaster

    Hi,

    You can actually reuse DashedSentence’s CSS styling to rewrite a simplified version of dashed:

    EDIT: I forgot about inserting manual linebreaks with <br>, so the code is slightly more complex now

    dashed = (name,sentence) => [
        newText(name,"").css({display:'flex','flex-direction':'row','flex-wrap':'wrap','line-height':'2em','max-width':'100%'}).print()
        ,
        ...sentence.split(/[\s\t<>]+/).map( (w,i) => (w=="br"?
                newText("").css("width","100vw").print(getText(name))
                :
                newText(name+'-'+i, w.replace(/([^.,?:;!]+)/g,"<span class='DashedSentence-ospan'><span class='DashedSentence-ispan'>$1</span></span>"))
                    .css("margin","0em 0.2em")
                    .print(getText(name))
        ))
        ,
        ...sentence.split(/[\s\t<>]+/).map((w,i)=>(w!="br"?[newKey(i+"-"+w," ").log().wait(),getText(name+'-'+i).text(w)]:null))
    ]

    The important part for you in the code above is [^.,?:;!]: it’s a regular expression that will match any character that is not in the list .,?:;!. All those non-punctuation characters will be wrapped in two span elements: the inner one is invisible and the outer one adds an underline

    Use it like this:

    newTrial(
        dashed("myDashed",  "This is a test. This is the second, longer part of the test!<br>\
                             And now this is a third part, just to test whether it will automatically insert a linebreak")
        ,
        newKey(" ").wait()
        ,
        getText("myDashed").remove()
        ,
        newButton("Finish").print().wait()
    )

    Jeremy

    in reply to: Change background color #6958
    Jeremy
    Keymaster

    Hi,

    You could insert this command:

    newFunction( ()=>$("body").css("background-color","lightgray") ).call()

    in your trial whenever you want to change the page’s background

    Incidentally, changing the background’s color is also what the custom element type in this guide on the documentation allows you to do

    Jeremy

    in reply to: Running by Conditions #6955
    Jeremy
    Keymaster

    Hi,

    The post of mine you mentioned expands on a technical point that was raised earlier in the discussion. The solution to the problem discussed in that thread is given two posts up

    Jeremy

    in reply to: access participants' browser info #6953
    Jeremy
    Keymaster

    Hi,

    Yes, you can do something like this for example:

    Sequence("block", "intro", randomize("experiment"))
    
    if (navigator.vendor.match(/apple/i))
        newTrial( "block" ,
            newText("<p>We're sorry, but this experiment is not compatible with your browser.</p>").print()
            ,
            newText("<p>We encourage you to revisit this experiment \
                        using a desktop or laptop version of Chrome or Firefox if possible.</p>").print()
            ,
            newText("<p>Thank you for your understanding.</p>").print()
            ,
            newButton().wait()
        )

    Note that filtering participants after recruiting them is against some recruitment platforms’ policy, such as Prolific’s (last time I checked)

    Jeremy

    in reply to: Running by Conditions #6949
    Jeremy
    Keymaster

    If you continue reading the tutorial, you’ll see that the order is randomized later on

    The different pre-defined functions that allow you to manipulate the order of items based on their labels are listed in the original Ibex documentation

    Jeremy

    in reply to: Choosing subet of items to present #6947
    Jeremy
    Keymaster

    The Latin Square column refers to a native-Ibex concept, where you can group items so that Ibex automatically generates latin-square lists. It’s a convenient grouping device for such designs, but it makes it much more confusing when you need to implement another grouping reasoning, which is why PennController uses a basic “label the rows you want to show together” idea, where a latin square manipulation simply means cycling over group labels

    To use native Ibex’s latin sqaure device, you would do something like this:

    var items = [
      [["DPrealA1", "item-1"], "PennController", newTrial( /* ... */ ) ],
      [["DPrealB1", "item-1"], "PennController", newTrial( /* ... */ ) ],
      [["DPrealC1", "item-1"], "PennController", newTrial( /* ... */ ) ],
      [["DPrealD1", "item-1"], "PennController", newTrial( /* ... */ ) ],
      [["DPrealA2", "item-2"], "PennController", newTrial( /* ... */ ) ],
      [["DPrealB2", "item-2"], "PennController", newTrial( /* ... */ ) ],
      [["DPrealC2", "item-2"], "PennController", newTrial( /* ... */ ) ],
      [["DPrealD2", "item-2"], "PennController", newTrial( /* ... */ ) ],
      // etc.
    ];

    This way Ibex would automatically pair the first item from “item-1” with the second item from “item-2”, the second item from “item-1” with the third item from “item-2”, and so on. You could actually easily generate such latin-square items from Template. Using the table from your previous message with only groups 1 and 2, you could do that:

    Template( "exp_Poss.csv" , exp => 
        newTrial(
            // ...
        )
        .label(["experimentais",exp.id_item.replace(/^.+?(\d+)$/,"$1")])
    )

    I’m using exp.id_item.replace(/^.+?(\d+)$/,"$1") to retrieve the last digit characters of the id_item column

    The problem with this method, if I’m not mistaken, is that it would pick different rows from your table every other run, which means that the latin square would always use an even counter value when running items from group 1, and an odd counter value when running items from group 2, effectively showing only half of your materials

    Jeremy

    in reply to: Choosing subet of items to present #6945
    Jeremy
    Keymaster

    From a purely runlist perspective, I would still say that you have 8 lists, although I can see how it should be seen as a 2-level-factor between-subject + 4-level-factor (latin-square?) within-subject design manipulation

    May I suggest a table like this (assuming a latin-square condition assigment)?

    group	tipo_DP	      num_DP	num_poss  num_N_Pred	id_item
    1	realizado	pl	sg	      sg	DPrealA1
    2	realizado	sg	pl	      sg	DPrealB1
    3	realizado	pl	pl	      sg	DPrealC1
    4	realizado	pl	pl	      pl	DPrealD1
    2	realizado	pl	sg	      sg	DPrealA2
    3	realizado	sg	pl	      sg	DPrealB2
    4	realizado	pl	pl	      sg	DPrealC2
    1	realizado	pl	pl	      pl	DPrealD2
    3	realizado	pl	sg	      sg	DPrealA3
    4	realizado	sg	pl	      sg	DPrealB3
    1	realizado	pl	pl	      sg	DPrealC3
    2	realizado	pl	pl	      pl	DPrealD3
    4	realizado	pl	sg	      sg	DPrealA4
    1	realizado	sg	pl	      sg	DPrealB4
    2	realizado	pl	pl	      sg	DPrealC4
    3	realizado	pl	pl	      pl	DPrealD4
    5	elidido	        pl	sg	      sg	DPeliA1
    6	elidido	        sg	pl	      sg	DPeliB1
    7	elidido	        pl	pl	      sg	DPeliC1
    8	elidido	        pl	pl	      pl	DPeliD1
    6	elidido	        pl	sg	      sg	DPeliA2
    7	elidido	        sg	pl	      sg	DPeliB2
    8	elidido	        pl	pl	      sg	DPeliC2
    5	elidido	        pl	pl	      pl	DPeliD2
    7	elidido	        pl	sg	      sg	DPeliA3
    8	elidido	        sg	pl	      sg	DPeliB3
    5	elidido	        pl	pl	      sg	DPeliC3
    6	elidido	        pl	pl	      pl	DPeliD3
    8	elidido	        pl	sg	      sg	DPeliA4
    5	elidido	        sg	pl	      sg	DPeliB4
    6	elidido	        pl	pl	      sg	DPeliC4
    7	elidido	        pl	pl	      pl	DPeliD4
    

    Jeremy

    in reply to: MediaRecorder's Ajax error (server on Dreamhost) #6943
    Jeremy
    Keymaster

    We solved the issue by email: the problem came from an invalid URL that simply wasn’t pointing at the PHP file

    Jeremy

    in reply to: MediaRecorder's Ajax error (server on Dreamhost) #6941
    Jeremy
    Keymaster

    Hello,

    These are generic error messages, and I cannot tell what specifically prevents your experiment from sending the recordings to your server, and your server from saving them. Would you mind sharing the link to your experiment with me? You can send it at support@pcibex.net if you’d rather not post it on a public forum

    Jeremy

    in reply to: Choosing subet of items to present #6940
    Jeremy
    Keymaster

    Hi Ana,

    The very function of the group/list column is to control between-subject row selection. All rows that should be presented to the same participant, even those defining different conditions as a result of a within-subject design manipulation, should have the same value in their group/list cell.

    The part of your table that you posted suggests another between-group manipulation that does not match the values in tipo_DP: all participants in group 1 (A) will only see pl-sg-sg rows, 2 (B) will only see sg-pl-sg, 3 (C) will only see pl-pl-sg and 4 (D) will only see pl-pl-pl. Because group starts over in the elidido rows, participants in group 1 will also see the E rows, 2 will also see F, and so on.

    So there is no group of participants who will see all A-B-C-D rows, and no group of participants who will see all E-F-G-H rows. What you have is four groups of participants: group 1 will see all A-E rows, group 2 will see all B-F rows, group 3 will see all C-G rows and group H will see all D-H rows

    If you are satisfied with the between-subject assignment of the crossing of num_DP-num_poss-num_NouPred as currently defined in your table, but want to additionally have tipo_DP as a between-subject factor, then it means that you effectively have 8 groups: your table currently defines four levels resulting from the (non-exhaustive) crossing of num_DP-num_poss-num_NouPred, and two levels for tipo_DP, which results in 4*2 = 8 groups. So starting from the first elidido row, you could have group jump to 5, 6, 7 and 8 instead of 1, 2, 3 and 4.

    Does it all make sense?

    Jeremy

    in reply to: Running by Conditions #6939
    Jeremy
    Keymaster

    Hello,

    You need to distribute A, B, C and D over the conditions, as illustrated in the tutorial where participants in group A see items 1 and 3 with a plural inflection and items 2 and 4 with a singular inflection, and participants in group B see the complementary association: items 1 and 3 with a singular inflection and items 2 and 4 with a plural inflection

    Jeremy

    in reply to: Issues with DashedSentence on new farm #6934
    Jeremy
    Keymaster

    Hi Zach,

    For some reason using print(x,y,canvas) adds the Controller element twice onto the page. I need to fix this for the next release of PennController. In the meantime, use canvas.add:

    newController("DashedSentence", {s: row.Sentence, mode: "speeded acceptability", blankText: "+", display: "in place"})
    ,
    getCanvas("sprcanv")
      .add( ds_x_left, ds_y , getController("DashedSentence"))
    

    Jeremy

    Jeremy
    Keymaster

    Hi Symon,

    As I said, the only sort of log file that (PC)Ibex reads is the internal counter. Any other cross-run log system will need to be implemented manually

    The results file is written when the submission is sent to the servers, but not read: doing so would publicly expose the results of every participants

    Editing a (PC)Ibex experiment means editing the javascript code, that is, the code that is executed on the client side (the participant’s browser). Communication with a log file that persists across runs involves setting up something on the server side, which cannot be done by simply editing an experiment. This is why you would need a parallel setup that would communicate with PennController in some way or another

    Jeremy

Viewing 15 posts - 841 through 855 (of 1,522 total)