I am trying to handle exceptions gracefully such that when a user enters a character, when a number is expected, he is notified with a custom warning/message.
I know that the try, catch has the following syntax:
try
statements
catch exception
statements
end
I have been trying something like this, to no avail:
number = input('Enter number');
try
assert(isnumeric(number));
catch ME
warning('NOT A NUMBER');
end
I do not understand why the above code fails since assert if it is false, displays the error message 'Assertion Failed'.
I know that using try and catch is a bit of a sledgehammer approach, but I would like to understand how to implement the above functionality. Any tips would be appreciated.
From the help command:
input Prompt for user input.
RESULT = input(PROMPT) displays the PROMPT string on the screen, waits
for input from the keyboard, evaluates any expressions in the input,
and returns the value in RESULT. To evaluate expressions, input accesses
variables in the current workspace. If you press the return key without
entering anything, input returns an empty matrix.
Therefore if a user types in "goat" MATLAB will try to evaluate the variable named "goat". That is not helpful for this problem.
However looking further down the help command:
STR = input(PROMPT,'s') returns the entered text as a MATLAB string,
without evaluating expressions.
This is what is more applicable to your problem.
number = input('Enter number', 's');
try
assert(~isnan(str2double(number)));
catch ME
warning('NOT A NUMBER');
end
I have a code in matlab (~1000 lines) that constists of about 15 functions. The code runs fine with each function as a different script, but I want to put them all into one file so I can use the publish function more easily. However, when I put them all together my 'main' function isn't recognizing the local functions. Here's what it looks like:
function full_function()
...
values = fvalues(0);
...
end
function values = fvalues(state)
...
end
When I try to run it, it gives me
"Undefined function 'fvalues' for input arguments
of type 'double'.
Error in full_function (line 32)
values = fvalues(0);"
I've looked all over for how to do local functions and I have no idea what I'm doing wrong. If I right-click on fvalues and hit 'open' it even brings me to the correct portion of the code, so I have no idea why full_function cannot read it. Please help! Thanks.
I'm looking to both catch and handle the "unassignedOuputs" error in Matlab. More specifically, looking at the following code:
try
[out1,out2]= somefunction(in1,in2);
catch err
if strcmp(err.identifier,'MATLAB:unassignedOutputs')
<some code>
else
rethrow(err);
end
end
If "somefunction" does not assign out2 and the resulting error is caught, is it possible to somehow retrieve the rest of the outputs from the function (in this case out1)? If not, is there a way to re-call the function ignoring that value so the function will not throw the error?
As far as I can tell, there is no way to retrieve variables once the function has been terminated with this error. For the case when the first output is produced but not the second, you could retry it with just one output, naively something like:
try
[out1,out2]= somefunction(in1,in2);
catch err
if strcmp(err.identifier,'MATLAB:unassignedOutputs')
try
out2 = [];
out1 = somefunction(in1, in2);
catch err2
% rethrow original error
rethrow(err)
end
else
rethrow(err);
end
end
To display a message saying which output wasn't assigned, you'd have to parse err.message (although the default message itself should be reasonably clear).
But getting this to work if you have more than two outputs, and you don't know which might have not been properly defined, would not be simple. And if the first output is not defined, this won't work at all. In that case you would have to, I think, edit the function itself.
If the specific use case is checking a bunch of student codes which all take the same inputs and provide the same outputs, an alternative option would be to provide them with a function template which contains a check at the end if the outputs exist, and if not sets them to empty and displays your custom message.
I created an UItable in Matlab which I fill with various values and options.
It looks like:
the corresponding code is the following:
selector_1 = { 'A'; 'B' ; 'C' };
selector_2 = { 'A.1'; 'A.2'; 'A.3'; ...
'B.1'; 'B.2'; 'B.3'; ...
'C.1'; 'C.2'; 'C.3' };
rows = 5;
f = figure('name','Configuration of output','Position',[200 200 430 25+rows*20],'numbertitle','off','MenuBar','none');
dat = {'select outputfile...', 'select identifier...', 'Specifier', 'Index'};
dat = repmat(dat,rows,1);
columnname = {'Output file ',...
'Identifier ',...
'Specifier ', 'Index'};
columnformat = { {selector_1{:}}, {selector_2{:}}, 'char', 'numeric' };
columneditable = [true true true true];
t = uitable('Units','normalized','Position',...
[0 0 1 1], 'Data', dat,...
'ColumnName', columnname,...
'ColumnFormat', columnformat,...
'ColumnEditable', columneditable,...
'RowName',[]);
set(t, 'Data', dat,'celleditcallback','get(t,''Data'')');
So I run the code and the figure is open. The underlying script has therefore finished.
When I now edit the table my uitable object is changed and after I finished I can get my final configuration with:
finalconfig = get(t,'Data');
But the thing is I need manually type this line, because my script has already finished. If I put this line at the end of my script, I get an error.
So I thought about using the following loop, to detect when I close the table and to store the last configuration
while ~isempty(findobj('name','Configuration of output'))
% some action
end
finalconfig = get(t,'Data');
And I tried everything to put inside the loop, the whole script, just the set command including the celleditcallback, and other things, but nothing worked. Either my script get stucked inside the loop or the display of my table is not updated when I edit a value. I also tried drawnow at different positions. How one handles this situation? How can I automatically store my final results?
I assume "closing the window" is the best action to detect, as I don't think I could implement a "save" button. I also tried to create a gui using GUIDE but got completely lost, I hope to solve it without.
Edit:
I was now able to implement a "save"-button and tried the callback as follows:
uimenu('Label','Save configuration','Callback',#saveConfig);
function saveConfig(~,~)
output = get(t,'Data',);
save([pwd 'output.mat'],'output');
end
also I implemented a custom CloseRequestFcn as suggested by Lucius Domitius Ahenobarbus. But then I have either one of the following problems:
1)
I define everything as a script, everything works fine, but I need to define functions like #saveConfig (actually my favorite) or #my_Closefcn as a unique function-file in my workspace and I have a hard time to pass the right parameters as dat always remains the same, even though it actually gets changend.
(The example from the mathworks site works! But it doesn't need additional parameters.)
2) When I use
function configuration
% my script from above
end
I can implement #saveConfig or #my_Closefcn directly (nested) and I guess the passing of the parameters would work fine. But the editing of my table does not work anymore, throwing the following error:
Error using handle.handle/get
Invalid or deleted object.
Error while evaluating uitable CellEditCallback
How to solve that?
Now that I know that I can even add buttons to an uitable I REALLY like to avoid GUIDE.
My code above is executable, so I'd be glad if you try it to see what my actual problem is, as it is hard to describe.
depending on using GUIDE or not:
use the CloseRequestFcn->
without GUIDE use:
%write your own CloseRequestFcn and set the figure CloseRequest-Callback to it:
set(gcf,'CloseRequestFcn',#my_closefcn)
%use gcf or the handle of the figure directly
and define my_closefcn including a delete statement for the figure-handle, else the figure will not close :)
See the docs for more information about "Redefining the CloseRequestFcn".
with GUIDE:
you can edit the CloseRequestFcn by inspecting the figure. There is a field called CloseRequestFcn that will create the function automatically and you dont need to take care about getting the handle. It will look like this:
function figure1_CloseRequestFcn(hObject, eventdata, handles)
% hObject handle to figure1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hint: delete(hObject) closes the figure
delete(hObject);
Now BEFORE deleting the figure, you should be able to get the data of the uitable (if you have the handle) and I would suggest to just assign the data to the base workspace, like:
assignin('base', 'finalTableData', get(myTableHandle,'Data'));
EDIT
as I was not clear enough, see this example:
(use within one single script)->
function test
h=figure;
x=1:10;
mytable=uitable(h,'Data',x);
set(h,'CloseRequestFcn',#myCloseFcn)
%give a unique Tag:
set(h,'Tag', 'myTag')
set(mytable,'Tag','myTableTag')
end
function myCloseFcn(~,~)
myfigure=findobj('Tag','myTag');
myData=get(findobj(myfigure,'Tag','myTableTag'),'Data')
assignin('base','myTestData',myData)
delete(myfigure)
end
in fact, there is no need to take care for the parameters of your Closereq-Callback, if you know how to find the handle of the figure! Just give something to your figure/uitable that you are able to identify it later on. I used 'Tag', because the first thing I would think of, but there would be other parameters as well.
There are only two differences I can think of between running the code directly after the code, or inside the code.
1. Scope
Perhaps you are actually working with functions, rather than scripts. In this case the problem may be that inside your function, something you need is out of scope.
2. Timing
Though it is rare, sometimes the computer may seem to be finished, whilst it is actually still busy (for a few milliseconds or so).
Here are the steps to a general approach:
Make sure there is a trivial line at the place where you want to insert your command (1==1 for example)
Put a breakpoint at the line
Once matlab stops at the breakpoint, wait a second and try to run your command.
If it works I would bet on problem number 2. try placing a pause(1) before your command and see whether it helps.
If it doesn't work you are likely meeting problem number 1. Now it becomes a matter of finding the right place to put your command. And if the command cannot be put somewhere else in the code, perhaps try an ugly evalin(,'base'). However, the latter should really be considered a workaround rather than a solution.
I am getting an error when running matlab code. Here I am trying to use one of the outputs of previous code as input to my new code.
??? Reference to non-existent field 'y1'.
Can anyone help me?
A good practice might be to check if the field exists before accessing it:
if isfield( s, 'y1' )
% s.y1 exists - you may access it
s.y1
else
% s.y1 does not exist - what are you going to do about it?
end
To take Edric's comment into account, another possible way is
try
% access y1
s.y1
catch em
% verify that the error indeed stems from non-existant field
if strcmp(em.identifier, 'MATLAB:nonExistentField')
fprintf(1, 'field y1 does not exist...\n');
else
throw( em ); % different error - handle by caller?
end
end
Have you used the command load to load data from file(s)?
if yes, this function overwrite your current variables, therefore, they become non-existent, so when you call, it instead of using:
load ('filename');
use:
f=load ('filename');
now, to refer to any variable inside the loaded file use f.varname, for
example if there is a network called net saved within the loaded data you may use it like:
a = f.net(fv);
I would first explain my situation and then give the solution.
I first save a variable op, it is a struct , its name is coef.mat;
I load this variable using coef = load( file_path, '-mat');
In a new function, I pass variable coef to it as a parameter, at here, the error Reference to non-existent field pops out.
My solution:
Just replace coef with coef.op, then pass it to the function, it will work.
So, I think the reason behind is that: the struct was saved as a variable, when you use load and want to acess the origin variable, you need point it out directly using dot(.) operation, you can directly open the variable in Matlab workspace and find out what it wraps inside the variable.
In your case, if your the outputs of previous code is a struct(It's my guess, but you haven't pointed out) and you saved it as MyStruct, you load it as MyInput = load(MyStruct), then when use it as function's parameter, it should be MyInput.y1.
Hops it would work!
At first load it on command window and observe the workspace window. You can see the structure name. It will work by accessing structure name. Example:
lm=load('data.mat');
disp(lm.SAMPLE.X);
Here SAMPLE is the structure name and X is a member of the structure