Как вывести данные в файл?
Поэтому я пытаюсь написать эксперимент Stroop с нуля. В идеале мне бы хотелось, чтобы эксперимент был организован:
- Введите информацию об участнике
- Страницы с инструкциями (нажмите x, чтобы продолжить)
- Страница инструкции 2 (нажмите x, чтобы продолжить)
- Начало эксперимента
- Перерыв между судом
- Эксперимент 2
- Конец
(будет более 2 испытаний, но для тестирования будет использовано только 2)
У меня проблемы с записью данных в текстовый файл. Второе испытание отлично записывает с различными значениями для каждого цикла. Однако первое испытание отображается как дубликаты, и каждое испытание имеет одинаковые значения в текстовом файле.
Кроме того, я не могу понять, как записать данные из всплывающего окна в мой текстовый файл. (т.е. имя субъекта, возраст, идентификатор)
Также есть способ, которым я могу ввести имя файла каждый раз? Без изменения кода? -можно, как всплывающее окно, чтобы выбрать путь и имя файла?
Спасибо!
from psychopy import visual, core
import random
import time
import datetime
import sys
from psychopy import gui
from psychopy import event
#Write to file, need to figure out how to choose file name in each instance
file = open ("Test Output.txt", 'w')
#Pop up subject information - need to figure out how to output this data
myDlg = gui.Dlg(title="TEST TEXT BOX")
myDlg.addText('Subject info')
myDlg.addField('Name:')
myDlg.addField('Age:', )
myDlg.addText('Experiment Info')
myDlg.addField('Subject ID', "#" )
myDlg.addField('Group:', choices=["Test", "Control"])
ok_data = myDlg.show()
if myDlg.OK:
print(ok_data)
else:
print('user cancelled')
#opens up window w/ text,
win = visual.Window([800,800],monitor="testmonitor", units="deg")
msg = visual.TextStim(win, text="Hello")
msg.draw()
win.flip()
event.waitKeys(maxWait=10, keyList=None, timeStamped=False) #page remains until keyboard input, or max of 10 seconds
#with keyboard input, second screen will come up
msg = visual.TextStim(win, text="Instructions 1")
msg.draw()
win.flip()
event.waitKeys(maxWait=10, keyList=None, timeStamped=False)
#3rd screen will pop up with keyboard input
msg = visual.TextStim(win, text="Trial 1")
msg.draw()
win.flip()
event.waitKeys(maxWait=10, keyList=None, timeStamped=False)
#Trial starts,
for frameN in range(5):
MyColor = random.choice(['red','blue','green','yellow'])
Phrase = random.choice(["Red","Green", "Blue", "Yellow"])
time = str(datetime.datetime.now())
key = str(event.getKeys(keyList=['1','2','3','4','5'], ))
pause = random.randint(1200,2200)/1000.0
length = str(pause)
msg = visual.TextStim(win, text=Phrase,pos=[0,+1],color=MyColor)
msg.draw()
win.flip()
core.wait(pause)
msg = visual.TextStim(win, text="Break between trial")
msg.draw()
win.flip()
event.waitKeys(maxWait=10, keyList=None, timeStamped=False)
#trial 2
for frameN in range(5):
MyColor2 = random.choice(['red','blue','green','yellow'])
Phrase2 = random.choice(["Red","Green", "Blue", "Yellow"])
time2 = str(datetime.datetime.now())
key2 = str(event.getKeys(keyList=['1','2','3','4','5'], ))
pause2 = random.randint(1200,2200)/1000.0
length2 = str(pause2)
msg = visual.TextStim(win, text=Phrase2,pos=[0,+1],color=MyColor2)
msg.draw()
win.flip()
core.wait(pause2)
#specifying which data will be recorded into the file
data = "Stimuli:"+ MyColor + ',' + Phrase + ','+ time + ',' + key + ',' + length + MyColor2 + ',' + Phrase2 + ','+ time2 + ',' + key2 + ',' + length2
file.write(data + '\n')
#Jessica's Code.
2 ответа
Вы должны действительно рассмотреть возможность использования TrialHandler
и / или ExperimentHandler
классы, которые встроены в PsychoPy: они уже решили это (и многие другие проблемы) для вас. Вам не нужно заново изобретать колесо.
т.е. определить параметры пробной версии (в вашем случае, цвета и фразы) и передать их в TrialHandler
когда это будет создано. Затем он будет автоматически циклически проходить через каждую пробную версию (последовательно или случайным образом, как требуется) и обрабатывать сохранение данных для вас в структурированных файлах автоматически. Данные, собранные из диалогового окна информации об эксперименте, сохраняются вместе с данными, так как словарь информации, собранной из диалогового окна, может быть передан как extraInfo
параметр, когда TrialHandler
или же ExperimentHandler
создано.
API данных PsychoPy находится здесь: http://www.psychopy.org/api/data.html и есть примеры использования TrialHandler
а также ExperimentHandler
под Demos
→ exp control
меню. Или изучите любой простой код, сгенерированный Builder, для эксперимента, который содержит цикл. Например, демонстрационная версия Builder Stroop;-) Код Builder довольно многословен, но достаточно взглянуть на часть, где создаются обработчики Trial/Experiment и как управляется экспериментальный цикл.
Рассматривали ли вы использование аргументов командной строки? Это позволит вам передать имена файлов в начале вашего скрипта. Например:
python myscript.py InputFile1 InputFile2 OutputFile1 OutputFile2
Есть действительно хороший модуль, который выполняет большую часть тяжелой работы за вас, который называется argparse: https://docs.python.org/3/library/argparse.html
Вот руководство, которое предоставляют документы, если вы немного запуганы: https://docs.python.org/3/howto/argparse.html
Если вам нужна документация по Python 2, вы можете просто изменить 3 на 2 в URL. Вот небольшой пример кода, который покажет вам, что вы можете с ним сделать:
import argparse
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--input", required = True, help = "Path to input file")
ap.add_argument("-o", "--output", required = True, help = "Path to output file")
args = vars(ap.parse_args())
print(args["input"])
print(args["output"])
Затем вы можете позвонить по этому из вашего терминала, чтобы передать ваши местоположения файлов (или все, что вы хотите передать):
python myscript.py -i File1.txt -o File2.txt
Затем вы получите следующий вывод из двух операторов print в приведенном выше коде:
File1.txt
File2.txt
Таким образом, теперь вы можете использовать args["input"] и args["output"], чтобы сообщить вашей программе, откуда она должна получать свои входные и выходные данные, не вставляя их непосредственно в код.