Code and Output
Code 12.3.1:
% Construct a File1.txt to use for the example
fileout1 = fopen('File1.txt','wt');
fprintf(fileout1,'THIS IS THE CONTENTS OF THE FIRST FILE\n');
fclose(fileout1);
% Now test for the existence of File1.txt
if exist('File1.txt','file') == 2
mybutton = questdlg('Delete old File1.txt? ','File1','Yes');
switch mybutton
case 'Yes'
delete('File1.txt');
msgbox('File1.txt deleted!')
case {'No' 'Cancel'}
msgbox('File1.txt unchanged...Exiting','','warn')
return
end
end
Code 12.3.2:
% Make sure File1.txt exists for the example
fileout1 = fopen('File1.txt','wt');
fprintf(fileout1,'THIS IS THE CONTENTS OF THE FIRST FILE\n');
fclose(fileout1);
% Read in a file, change it, and write out the modified file.
infilename = uigetfile('*.txt')
theText = fileread(infilename);
theText = strrep(theText,'FIRST','SECOND');
fileout2 = fopen('File2.txt','wt');
fprintf(fileout2,theText);
fclose(fileout2);
% Verify that the updated text is now in File2.txt
msgbox('File2.txt successfully created,','All done!','Help')
fprintf('\nContents of File2.txt:')
type File2.txt
Output 12.3.2:
infilename =
File1.txt
Contents of File2.txt:
THIS IS THE CONTENTS OF THE SECOND FILE
Code 12.4.1:
h = figure;
set(h,'position',[ 427 306 512 100])
hpb = uicontrol('Style', 'pushbutton',...
'String', 'Make a sound!',...
'Position', [20 20 150 20],...
'Callback', 'beep');
pause(10)
close(h);
Output 12.4.1:
Code 12.4.2:
function main
beepcount = 0;
h = figure;
hpb = uicontrol('Style', 'pushbutton',...
'String', 'Click to Beep!',...
'Position', [150 100 200 200],...
'Callback', @beepcallback);
pause(10)
close(h);
msgbox(sprintf('Counted %d beeps!',beepcount));
return
function beepcallback(source,eventdata)
beep
beepcount = beepcount + 1;
return
end
end
Output 12.4.2:
Code 12.4.3:
function main;
% Initialize variables common to main and nested subfunctions
month = 'January';
year = 2001;
% Open the figure for the interface
handletothefigure = figure;
% Install a popup menu for the months
monthstrings = {
'Month'
'January'
'February'
'March'
'April'
'May'
'June'
'July'
'August'
'September'
'October'
'November'
'December'};
hmonth = uicontrol('Style', 'popupmenu',...
'String',monthstrings,...
'Position', [120 320 100 20],...
'Callback', @monthcallback);
% Install a popup menu for the years
hyear = uicontrol('Style', 'popupmenu',...
'String',...
'Year|2008|2009|2010|2011|2012|2013|2014|2015|2016|2017|2018',...
'Position', [220 320 100 20],...
'Callback', @yearcallback);
% Install an informative text field for the popup controls
uicontrol('Style','text','String','Pick a month and a year: ',...
'Position', [120,360,200,15]);
% Install a GO button
hgobutton = uicontrol('Style','pushbutton',...
'String','Look up days in the month',...
'Position', [120 120 200 40],...
'Callback', @gobuttoncallback);
% Now just wait for the user to finish (when the window closes);
uiwait(handletothefigure)
return % from main
% Callback routines in nested functions:
function monthcallback(source,eventdata)
mylist = (get(source,'String'));
myitem = (get(source,'Value'));
month = char(mylist(myitem));
end
function yearcallback(source,eventdata)
mylist = (get(source,'String'));
myitem = (get(source,'Value'));
year = str2num(mylist(myitem,:))
end
function gobuttoncallback(source,eventdata)
hmsg = msgbox(sprintf(...
'Will compute days for %s, %d\n\n',month, year));
uiwait(hmsg)
% When user presses the "go" button, the computation from
% Code 7.3.6 would be executed here, to return the results
% (code to be inserted).
close(handletothefigure)
end
end %function main
Output 12.4.3:
Output 12.5.1:
Code 12.6.1:
commandwindow
tic
response = input('What is five plus the square root of 64? ')
Reaction_Time = toc
Output 12.6.1:
response =
13
Reaction_Time =
2.2859
Code 12.6.2:
function RunaTrial
figure(1);clf
pause(2+randi(4)/2)
text(.5,.5,'go','fontsize',32)
axis off
tic
waitforbuttonpress
reactiontime = toc
keypressed = get(gcf,'CurrentCharacter')
close(1)
end
Output 12.6.2:
reactiontime =
0.3626
keypressed =
x
Code 12.6.3:
function RunOneTrial
myfigure = figure(1);clf
pause(2+randi(4)/2)
text(.5,.5,'Press!','fontsize',32)
axis off
reactiontime = [];
tic
set(myfigure,'Keypressfcn',@gotAKey)
timedout = true;
pause(3)
close all;
% Other computation, such as recording the data
if timedout
disp('timed out')
elseif correct
fprintf('Reaction Time = %f\n',reactiontime)
else
disp('It was an error')
beep
end
function gotAKey(src,event)
timedout = false;
if strcmp(event.Character,'g');
reactiontime = toc;
correct = true;
set(myfigure,'Keypressfcn',[])
else
correct = false;
end
end
end
Output 12.6.3:
>> Code_12_5_3
Reaction Time = 0.749595
>> Code_12_5_3
timed out
>> Code_12_5_3
It was an error
Code 12.6.4:
function RunOneTrial
myfigure = figure(1);clf
pause(2+randi(4)/2)
text(.5,.5,'Press!','fontsize',32)
axis off
reactiontime = [];
tic
set(myfigure,'Keypressfcn',@gotAKey)
timedout = false;
mytimer = timer('TimerFcn', @timercallback, 'startDelay', 3);
start(mytimer)
wait(mytimer)
if timedout
disp('timed out')
beep
elseif correctresponse
fprintf('Reaction time = %f\n',reactiontime);
else
disp('error')
beep
end
close(myfigure)
% ... Other computation, such as recording the data
return
function gotAKey(src,event)
correctresponse = false;
if strcmp(event.Character,'g')
reactiontime = toc;
correctresponse = true;
end
timedout = false;
stop(mytimer)
set(myfigure,'Keypressfcn',[])
end
function timercallback(src,event)
timedout = true;
end
end
Code 12.6.5:
function SimonDemo;
clc
clear
close all;
sinit = input('Subject''s initials: ','s');
outfilename = ['SimonData_' sinit];
rawdataoutfilename = strrep(outfilename,'_','_Rawdata_');
rawdataoutfilename = strcat(rawdataoutfilename,'.txt');
rawdatafile = fopen(rawdataoutfilename,'w');
fprintf(rawdatafile,'Trial\tside\tstim\tcomp\tKey\tResp.\tRT\n');
screensize = get(0,'screensize');
% SetScreen
hfig = figure('position',[0 0 screensize(3) 200],'color', [1 1 1]);
% DefineTrialTypes
[ttype(1:4).side] = deal('L','R','L','R');
[ttype(1:4).stim] = deal('L','L','R','R');
[ttype(1:4).comp] = deal('C','I','I','C');
% InitializeData.
[ttype(1:4).RT] = deal([]);
[ttype(1:4).error] = deal(0);
%Run 8 blocks of the four types in random order (32 in all);
trialnumber = 0;
for blocknumber = 1:8
for typenum = randperm(4);
trialnumber = trialnumber + 1;
pause(2)
hfix = text(.5,.5,'+','fontsize',36);
axis off
set(gca,'position',[0 0 1 1])
pause(1)
% Run the trial
if ttype(typenum).side == 'L'
stimposition = .1;
else
stimposition = .9;
end
hstim = text(.1,.5,ttype(typenum).stim,'fontsize',...
72,'fontweight','bold');
tic
waitforbuttonpress
% Record the response
thisRT = toc;
thechar = get(gcf,'CurrentCharacter');
delete([hfix hstim]);
switch thechar
case 'a'
thisResp = 'L';
case ';'
thisResp = 'R';
otherwise
thisResp = 'X'; % illegal key
end
if ttype(typenum).stim == thisResp
ttype(typenum).RT = [ttype(typenum).RT thisRT];
fprintf(rawdatafile,'%2d\t%s\t%s\t%s\t%s\tcorrect\t%5.2f\n',...
trialnumber,...
ttype(typenum).side,...
ttype(typenum).stim,...
ttype(typenum).comp, thisResp, thisRT);
else
ttype(typenum).error = ttype(typenum).error + 1;
beep
fprintf(rawdatafile,'%2d\t%s\t%s\t%s\t%s\terror\t%5.2f\n',...
trialnumber,...
ttype(typenum).side,...
ttype(typenum).stim,...
ttype(typenum).comp, thisResp, thisRT);
end
end
end
save(outfilename,'ttype');
fclose(rawdatafile);
Code 12.6.6:
load SimonData_ef.mat
ttype
type1data = ttype(1)
Output 12.6.6:
ttype =
1x4 struct array with fields:
side
stim
comp
RT
error
type1data =
side: 'L'
stim: 'L'
comp: 'C'
RT: [0.4938 0.6327 0.6572 0.8561 0.6182 0.7189 0.8305]
error: 1
Code 12.6.7:
type SimonData_Rawdata_ef.txt
Output 12.6.7:
Trial side stim comp Key Resp. RT
1 L L C R error 0.73
2 R R C R correct 0.79
3 L R I R correct 0.54
4 R L I L correct 0.51
5 L R I R correct 0.44
6 L L C L correct 0.49
7 R L I R error 0.39
8 R R C R correct 0.68
...data from 24 more trials not shown
Solutions
% Solutions_Chapter_12
% Solutions for selected problems from MATLAB for Behavioral Scientists,
% Second Edition (D. A. Rosenbaum, J. Vaughan, & B. Wyble),
% (c) 2015, Taylor & Francis
% To generate the solution for one problem, copy and run the code for that
% problem in a file or paste it into the Command window. Show the Command
% window to see the results.
% To generate sll the solutions for Chapter 12, save this code as a
% MATLAB script file and run the program.
% To execute Solution_12_7_1, download GUIDEexample_12_7_1_Folder.zip
% from the website, and run the program GUIDEexample_12_7_1.m from that
% folder, which must also contain GUIDEexample_12_7_1.fig.
% To execute Solution_12_7_2, you must copy and paste the code amd run it
% from the editor, because it interacts with the user.
function main % Problems in this chapter may have nested or local
% functions so the ProblemsChapter12 file must itself be a function
clc
commandwindow
close all
Solution_12_7_1 %Run each of the problem functions in turn.
Solution_12_7_2
Solution_12_7_3
Solution_12_7_4
Solution_12_7_5
Solution_12_7_6
end
% 12.7 Practicing user interactions
% Try your hand at the following exercises, using only the methods
% introduced so far in this book or in information given in the
% problems themselves.
% Problem 12.7.1
% Finish the interface implementing the callback routines in
% Guideexample_12.7_1.m, and Guideexample_12_7_1.fig, which you
% will generate using the example of Output.12.7.1 and GUIDE,
% by finding the callback routines in the code generated by GUIDE
% and inserting the appropriate code to respond to the user's actions.
function Solution_12_7_1
fprintf('A solution to problem 12.7.1 is in the script\n')
fprintf(' GUIDEexample_12_7_1.m\n\n')
fprintf('The figure file GUIDEexample_12_7_1.fig\n')
fprintf(' must be in the same folder as the script when it is run!\n\n')
fprintf('Both files can be downloaded from the file\n')
fprintf(' GUIDEexample_12_7_1_Folder.zip.\n\n')
fprintf('See Solution_12_7_2 for a related example of implementation\n')
fprintf(' of callback routines.\n\n')
end %
% Problem 12.7.2
% Combine Code 7.3.6 with Code 12.4.3, to make a GUI-based
% program for computing the number of days in any month.
% Provide the output (e.g., 'February 2008 has 28 days')
% using an appropriate user control, in the same window as the input.
function Solution_12_7_2;
fprintf('\n\n %s\n\n','Output 12.7.2')
fprintf('Function Solution_12_7_2 must be run from the editor because\n')
fprintf('it interacts with the user.\n\n');
% Most of this function is identical to Code 12.4.3; the implementation
% of the computation of days in the month has simply been added at the
% appropriate place, based on Code 7.3.6
% Initialize variables common to main and nested subfunctions
month = 'January';
year = 2001;
% Open the figure for the interface
handletothefigure = figure;
title('Output 12.7.2');
set(gca,'xticklabel',[]);
set(gca,'xtick',[]);
set(gca,'yticklabel',[]);
set(gca,'ytick',[]);
box on;
% Install a popup menu for the months
monthstrings = {
'Month'
'January'
'February'
'March'
'April'
'May'
'June'
'July'
'August'
'September'
'October'
'November'
'December'};
hmonth = uicontrol('Style', 'popupmenu',...
'String',monthstrings,...
'Position', [120 320 100 20],...
'Callback', @monthcallback);
% Install a popup menu for the years
hyear = uicontrol('Style', 'popupmenu',...
'String',...
'Year|2008|2009|2010|2011|2012|2013|2014|2015|2016|2017|2018',...
'Position', [220 320 100 20],...
'Callback', @yearcallback);
% Install an informative text field for the popup controls
uicontrol('Style','text','String','Pick a month and a year: ',...
'Position', [120,360,200,15]);
% Install a GO button
hgobutton = uicontrol('Style','pushbutton',...
'String','Look up days in the month',...
'Position', [120 120 200 40],...
'Callback', @gobuttoncallback);
return % from main
% Callback routines in nested functions:
function monthcallback(source,eventdata)
mylist = (get(source,'String'));
myitem = (get(source,'Value'));
month = char(mylist(myitem))
end
function yearcallback(source,eventdata)
mylist = (get(source,'String'));
myitem = (get(source,'Value'));
year = str2num(mylist(myitem,:))
end
function gobuttoncallback(source,eventdata)
hmsg = msgbox(sprintf(...
'Will compute days for %s, %d\n\n',month, year));
uiwait(hmsg)
% Code from Code 7.3.6 goes here, to compute the days in the month
% Executed as part of the GOBUTTONCALLBACK routine.
% Days_In_A_Month
% Month and year have already been specified in the pulldown menu
% callback routines.
% month = input('Type in the month: ','s');
% year = input('Type in the year (4 digits): ');
switch month
% Thirty days hath September,
% April, June, and November...
case {'September' 'April' 'June' 'November'}
no_of_days = 30;
case 'February'
if rem(year, 4) == 0 & ...
(rem(year, 100) ~= 0 | rem(year, 400) == 0)
no_of_days = 29;
else
no_of_days = 28;
end
% All the rest have thirty-one
otherwise
no_of_days = 31;
end
fprintf('%s %d has %d days.\n', month, year, no_of_days);
hmsg = msgbox(sprintf(...
'%s %d has %d days.\n', month, year, no_of_days));
uiwait(hmsg)
close(handletothefigure)
end
end %function Solution_12_7_2
% Problem 12.7.3
% Using uicontrol or GUIDE, devise an appropriate user
% interface for a program that you have previously written.
function Solution_12_7_3
fprintf('\n\n %s\n','Output 12.7.3')
fprintf('Solution left to the student.\n\n');
end % function Solution_12_7_3
% Problem 12.7.4
% Write a program to analyze the file SimonData_Rawdata_ef.mat
% from the web site (or your own data file from running
% Code 12.6.5, or a similar tab-delimited text file of your
% choosing) and report the reaction times for the four
% conditions. Make the output suitable for transfer to a
% spreadsheet or statistics program.
function Solution_12_7_4
fprintf('\n\n %s\n','Output 12.7.4')
fprintf('Solution left to the student.\n\n');
end % function Solution_12_7_4
% Problem 12.7.5
% Write a program to analyze the file SimonData_Rawdata_ef.txt
% from the web site (or your own data file from running Code
% 12.6.5, or a similar tab-delimited text file of your choosing)
% and report the reaction times for the four conditions. Make
% the output suitable for transfer to a spreadsheet or
% statistics program. Do the results agree exactly with those
% of Problem 12.7.4? Should they? (See Section 7.6 to help you
% get started).
function Solution_12_7_5
fprintf('\n\n %s\n','Output 12.7.5')
fprintf('Solution left to the student.\n\n');
end % function Solution_12_7_5
% Problem 12.7.6
% Present a brief tone of moderate intensity, and allow the
% user to raise or lower the intensity of the tone using the
% up-arrow and down-arrow keys of the keyboard. Instruct the
% user to lower the intensity for the next trial if she hears
% it, and raise the intensity if she does not. Plot the
% psychophysical absolute threshold determined in this way,
% using a staircase graph. Make it possible to vary the frequency
% of the test stimulus. (If you'd like, use a patch of grey
% on a dark grey background, instead, and plot the difference
% threshold as the patch is adjusted brighter and darker. Vary
% the brightness of the background on different trials, and
% determine the ratio between the difference threshold and the
% brightness of the background.) Consider what precautions
% should be taken to ensure that performance is not affected
% by non-sensory factors such as stimulus sequence.
function Solution_12_7_6
fprintf('\n\n %s\n','Output 12.7.6')
fprintf('Solution left to the student.\n\n');
end % function Solution_12_7_6
A solution to problem 12.7.1 is in the script
GUIDEexample_12_7_1.m
The figure file GUIDEexample_12_7_1.fig
must be in the same folder as the script when it is run!
Both files can be downloaded from the file
GUIDEexample_12_7_1_Folder.zip.
See Solution_12_7_2 for a related example of implementation of callback routines.
Output 12.7.2:
Function Solution_12_7_2 must be run from the editor because
it interacts with the user.
Output 12.7.3
Solution left to the student.
Output 12.7.4:
Solution left to the student.
Output 12.7.5
Solution left to the student.
Output 12.7.6:
Solution left to the student.