Randomly Shuffle Positions of Elements

PennController for IBEX Forums FAQ / Tips Randomly Shuffle Positions of Elements

Tagged: , , ,

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #1594
    Jeremy
    Keymaster

    Say you want to show three elements in line on the screen, but randomly determine which one appears to the left, to the right or in the middle. What you need to do is group them within a Selector element and use its command shuffle:

    newCanvas("green", 100, 100)
        .settings.css("background", "green")
    ,
    newCanvas("red", 100, 100)
        .settings.css("background", "red")
    ,
    newCanvas("blue", 100, 100)
        .settings.css("background", "blue")
    ,
    getCanvas("green")
        .settings.after(
            getCanvas("red")
                .settings.after( getCanvas("blue") )
        )
        .print()
    ,
    newSelector("canvas")
        .settings.add( getCanvas("green") , getCanvas("red") , getCanvas("blue") )
        .settings.disableClicks()
        .shuffle()
    

    If you want to later check the result positions of the elements, you can use the test command index on the Selector element. In the example above green, red and blue are initially added to the selector with indices 0, 1 and 2 respectively (i.e., the order in which they appear in add) and initially appear in this order from left to right, so you know that whichever element ends up with index 0 after the shuffle is the left-most element and 2 is the right-most element.

    #7424
    ari
    Participant

    Dear Jeremy,

    This trick worked very well for me until recently and now suddenly doesn’t – the only change being that I’m no longer using the PCIbex Farm, I have to run the experiment on a locally hosted IbexFarm server by syncing the git repo to obey local data protection laws.

    Here’s the code for the relevant segment of a trial:

    newTrial("practice",
        defaultText
            .center()
            .print(),
            
        newText("info","<p><i>This is a trial round.</i></p>"),
            
        newSelector("texts"),
            
        newText("premise1", "The girl is holding an ice-cream.")
            .selector("texts"),
        newText("premise2", "The boy is holding a cupcake.")
            .selector("texts"),
        newText("premise3", "The baby is holding an ice-cream and a cupcake.")
            .selector("texts"),
            
        getSelector("texts")
            .shuffle()
            .disable(),
            
        newButton("next", "NEXT"),
        
        newCanvas("next1", 250, 250)
            .add(300, 64.5, getButton("next"))
            .print(),
        
        getButton('next')
            .log()
            .wait()
    
    );

    The same code runs on IbexFarm but no longer shuffles the elements. I’ve tried different formats like adding items to the selector using .add() instead, using .disableClicks(), ordering differently, etc. but it makes no difference and I can’t tell what I’m doing wrong. Might it have something to do with the PennController syncing to where I’m running the experiment?

    Thank you for your input!

    #7429
    Jeremy
    Keymaster

    Hi,

    Make sure to include the latest version of PennController.js in your project’s js_includes folder

    Jeremy

    #7459
    ari
    Participant

    Hi Jeremy,

    I’ve checked and synced it exactly as it says to in the above link :/ It still refuses to shuffle.

    #7462
    Jeremy
    Keymaster

    Hi,

    I’m not sure what link you are referring to: the link from my previous message points to a .js file that you should download and place in your project’s js_includes folder. If you are referring to https://github.com/PennController/Sync, note that it still points to version 1.9 (I actually need to update this…)

    There is nothing wrong with your code: if you paste it into an empty project on the farm (which comes with PennController 2.0) and take a test run, you’ll see that the Text elements’ positions are indeed shuffled as expected

    Jeremy

    #8564
    ediachek
    Participant

    Hi Jeremy,

    I’m sorry I’m bugging you with a simple question again. I want to display 3 words in a random order horizontally in one line. When I’m using your trick above, I am losing 1 word and there are no spaces between them. Can I add spaces between and move it down a bit? Do you have any suggestions on how to fix it?

    Template("triplets_English_version3.csv", row =>
        newTrial("trials",
        
            newText("agent",row.agent).bold().color("red"),
            newText("verb",row.verb).bold().color("red"),
            newText("patient",row.patient).bold().color("red"),
            
            getText("agent")
                .after(getText("verb")
                    .after(getText("patient")))
                .print()
            ,
            
            newSelector("triads")
                .add(getText("agent"),getText("verb"),getText("patient"))
                .shuffle()
                .disableClicks()
                .center()
            ,
            
            newText("instructions","Please make up a sentence using all 3 words above and type it in the box below"),
    
            newTextInput("answer", "")
                .size(400,200)
                .center()
                .print()
                .log()
            ,
            
            newCanvas("trial_display", 1000, 500)
                .add("center at 50%", "middle at 20%", getSelector("triads"))
                .add("center at 50%", "middle at 40%", getText("instructions") )
                .add("center at 50%", "middle at 65%", getTextInput("answer") )
                .print()
            ,
    #8654
    Jeremy
    Keymaster

    Hi,

    This is a bug caused by the embedding of after commands: shuffle will try to move the elements around, but since some are embedded inside other ones, it ends up crashing because of a recursion issue

    A workaround consists in printing all three Text elements inside a container Text element:

    newText("agent",row.agent).bold().color("red").css("margin-right","0.25em"),
    newText("verb",row.verb).bold().color("red").css("margin-right","0.25em"),
    newText("patient",row.patient).bold().color("red").css("margin-right","0.25em"),
    
    newText("container", "").css("display","flex").print(),
    getText("agent").print(getText("container")),
    getText("verb").print(getText("container")),
    getText("patient").print(getText("container"))
    ,
    
    newSelector("triads")

    Jeremy

    #9613
    ediachek
    Participant

    Hi Jeremy,

    I was wondering if it would be possible to randomly shuffle images in a 3×3 grid. In other words, if I have 9 images, I want them to appear in random places on the grid on each trials.

    Thanks so much!

    Best,
    Yev

    #9619
    Jeremy
    Keymaster

    Hi Yev,

    Use the Selector element’s shuffle command, as illustrated above and in the tutorial:

    newSelector("images")
    ,
    defaultImage.size(100,100).selector("images")
    ,
    newCanvas("3x3", 300, 300)
      .add(  0,  0,newImage("one.png"))
      .add(100,  0,newImage("two.png"))
      .add(200,  0,newImage("three.png"))
      .add(  0,100,newImage("four.png"))
      .add(100,100,newImage("five.png"))
      .add(200,100,newImage("six.png"))
      .add(  0,200,newImage("seven.png"))
      .add(100,200,newImage("eight.png"))
      .add(200,200,newImage("nine.png"))
      .print()
    ,
    getSelector("images").shuffle().disable()

    Jeremy

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.