So far, we have focused on stimuli presentation and responding to these stimuli. We let PsychoPy create the stimuli and put the results on the screen. But we need to record the data in external data files and sometimes we have already existing stimuli lists, we want to use for our experiment. For these functions we need data import and export.
For exporting data we can use the PsychoPy experiment handler or the underlying Python file handling system. We choose the second since it is simpler to use and offers more freedom.
#!/usr/bin/env python import csv ## Experiment Section, collect data here data = [1, 0, 1, 1, 1, 0, 0, 1, 1] ## Closing Section datafile = open("data.csv", "wb") writer = csv.writer(datafile, delimiter=";") for i, row in enumerate(data): writer.writerow([i, row]) datafile.close()
Saving data in Python works in two steps. What you have to do first is to define an output file where Python can direct output to. You do this by using the open() function. Second, you have to make a csv.writer that send your list of data to the output file every time you want to write to it. The term csv stand for comma separated value. It can really do more that just that, but we will see about that in the exercise.
For open(), you need the file name (i.e. how to call the file on the hard disk) as argument and a second argument that describes how to open the file. We use "wb" for writing en "rb" for reading. There are two more functions needed, writerow() and close(). With writerow() from csv.writer object you add a line of comma separated values to your output file on the hard disk, with close() from the file object, you close your file.
Importing or reading in data is almost as easy as exporting and works in a comparable manner. Imagine you want to present a square of a certain size and color on the screen. The experiment consists of four trials, but this could be a different set of trials for different groups of testees. Let's says that you have a file for each experiment and these files have one line for each trial. The value in the first column is the size of the square and the value in the second column is the time it should be on the screen. The columns are separated by a semicolon:
3.3;"red" 1.1;"green" 4.4;"red" 2.2;"green"The experiment code code look like his:
#!/usr/bin/env python import csv ## Setup section, read experiment variables size and color from file size = [] color = [] datafile = open("stimuli.csv", "rb") reader = csv.reader(datafile, delimiter=";") for row in reader: size.append(float(row[0])) color.append(row[1]) datafile.close() ## Experiment Section, use experiment variables here for trial in range(len(size)): print("size = {}, color = {}".format(size[trial], color[trial]))
First we make the empty lists to store size and color of the stimulus. Then we make a file object and connect it to a csvreader. The reader wants to know the precise format of the file, such as the delimiter used. Then we read every line of the file. The first field is appended to the list of sizes. The second row to the list of colors. This example does not show a real experiment section. It just prints the values to the PsychoPy output in the bottom of your window.
You do not need the csv.reader directly in your experiment. my.py as given in the previous lesson contains functions that can do this for you.
#!/usr/bin/env python # -*- coding: utf-8 -*- from psychopy import core, visual, event import csv ## Setup section, read experiment variables from file win = visual.Window([400,300], monitor="testMonitor", units="cm", fullscr=False) stimuli = [] datafile = open("redgreen_stimuli.csv", "rb") reader = csv.reader(datafile, delimiter=";") for row in reader: if len(row)==2: # ignore empty and incomplete lines size = float(row[0]) # the first element in the row converted to a floating point number color = row[1] # the second element in the row stimulus = visual.Rect(win, width=size, height=size) stimulus.fillColor = color stimuli.append(stimulus) datafile.close() ## Experiment Section, use experiment variables here for stimulus in stimuli: stimulus.draw() win.flip() core.wait(1.000) ## Closing Section win.close() core.quit()
Microsoft Excel uses the List separator from the Region and Language settings as delimiter when saving a csv-file, even though in the Save File dialog it says CSV (Comma delimited) (*.csv). This is a long standing problem in Microsoft Excel that especially affects European users, since in European version of Microsoft Windows the standard list separator is set to semi-colon (;). Since the interpretation of the comma (and the period) as decimal marker (and therefore not as list separator) is considered standard in the ISO 80 000 International System (pdf 5.3.4) we assume in this tutorial that the list separator is set to semi-colon.
Unlike most other programs, Microsoft Excel does not support the UTF-8 character set in csv-files. Keep in mind that you cannot use non-ascii characters (χαρακτήρες) if you make your experiment file in Excel.
Continue with the next lesson