Как вывести данные в файл?

Итак, я пытаюсь написать эксперимент Струпа с нуля. В идеале я хотел бы, чтобы эксперимент был организован следующим образом:

  1. Введите информацию об участнике
  2. Страницы с инструкциями (нажмите x, чтобы продолжить)
  3. Страница инструкций 2 (нажмите x, чтобы продолжить)
  4. Начало эксперимента
  5. Перерыв между испытаниями
  6. Эксперимент 2
  7. Конец

(будет более 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.

person Jessica C    schedule 24.05.2016    source источник
comment
Несколько вещей, которых следует остерегаться: не создавайте новый TextStim так много раз. Это тяжело для компьютерных ресурсов и не дает четкого представления о том, что вы просто хотите изменить текст, а иногда и цвет. Просто создайте его в начале скрипта и обновите текст, используя msg.text = Phrase2 и msg.color = MyColor2. Что касается диалога, загляните на gui.DlgFromDict, это облегчит вам жизнь!   -  person Jonas Lindeløv    schedule 25.05.2016


Ответы (2)


Вам действительно следует подумать об использовании классов TrialHandler и/или ExperimentHandler, встроенных в PsychoPy: они уже решили эту (и многие другие проблемы) за вас. Вам не нужно заново изобретать велосипед.

т. е. определить параметры испытания (в вашем случае цвета и фразы) и передать их в TrialHandler при его создании. Затем он будет автоматически циклически проходить каждое испытание (последовательно или случайным образом, по мере необходимости) и автоматически сохранять данные для вас в структурированных файлах. Данные, собранные из информационного диалогового окна эксперимента, сохраняются вместе с данными, так как словарь информации, полученный из диалогового окна, может быть передан как параметр extraInfo при создании TrialHandler или ExperimentHandler.

API данных PsychoPy находится здесь: http://www.psychopy.org/api/data.html и есть примеры использования TrialHandler и ExperimentHandler в меню Demosexp control. Или проверьте любой простой код, сгенерированный Builder, на предмет эксперимента, содержащего цикл. Например, демо-версия Builder Stroop ;-) Код Builder довольно многословен, но просто посмотрите на ту часть, где создаются обработчики Trial/Experiment и как контролируется экспериментальный цикл.

person Michael MacAskill    schedule 24.05.2016

Рассматривали ли вы возможность использования аргументов командной строки? Это позволит вам передавать имена файлов в начале вашего скрипта. Например:

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

Затем вы получите следующий вывод из двух операторов печати в приведенном выше коде:

File1.txt
File2.txt

Таким образом, теперь вы можете использовать args["input"] и args["output"] , чтобы указать вашей программе, откуда ей нужно получать ввод и вывод, не помещая их напрямую в свой код.

person Kush    schedule 24.05.2016