一:将想要的数据写入数据文件
问题描述:
通常使用组件直接设置的内容可能会被自动写入数据文件,比如键盘组件、图片组件等(具体来说,比如按键的反应时、正确的按键、在组件中添加的变量等)。
然而,程序运行过程中产生的中间数据,比如每张图片出现的位置,并没有被写入数据文件中——往往是用代码直接写的部分,这时需要再手动写代码来添加想要的数据到最后生成的数据文件。
实现这个只需要一句简单的代码:
trials.addData('image_1.position', image_1.pos)
image_1是我的图片组件名,image_1.position是我想在数据文件中查看的变量名称(也就是列名),image_1.pos是这个组件所表示的图片的位置。末尾.pos是一个属性,表示图片的位置。
再举一个例子:
thisExp.addData('num_presses',num_presses)
(ps. 我本以为这两句代码开头是一样的。直到打进去才发现有差别。笑哭emoji。)
所以我原本用第二句代码当第一句使也完全没有问题,前提是把它放在循环loop的里面。但实际上这串代码常放在loop之外。两句代码具体差别见下:
GPT:
-trials.addData() 主要用于在每个试次循环中添加特定于试次的数据,例如试次编号、条件名称、响应时间等。它将数据添加到与当前试次对应的数据文件的行中。
-thisExp.addData() 用于在全局范围内添加整个实验的共享数据,例如被试信息、实验参数、整个实验的平均结果等。它将数据添加到数据文件的一行中,该行通常位于数据文件的顶部,记录了与整个实验相关的信息。
-在某些情况下,您可以使用其中任意一种方法来添加数据。例如,如果要将特定于试次的数据添加到数据文件的一行中,您可以使用 trials.addData() 或 thisExp.addData() 来实现相同的效果。
除此之外,在程序的脚本中,我还发现了将block数据写入数据文件的代码:
blocks.addData('text_3.started', text_3.tStartRefresh)
blocks.addData('key_resp_2.keys', key_resp_2.keys)
回头看组件,发现这些信息确实只存在于每一次block开始时的指导语routine中。
二:属性的用处
主要说一下我如何借助属性来写条件语句,从而获得想要的赋值的。
问题描述
我的实验程序每个试次要呈现四张图片,每个象限各一张,左右两边各代表一个选项,每个选项中有两个属性,每个属性位于同一行。
(Glickman, 2019, PLOS computational biology)
将A图向右翻转90度就是我的展示方式。由于要做随机化处理,即两种属性(此属性非彼属性,这里指的是努力和奖赏两种属性。本文要介绍的是组件属性。)的上下位置随机,两个选项的左右位置随机,因此一共有四种组合方式。
这四种组合方式是随机呈现的,代码如下:
pos1 = 0
pos2 = 0
pos3 = 0
pos4 = 0
# 先定义变量
elif 0.25 <= random() < 0.5:
pos1 = (0.3,0.3)
pos2 = (0.3,-0.3)
pos3 = (-0.3,0.3)
pos4 = (-0.3,-0.3)
correct = 'f'
# 选高努力选项的情况视为正确。我实验设置了高努力属性对应了pos3的位置,高奖赏属性对应了pos4的位置。由于f是左键,对应了这里的pos3和pos4,所以在这种试次下选f人为规定为正确。下方同理。
elif 0.5 <= random() < 0.75:
pos1 = (-0.3,-0.3)
pos2 = (-0.3,0.3)
pos3 = (0.3,-0.3)
pos4 = (0.3,0.3)
correct = 'j'
else:
pos1 = (0.3,-0.3)
pos2 = (0.3,0.3)
pos3 = (-0.3,-0.3)
pos4 = (-0.3,0.3)
correct = 'f'
# 再赋值
# ps. pos1和pos2总是在一边,pos3和pos4总是在一边。
每张图片对应于一个位置,比如image1_1组件设定了Image属性为$aa,Position[x,y]属性为$pos1;image2_2组件设定了Image属性为$bb,Position属性为$pos2;以此类推。
重点来了:我需要根据被试的决策来提供相应的任务及反馈,那么我就需要知道被试在当前试次的选择是什么,并为任务环节需要的变量来赋值。
赋值过程代码如下:
max_presses = 0
# 被试决策完要进行努力任务,那么在此之前需要获得被试选择的努力任务的水平。于是定义一个按键最大次数的变量。
if key_resp.corr == 0 and image1_1.image == 'eff_1.png':
max_presses = 5
elif key_resp.corr == 0 and image1_1.image == 'eff_2.png':
max_presses = 10
elif key_resp.corr == 0 and image1_1.image == 'eff_3.png':
max_presses = 15
elif key_resp.corr == 0 and image1_1.image == 'eff_4.png':
max_presses = 20
elif key_resp.corr == 0 and image1_1.image == 'eff_5.png':
max_presses = 25
elif key_resp.corr == 1 and image3_3.image == 'eff_1.png':
max_presses = 5
elif key_resp.corr == 1 and image3_3.image == 'eff_2.png':
max_presses = 10
elif key_resp.corr == 1 and image3_3.image == 'eff_3.png':
max_presses = 15
elif key_resp.corr == 1 and image3_3.image == 'eff_4.png':
max_presses = 20
elif key_resp.corr == 1 and image3_3.image == 'eff_5.png':
max_presses = 25# 这部分代码的意思是根据被试的选择,如果是“正确的”,即key_resp.corr ==1(注,key_resp是决策环节键盘组件名 .corr就是该组件的Correct answer属性。),以及如果当前试次图片组件(比如image1_1)提取的图片为某图片名(比如eff_1),那么将5赋值给max_presses。该过程正是通过组件的属性,即image属性来进行的。前文说过image属性里设置了$aa,$bb等,而aa,bb其实是存储着所有图片名的excel的一个变量名(列名)。ps. 这里aa其实是eff_low.
(Figure. ps. 其中从第二行开始,每一行代表一个condition。每个试次正是从这些condition中随机抽取的。)
总结:对于奖赏反馈信息的呈现,也是采用同样的办法。重要的是善于利用组件中的属性。以及善于利用条件语句。
我的收获与感悟:程序从构思、到在与GPT攀谈的过程中不停摸索、再到一步一步逼近成果,花了5天左右的时间。这段时间还是很有成就感的,也很感叹困难一个个都在不懈努力或机缘巧合下被解决了。此外要感谢那些爱分享又热爱学习的热心网友们。接下来还有好多工作要做,要一鼓作气!
记于凌晨1.12。明天再写几篇稿子来复盘!(噢不,今天)