Jeremy

Forum Replies Created

Viewing 15 posts - 751 through 765 (of 1,522 total)
  • Author
    Posts
  • in reply to: result files: change in the columns #7232
    Jeremy
    Keymaster

    Hi Andressa,

    You’re not doing anything wrong. The issue was reported and has been discussed on this thread

    Jeremy

    in reply to: Filled TextInput #7231
    Jeremy
    Keymaster

    Hi Ana,

    The first column in the results file is already (almost) unique to each participant. You only get duplicates when the same browser on the same device is used multiple times to take the experiment

    You can also generate a unique completion code, as described here. Some recruiting platforms also allow you to pass a unique ID as part of the experiment’s URL: here is a guide on how to interface your PCIbex experiment with the recruiting platform Prolific

    Let me know if you have questions

    Jeremy

    in reply to: Controller of UndashedSentence #7227
    Jeremy
    Keymaster

    Hello Yoko,

    You can upload custom controllers to your project: drag and drop your js file to your project’s Modules folder, or click the up-arrow upload icon which appears to the right of “Modules” when you move your mouse over it to open a dialog to select a file from your device

    Jeremy

    in reply to: Shuffling particular trials within a trial sequence #7223
    Jeremy
    Keymaster

    Hi Alex,

    Are you looking for rshuffle("exp-trials","catch-trials")? Or randomize(endsWith("-trials"))? See the Ibex documentation

    Jeremy

    in reply to: Controller Name Column in Results Missing Data #7220
    Jeremy
    Keymaster

    Hi Max,

    Thank you for reporting this bug. It has independently been brought to my attention recently, it’s a bug that was introduced with the new results-generation algorithm. It is independent from PennController, which explains why you observed it with all versions you tried. Same about the browsers: the problem lies with the farm’s code

    I am reluctant to update the farm’s code just for this, as this sort of operations always come with a risk of extended downtime. In the meantime, assuming you don’t need the information in the Controller column, you can easily drop that column name in R: names(results) <- names(results)[c(1,2,seq(4,length(names(results))))]—or you can simply read the results file with no column names first, and then manually name the columns yourself

    Re. saving the results file on the old farm: you can click the eye icon to open the results in a new tab and then use your browser’s menu’s File>Save option, it’s faster and safer than copying and pasting the text in a new file

    Jeremy

    in reply to: Buttons for priming experiments #7217
    Jeremy
    Keymaster

    Hi,

    You can allow selection through both keypresses and clicks using a Selector element, as illustrated in the tutorial

    Clicks are notoriously slower than key strokes, but letting participants tap buttons on a touchscreen is of course a better option than asking them to use a virtual keyboard. It’s probably a good idea to explicitly invite your participants to press keys if they have a keyboard (it will also make them go through the experiment faster than clicking, which they will surely appreciate) or to tap the buttons if they have a touchscreen. You could ask them to fill a form at the end of the experiment where they report how they made their selections. And if you want to have an independent measure, you can always keep a Key element but log it without waiting for it, so you see in the results file whether they pressed a key

    Example:

    newTrial(
      newText("<p>HELLO</p>").bold().center().print()
      ,
      defaultText
        .italic()
        .size("10em","5em")
        .css({
            border: "solid 1px gray",
            padding: "0.5em",
            'text-align': "center"
        })
      ,
      newCanvas("container", "30em", "auto")
        .add("right at 10em", 0, newText("yes","<p>Word</p><p>(F)</p>"))
        .add("left at 20em", 0, newText("no","<p>Not a word</p><p>(J)</p>"))
        .center()
        .print()
      ,
      newKey("FJ").log("first")
      ,
      newSelector("answer")
        .add(getText("yes"),getText("no"))
        .keys("F","J")
        .log()
        .wait()
    )

    Jeremy

    Jeremy
    Keymaster

    The ‘Sync’ option just copies all the files from the git repo to the PCIbex Farm, so yes, it does use storage space, which is why it counts toward your quota. If you have files on Github you can directly reference their download URL, eg. newImage("https://raw.githubusercontent.com/LariCury/test_includes/main/Imagem-1-A.png")—you can also add AddHost("https://raw.githubusercontent.com/LariCury/test_includes/main/") at the top of your script and then use newImage("Imagem-1-A.png"), newImage("Imagem-1-B.png"), etc. in your trials if you need to reference multiple files from your github repo

    The PCIbex Farm won’t be able to see your private repositories, so you won’t be able to sync them to your projects

    It shouldn’t be a problem to directly have diacritics in the CSV file, I just tried and it worked—double-check whether you use commas in your sentences, which would be interpreted as separating columns. If you have any comma that’s not supposed to separate two columns, you can replace them with &comma;; likewise, you can replace any á with &acute;, any é with &ecute;, any à with &agrave;, any è with &egrave;, …

    Jeremy

    Jeremy
    Keymaster

    Hi,

    The folders and file in the github repository at https://github.com/LariCury/test_includes.git do not have the structure of an Ibex experiment: if you look at this repo for example, you’ll see three directories: chunk_includes (Resources), data_includes (Scripts) and js_includes (Modules)—project can have a fourth folder, css_includes (Aesthetics)

    If you want to import images to your project’s Resources by syncing a git repo, you need to place those images in a folder named chunk_includes at the root of that repo (for example, just rename folder_includes to chunk_includes)

    Other than that, there’s something weird that happened with the project at the link you gave, where main.js is listed twice under Scripts—something for me to look into. Anyway, glad that the 300×200 images now work properly!

    Jeremy

    in reply to: Filled TextInput #7207
    Jeremy
    Keymaster

    Hi Ana,

    You inserted the code at the right place, there only are two minor problems:

    – your TextInput element is named "inputNasc" so you need to update the querySelector line: const ipt = document.querySelector(".PennController-TextInput-container.PennController-inputNasc-container textarea");

    – you have a wait on the TextInput element before you call the Function element, so the function will only be called after a keypress on Enter, at which point it is too late for the function to have any effect, really; simply add a getTextInput("inputNasc") after your Function element’s call command (don’t forget the separating comma) and attach the wait lines to that getTextInput instead, so that you wait for a keypress after the function has been executed

    Two last notes:

    – you haven’t added the CSS rules to Aesthetics/PennController.css yet—the function will work without them, but the rendering will look very messy (even more so given the long list of cities you have)

    – you might want to change the local.filter line to sug = local.filter(v=>v.match(new RegExp("^"+ipt.value, "i"))); so you only keep the suggestions that start with what’s in the text box, rather than any suggestion that simply contains what’s in the text box anywhere (notice the addition of "^"+)

    Jeremy

    in reply to: Filled TextInput #7205
    Jeremy
    Keymaster

    Hi Ana,

    Sure, you’ll need to adapt the javascript code to the specific DOM stucture of a PennController trial, but it’s pretty much the same logic as what you found on w3schools. Here’s an example:

    newTrial(
        newTextInput("country")
            .print()
        ,
        newFunction( ()=>{
            let sug = [];
            let idx = 0;
            const ipt = document.querySelector(".PennController-TextInput-container.PennController-country-container textarea");
            const countries = ["Afghanistan","Albania","Algeria","Andorra","Angola","Anguilla","Antigua & Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain","Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia & Herzegovina","Botswana","Brazil","British Virgin Islands","Brunei","Bulgaria","Burkina Faso","Burundi","Cambodia","Cameroon","Canada","Cape Verde","Cayman Islands","Central Arfrican Republic","Chad","Chile","China","Colombia","Congo","Cook Islands","Costa Rica","Cote D Ivoire","Croatia","Cuba","Curacao","Cyprus","Czech Republic","Denmark","Djibouti","Dominica","Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Ethiopia","Falkland Islands","Faroe Islands","Fiji","Finland","France","French Polynesia","French West Indies","Gabon","Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guam","Guatemala","Guernsey","Guinea","Guinea Bissau","Guyana","Haiti","Honduras","Hong Kong","Hungary","Iceland","India","Indonesia","Iran","Iraq","Ireland","Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kiribati","Kosovo","Kuwait","Kyrgyzstan","Laos","Latvia","Lebanon","Lesotho","Liberia","Libya","Liechtenstein","Lithuania","Luxembourg","Macau","Macedonia","Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Mauritania","Mauritius","Mexico","Micronesia","Moldova","Monaco","Mongolia","Montenegro","Montserrat","Morocco","Mozambique","Myanmar","Namibia","Nauro","Nepal","Netherlands","Netherlands Antilles","New Caledonia","New Zealand","Nicaragua","Niger","Nigeria","North Korea","Norway","Oman","Pakistan","Palau","Palestine","Panama","Papua New Guinea","Paraguay","Peru","Philippines","Poland","Portugal","Puerto Rico","Qatar","Reunion","Romania","Russia","Rwanda","Saint Pierre & Miquelon","Samoa","San Marino","Sao Tome and Principe","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore","Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Korea","South Sudan","Spain","Sri Lanka","St Kitts & Nevis","St Lucia","St Vincent","Sudan","Suriname","Swaziland","Sweden","Switzerland","Syria","Taiwan","Tajikistan","Tanzania","Thailand","Timor L'Este","Togo","Tonga","Trinidad & Tobago","Tunisia","Turkey","Turkmenistan","Turks & Caicos","Tuvalu","Uganda","Ukraine","United Arab Emirates","United Kingdom","United States of America","Uruguay","Uzbekistan","Vanuatu","Vatican City","Venezuela","Vietnam","Virgin Islands (US)","Yemen","Zambia","Zimbabwe"];
            const select = s=>{
                ipt.value = s;
                if (ipt.parentElement==div.parentElement)
                    ipt.parentElement.removeChild(div);
            };
            const div = document.createElement("DIV");
            div.classList.add("PennController-suggestions")
            let previousIdx = 0;
            const refreshSug = ()=>{
                if (div.parentElement!=ipt.parentElement) return;
                if (idx!=previousIdx){
                    div.childNodes.forEach((v,i)=>{
                        if (i==idx) {
                            v.style["background-color"] = "pink";
                            v.scrollIntoView({block: "nearest"});
                        }
                        else v.style["background-color"] = "transparent";
                    });
                    previousIdx = idx;
                }
                window.requestAnimationFrame(refreshSug);
            }
            ipt.addEventListener("keydown", e=>{
                if (div.parentElement!=ipt.parentElement) return true;
                if (e.keyCode==40) idx = (idx+1)%sug.length;
                else if (e.keyCode==38) idx = (idx-1 < 0 ? sug.length-1 : idx-1);
                else if (e.keyCode==13) select(sug[idx]);
                else return true;
                e.preventDefault();
                return false;
            })
            ipt.addEventListener("input", ()=>{
                sug = countries.filter(v=>v.match(new RegExp(ipt.value, "i")));
                if (sug.length){
                    div.innerHTML = "";
                    sug.forEach((v,i)=>{
                        const s = document.createElement("SPAN");
                        s.innerText = v;
                        s.addEventListener('mouseenter', ()=>idx=i);
                        s.addEventListener('mousedown', ()=>select(v));
                        div.appendChild(s);
                    });
                    idx = -1;
                    ipt.parentElement.appendChild(div);
                    refreshSug();
                } else if (div.parentElement==ipt.parentElement)
                    ipt.parentElement.removeChild(div);
            });
            ipt.addEventListener("blur", ()=>ipt.parentElement==div.parentElement && ipt.parentElement.removeChild(div));
        }).call()
        ,
        newButton("Hello world")
            .print()
            .wait()
    )

    You'll also need to add those CSS rules to Aesthetics/PennController.css:

    .suggestions {
        position: absolute;
        transform: translateY(-100%);
        display: flex;
        flex-direction: column;
        max-height: 5em;
        overflow-y: scroll;
        background-color: lightgray;
    }

    Let me know if you have questions

    Jeremy

    Jeremy
    Keymaster

    Hello,

    When copying the link from the green “CODE” button on github, make sure you have ‘HTTPS’ selected and not ‘GitHub CLI’ or ‘SSH’. Also make sure that the folders and files in your repository are properly structured as an Ibex project, with your files in their respective *_includes folders. Like this, for example.

    You project with 100x50px image files works well for me too. Do you have a link to a project with bigger resolution images that doesn’t work, so I can try to identify the problem?

    Jeremy

    Jeremy
    Keymaster

    Hi,

    If the button to select a branch doesn’t work, it probably means the git URL is not valid. Here is an example of a valid URL: https://github.com/penncontroller/sync. Note that you cannot selectively sync one folder or file at a time. The following is *not* a valid git URL: https://github.com/PennController/Sync/tree/master/js_includes

    What is the size of the bigger file that you are trying to upload? Note that each account on the PCIbex Farm has a 64MB quota, which applies to the total of files across all your projects

    Jeremy

    in reply to: Randomising serially presented text items within a trial #7195
    Jeremy
    Keymaster

    Hi,

    The most efficient solution here is probably to use javascript to randomly determine which premises you’ll pick as the first, second and third ones. And since you don’t need to do it during runtime, you can randomize those things for each trial when generating them, in the function you pass to Template

    To give you an idea, you would start your Template command like this:

    Template("fillers.csv", row => {
        row.premiseIndices = [1,2,3];
        fisherYates(row.premiseIndices);
        return newTrial("filler-trial",
    

    You can find the full code (and its demo) here: https://farm.pcibex.net/r/WKBLfB/

    Jeremy

    in reply to: Bug? Some trials will not show up #7191
    Jeremy
    Keymaster

    Hello Matthias,

    Good job figuring out this problem! The debugger fails to catch some errors, it’s not clear which ones fall through the cracks

    When you have such a syntax error, all the code that follows it in your script is ignored by the parser, which explains why the “Dank” trial was not executed: it was not even created, because it is defined further down from where the syntax error was located

    Jeremy

    in reply to: Pre-processing self-paced reading data in R #7186
    Jeremy
    Keymaster

    Hi Ana,

    There is no one-size-fits-all answer to your question. What pcibex.read does is find the rows with the most columns and use those for the whole table

    It’s pretty easy to subset a data frame in R and delete a column, then rename the remaining ones:

    df <- data.frame(colInts=c(1,2,3),colLetters=c(NA,NA,NA),colExtra=c('a','b','c'),colBools=c(T,F,T),colRats=c(1/1,1/2,1/3))
    cols <- names(df)
    df[,2] <- NULL
    cols <- cols[c(seq(1,2),seq(4,5))]
    names(df) <- cols

    The value of df after the first line:

      colInts colLetters colExtra colBools   colRats
    1       1         NA        a     TRUE 1.0000000
    2       2         NA        b    FALSE 0.5000000
    3       3         NA        c     TRUE 0.3333333

    The value of df after the last line:

      colInts colLetters  colBools   colRats
    1       1          a      TRUE 1.0000000
    2       2          b     FALSE 0.5000000
    3       3          c      TRUE 0.3333333

    Jeremy

Viewing 15 posts - 751 through 765 (of 1,522 total)