Millisecond Forums

Communication to another program on a different machine

https://forums.millisecond.com/Topic36326.aspx

By Simone1993 - 6/25/2024

Hello,
I am currently building an experiment that includes a wanting key press task to allow consumers to record how much of a food product they want by pressing keys to manipulate a rectangle (similar to this post: https://forums.millisecond.com/Topic25883.aspx).

I have written a script that includes the output of interest being the shape.indicator.height (in%).

I would like to run a web server in Python on another machine and have the Inquisit script send the shape.indicator.height data and participant number to that local web server using <html> elements.

However, I am unsure how to do this in Inquisit and wondered if anyone could help.

Thanks,
Simone
By Dave - 6/26/2024

Simone1993 - 6/26/2024
Hello,
I am currently building an experiment that includes a wanting key press task to allow consumers to record how much of a food product they want by pressing keys to manipulate a rectangle (similar to this post: https://forums.millisecond.com/Topic25883.aspx).

I have written a script that includes the output of interest being the shape.indicator.height (in%).

I would like to run a web server in Python on another machine and have the Inquisit script send the shape.indicator.height data and participant number to that local web server using <html> elements.

However, I am unsure how to do this in Inquisit and wondered if anyone could help.

Thanks,
Simone

First, I'm not convinced this can work, or work well.

Second, you'll need to be more specific re. what exactly you need help with.

Displaying a <html> element will make GET requests to the URL specified. You can, in theory, include the information of interest (height, id)  in URL parameters.

However, if I were to try this, I wouldn't use <html>, which is comparatively slow. Instead, have your Python server host a 1 x 1 pixel image file at some URL. Then have a <picture> element load that image from the URL, with URL parameters for indicator height and subject id tacked on.

Your Python server would be responsible for properly processing the GET request and parsing out the information of interest from the URL parameters.
By Simone1993 - 6/26/2024

Thank you, Dave, for your reply.

We are planning a study involving different participants, where each time a participant completes the wanting task, Inquisit needs to send URL parameters to the Python server.

I already know how to create the Python server and set it to loop in listen mode.
What I need to understand is how to send the URL parameters to a specific Python server in Inquisit. The URL parameter should contain only the height (a quantity) and the participant ID.

I hope I have explained myself clearly now.

Thank you,
Simone
By Dave - 6/26/2024

Simone - 6/26/2024
Thank you, Dave, for your reply.

We are planning a study involving different participants, where each time a participant completes the wanting task, Inquisit needs to send URL parameters to the Python server.

I already know how to create the Python server and set it to loop in listen mode.
What I need to understand is how to send the URL parameters to a specific Python server in Inquisit. The URL parameter should contain only the height (a quantity) and the participant ID.

I hope I have explained myself clearly now.

Thank you,
Simone

I thought I'd already explained that. Anyhow, suppose you have your server running in the local network at IP 192.168.0.100 and the server is hosting an image at the URÖ http://192.168.0.100/img/1pixel.jpg.

Then, to make a GET request to that URL whenever you need to with id and some object's height whenever you need to, you do something like this:

<shape indicator>
/ shape = rectangle
/ color = cadetblue
/ erase = false
/ size = (5%, 5%)
</shape>

<trial mytrial>
/ ontrialend = [
    shape.indicator.height = 1% * round(rand(15, 85)); // just changes the height randomly
]
/ stimulusframes = [1=clearscreen, shape.indicator]
/ validresponse = (57)
/ branch = [
    return trial.do_GET_request;
]
</trial>

<picture GET_request>
/ erase = false
/ size = (1px, 1px)
/ position = (0%, 0%)
</picture>

<trial do_GET_request>
/ ontrialbegin = [
    trial.do_GET_request.resetstimulusframes();
    picture.GET_request.clearitems();
    var url = concat("http://192.168.0.100/img/1pixel.jpg?id=", script.subjectid);
    url = concat(url, "&height=");
    url = concat(url, shape.indicator.height);
    picture.GET_request.appenditem(url);
    trial.do_GET_request.insertstimulusframe(picture.GET_request, 1);
]
/ responseinterrupt = frames
/ trialduration = 0
/ validresponse = (0)
</trial>

<block myblock>
/ trials = [1-10 = trial.mytrial]
</block>



By Simone1993 - 7/1/2024

Thank you, Dave, for your response. I'm attaching my script. We aim to send information rather than retrieve it from the Python server.

Is it possible to send information via Inquisit, such as in this example: id, shape.indicator.height, text.stim.currentitem?

Here is our script.

<values>
/ viewtime = 3000
/stimnumber = 1
</values>

<expressions>
/ viewtime = values.viewtime
</expressions>

<expt>
/ blocks = [1= viewingtime; 2 = response; 3 = viewingtime; 4 = response]
</expt>


<page startinstr>
^After pressing the spacebar you will see a screen with up and down arrows.
^Pressing the up arrow will increase the amount of this yoghurt you will receive in the session and the down arrow will decrease this amount.
^^You will have 3 seconds to make adjustments to the yoghurt amount you want to consume.
</page>

<instruct>
/ nextkey = (57)
</instruct>

<block viewingtime>
/ onblockbegin = [
values.viewtime = 3000;
shape.indicator.height = 50%;
values.stimnumber = list.stimnumbers.nextindex;
]
/ trials = [1=viewtrial]
/ preinstructions = (startinstr)

/ stop = [
block.viewingtime.elapsedtime >= expressions.viewtime;
]
</block>

<block response>
/ trials = [1=do_POST_request]

</block>

//on the keyboard
//press the UP arrow to increase view time
/ press DOWN arrow to decrease view time

<trial viewtrial>
/ ontrialend = [
if (trial.viewtrial.response == 200) {
shape.indicator.height += 2%;
};
if (trial.viewtrial.response == 208){
shape.indicator.height -= 2%;
};
]
/ stimulusframes = [1=clearscreen, stim, up, down, indicator, small_teaspoon, medium_teaspoon, large_teaspoon]
/ validresponse = (200, 208)
/ timeout = 3000
/ branch = [
trial.viewtrial;
]

</trial>

<picture GET_request>
/ erase = false
</picture>


<trial do_POST_request>
/ ontrialbegin = [
var url = concat("http://10.8.0.100:8080/?id=", script.subjectid);
url = concat(url, "&height=");
url = concat(url, shape.indicator.height);
    url = concat(url, "&sample=");
    url = concat(url, text.stim.currentitem);
    pciture.GET_request.appenditem(url);
    trial.do_POST_request.insertstimulusframe(picture.GET_request, 1);
]
/ trialduration = 50
/ validresponse = (noresponse)
</trial>




//3 items in this example
<list stimnumbers>
/ poolsize = 2
</list>

<text stim>
/ items = ("281", "354")
/ select = values.stimnumber
/ erase = false
</text>

<text up>
/ items = ("↑")
/ erase = false
/ position = (30%, 50%)
</text>

<text down>
/ items = ("↓")
/ erase = false
/ position = (70%, 50%)
</text>

<shape indicator>
/ shape = rectangle
/ color = blue
/ position = (10%, 90%)
/ size = (5%, 8%)
/ erase = false
/ halign = center
/ valign = bottom

</shape>

<picture small_teaspoon>
/ items = ("teaspoonsx2.png")
/ position = (5%, 90%)
/ size = (5%, 8%)
/ erase = false
/ valign = bottom

</picture>

<picture medium_teaspoon>
/ items = ("teaspoonx4.png")
/ position = (5%, 50%)
/ size = (5%, 8%)
/ erase = false
/ valign = bottom

</picture>


<picture large_teaspoon>
/ items = ("teaspoonx8.png")
/ position = (5%, 10%)
/ size = (5%, 8%)
/ erase = false
/ valign = bottom

</picture>
<text anchor_min>
/ items= ("10g")
/erase = false
/ position = (5%, 90%)
/ erase = false


</text>

<text anchor_max>
/ items= ("50g")
/erase = false
/ position = (5%, 10%)
/ erase = false


</text>

<text anchor_middle>
/ items= ("30g")
/erase = false
/ position = (5%, 50%)
/ erase = false


</text>

<data>
/ columns = (date time subject group blocknum blockcode trialnum trialcode response latency text.stim.currentitem shape.indicator.height)
/ items= ("50g")
/erase = false
/ position = (5%, 10%)
/ erase = false


</text>)
/ separatefiles = true
</data>



By Dave - 7/1/2024

Simone - 7/1/2024
Thank you, Dave, for your response. I'm attaching my script. We aim to send information rather than retrieve it from the Python server.

Is it possible to send information via Inquisit, such as in this example: id, shape.indicator.height, text.stim.currentitem?

Here is our script.

<values>
/ viewtime = 3000
/stimnumber = 1
</values>

<expressions>
/ viewtime = values.viewtime
</expressions>

<expt>
/ blocks = [1= viewingtime; 2 = response; 3 = viewingtime; 4 = response]
</expt>


<page startinstr>
^After pressing the spacebar you will see a screen with up and down arrows.
^Pressing the up arrow will increase the amount of this yoghurt you will receive in the session and the down arrow will decrease this amount.
^^You will have 3 seconds to make adjustments to the yoghurt amount you want to consume.
</page>

<instruct>
/ nextkey = (57)
</instruct>

<block viewingtime>
/ onblockbegin = [
values.viewtime = 3000;
shape.indicator.height = 50%;
values.stimnumber = list.stimnumbers.nextindex;
]
/ trials = [1=viewtrial]
/ preinstructions = (startinstr)

/ stop = [
block.viewingtime.elapsedtime >= expressions.viewtime;
]
</block>

<block response>
/ trials = [1=do_POST_request]

</block>

//on the keyboard
//press the UP arrow to increase view time
/ press DOWN arrow to decrease view time

<trial viewtrial>
/ ontrialend = [
if (trial.viewtrial.response == 200) {
shape.indicator.height += 2%;
};
if (trial.viewtrial.response == 208){
shape.indicator.height -= 2%;
};
]
/ stimulusframes = [1=clearscreen, stim, up, down, indicator, small_teaspoon, medium_teaspoon, large_teaspoon]
/ validresponse = (200, 208)
/ timeout = 3000
/ branch = [
trial.viewtrial;
]

</trial>

<picture GET_request>
/ erase = false
</picture>


<trial do_POST_request>
/ ontrialbegin = [
var url = concat("http://10.8.0.100:8080/?id=", script.subjectid);
url = concat(url, "&height=");
url = concat(url, shape.indicator.height);
    url = concat(url, "&sample=");
    url = concat(url, text.stim.currentitem);
    pciture.GET_request.appenditem(url);
    trial.do_POST_request.insertstimulusframe(picture.GET_request, 1);
]
/ trialduration = 50
/ validresponse = (noresponse)
</trial>




//3 items in this example
<list stimnumbers>
/ poolsize = 2
</list>

<text stim>
/ items = ("281", "354")
/ select = values.stimnumber
/ erase = false
</text>

<text up>
/ items = ("↑")
/ erase = false
/ position = (30%, 50%)
</text>

<text down>
/ items = ("↓")
/ erase = false
/ position = (70%, 50%)
</text>

<shape indicator>
/ shape = rectangle
/ color = blue
/ position = (10%, 90%)
/ size = (5%, 8%)
/ erase = false
/ halign = center
/ valign = bottom

</shape>

<picture small_teaspoon>
/ items = ("teaspoonsx2.png")
/ position = (5%, 90%)
/ size = (5%, 8%)
/ erase = false
/ valign = bottom

</picture>

<picture medium_teaspoon>
/ items = ("teaspoonx4.png")
/ position = (5%, 50%)
/ size = (5%, 8%)
/ erase = false
/ valign = bottom

</picture>


<picture large_teaspoon>
/ items = ("teaspoonx8.png")
/ position = (5%, 10%)
/ size = (5%, 8%)
/ erase = false
/ valign = bottom

</picture>
<text anchor_min>
/ items= ("10g")
/erase = false
/ position = (5%, 90%)
/ erase = false


</text>

<text anchor_max>
/ items= ("50g")
/erase = false
/ position = (5%, 10%)
/ erase = false


</text>

<text anchor_middle>
/ items= ("30g")
/erase = false
/ position = (5%, 50%)
/ erase = false


</text>

<data>
/ columns = (date time subject group blocknum blockcode trialnum trialcode response latency text.stim.currentitem shape.indicator.height)
/ items= ("50g")
/erase = false
/ position = (5%, 10%)
/ erase = false


</text>)
/ separatefiles = true
</data>




The code I gave you "sends" information to the server in the form of URL parameters in a GET request. How you process that GET request on your Python server is up to you, i.e. you need to make it extract the information from the URL parameters.

There is no way for Inquisit to make arbitrary requests, e.g. a POST to some URL. You're limited to having it make GET requests for some resource, and the response to the GET request must be something that Inquisit can work with. In the example I gave you, the response is an image, because that is what a <picture> element expects. If you were to use <html> instead, then the server would have to return actual HTML, which is much larger and slower than using a 1 pixel image.
By Simone1993 - 7/1/2024

Thank you Dave,
 
Now, is working with changing the pixel back to 1px as you suggested.

Kind regards,
Simone