I am upgrading my Matlab from 2013b to 2018b and have found out that MathWorks have made quite a few changes to the GUI's.
One problem I am having is getting the value of checkbox. The line below is the code I used to use but now it doesn't work.
if get(handles.check_perf_attr,'Value') == 1
The error message is,
Undefined operator '==' for input arguments of type 'cell'.
So I tried the line below to just get the value that is being returned and then apply some logic.
tValue = get(handles.check_perf_attr,'Value');
However tValue is 2 x 1 cell which in (1, 1) = 0 & (2, 1) = 1. I don't really understand this as surely a checkbox can only be one value true (1) or false (0)?
get returns a cell array with values when applied to an array of handles.
Thus, I think your problem is that handles.check_perf_attr contains two handles, not one.
"Dot notation is a new syntax to access object properties starting in R2014b."
so try
if handles.check_perf_attr.Value == 1
or
tValue = handles.check_perf_attr.Value;
Related
So I am creating an app to work out a value based on a series of variables. The variables are:
Gender
Age
Weight
Creatinine
Here's what the app looks like:
In order to simplify the process somewhat I decided to make the gender selection a dropdown menu, this has caused me some issues since I have it setup like so:
And the maths associated with the button looks like so:
function CalculateButtonPushed(app, event)
gender = app.PatientGenderDropDown.Value ;
age = app.PatientAgeEditField.Value ;
weight = app.LeanBodyWeightEditField.Value ;
serum = app.SerumCreatinineEditField.Value ;
final = (gender*(age)*weight) / (serum) ;
app.ResultEditField.Value = final ;
end
end
Running this gives the following error:
Error using
matlab.ui.control.internal.model.AbstractNumericComponent/set.Value
(line 104) 'Value' must be numeric, such as 10.
As far as I am aware, the values I input into ItemsData are numeric values. Have I missed something or is there a better way to do this?
If you put a breakpoint in the offending file on the appropriate line (by running the below code),
dbstop in uicomponents\+matlab\+ui\+control\+internal\+model\AbstractNumericComponent.m at 87
you could see the following in your workspace, after clicking the button:
There are two separate problems here, both of which can be identified by looking at the newValue validation code (appearing in AbstractNumericComponent.m):
% newValue should be a numeric value.
% NaN, Inf, empty are not accepted
validateattributes(...
newValue, ...
{'numeric'}, ...
{'scalar', 'real', 'nonempty'} ...
);
Here are the issues:
The new value is a vector of NaN.
The reason for this is in this line:
final = (gender*(age)*weight) / (serum) ;
where serum has a value of 0 - so this is the first thing you should take care of.
The new value is a vector of NaN.
This is a separate problem, since the set.Value function (which is implicitly called when you assign something into the Value field), is expecting a scalar. This happens because gender is a 1x4 char array - so it's treated as 4 separate numbers (i.e. the assumption about ItemsData being a numeric is incorrect). The simplest solution in this case would be to str2double it before use. Alternatively, store the data in another location
(such as a private attribute of the figure), making sure it's numeric.
I want to find and save all values greater than 0 in an array and save them in a variable called "times". How do I do that? And what is the difference between saving the indices of those cells versus the actual values of the cells?
This is what I have tried, but it must be worng because I get the error:
Undefined operator '>' for input arguments of type
'cell'.
clear all, close all
[num,txt,raw] = xlsread('test.xlsx');
times = find(raw(:,5)>0)
To access the contents of a cell you must use {} instead of ():
idx = find([raw{:, 5}] > 0);
But this gives you the index of the cells of raw containing a positive value. If you want the values instead, you can access them and collect them in a numeric array in this way:
times = [raw{idx, 5}];
In most OO languages, where variables may point to objects, they may also have a null value, which is highly convenient.
In Matlab, I have a function which parses a command, and then returns a cell array, or false (which is equal to zero — which is another common pattern) if it fails:
function re = parse(s)
...
if (invalid)
re = false;
return;
end
end
The problem is that when I check the result, it gives an error:
re = parse(s);
if (false == re)
Undefined function 'eq' for input arguments of type 'cell'.
I've written a function to check it without an error: strcmp('logical', class(re)) && false == re, but that seems to be really slow for use in hot areas of the code, and also inconvenient if I have to add this function to every M file I'm writing.
Using NaN is even worse, because besides throwing that error, it also isn't equal to itself.
What's a better alternative for use with this pattern?
You can use the isequal function to compare any two items without causing that error. For example:
if isequal (re, false)
%code here
end
A good alternative is to use the empty array: [] and isempty(re) to check. This doesn't throw the error.
Reference: http://www.mathworks.com.au/matlabcentral/newsreader/view_thread/148764
If you can change the function parse one solution would be to return two output arguments [re status] = parse(s), where status would be logical variable. Set it to true in case of success, and to false otherwise.
I would use the empty cell array {} if it is not a valid result otherwise. Using empty matrices is MATLAB standard (see Evgeni Sergeev's answer), but using an empty cell array instead of an empty numeric array ensures that you'll always end up with the same type of result.
If, on the other hand, the empty cell array {} is a valid result of your function, then I'd use an exception to signalize a problem:
if invalid
error('Parse:InvalidArgumentError', 'The input is invalid.');
end
Make sure to use an appropriate error ID (first argument to error) so that you can catch exactly that exception when you call the function:
try:
result = parse(something);
catch ME
if strcmp(ME.identifier, 'Parse:InvalidArgumentError')
fprintf('Ooops\n');
else
% Some other error
ME.rethrow();
end
end
I think the problem is that matlab functions don't return pointers but copies of values.
IMHO the best best approach would be to define your own "pointer" class. Inside you can define an "isNull()" command or even override comparison to produce the behavior you desire.
the program is working perfectly but when i am changing it to function the follwing error is beeing displayed:
[Parent1index, Parent1Position, alldcel] = Parent1n(TotalnoOfGrids, noOfNodes, Penalties, test)
??? Index exceeds matrix dimensions.
Error in ==> Parent1n at 10
[~,index]=min(alldcel{t});
Because alldcell{t} may not exist for some values of t if the condition to assign values to it in
if Penalties{t}(r)== 0;
alldcel{t}(r)=inf;
end
is never satisfied. Assume for some t that all values of Penalties{t} are different than zero. Then you would never assign inf to alldcell{t}. That means, you are only extending the cell array alldcell when Penalties{t} is zero for some r. If the condition is never satisfied, alldcell{t} will not exist and asking for it will give you a cell array error.
You should at least initialize it using alldcell = cell(TotalnoOfGrids,1).
Also, comparing for equality to zero using a==0 is not a good idea. You should use abs(a)<tol for some small value tol.
ok with this code the functiion worked:if Penalties{t}(r)> 0;
alldcel {t}(r)=alldcel{t}(r);
else alldcel {t}(r)=inf; but interchanging if statement with else did not
I have no idea what's going on here. I'm using R2006b. Any chance someone out there with a newer version could test to see if they get the same behavior, before I file a bug report?
code: (bug1.m)
function bug1
S = struct('nothing',{},'something',{});
add_something(S, 'boing'); % does what I expect
add_something(S.something,'test'); % weird behavior
end
function add_something(X,str)
disp('X=');
disp(X);
disp('str=');
disp(str);
end
output:
>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.
Error in ==> bug1>add_something at 11
disp(str);
Error in ==> bug1 at 4
add_something(S.something,'test');
It looks like the emptiness/nothingness of S.something allows it to shift the arguments for a function call. This seems like Very Bad Behavior. In the short term I want to find away around it (I'm trying to make a function that adds items to an initially empty cell array that's a member of a structure).
Edit:
Corollary question: so there's no way to construct a struct literal containing any empty cell arrays?
As you already discovered yourself, this isn't a bug but a "feature". In other words, it is the normal behavior of the STRUCT function. If you pass empty cell arrays as field values to STRUCT, it assumes you want an empty structure array with the given field names.
>> s=struct('a',{},'b',{})
s =
0x0 struct array with fields:
a
b
To pass an empty cell array as an actual field value, you would do the following:
>> s = struct('a',{{}},'b',{{}})
s =
a: {}
b: {}
Incidentally, any time you want to set a field value to a cell array using STRUCT requires that you encompass it in another cell array. For example, this creates a single structure element with fields that contain a cell array and a vector:
>> s = struct('strings',{{'hello','yes'}},'lengths',[5 3])
s =
strings: {'hello' 'yes'}
lengths: [5 3]
But this creates an array of two structure elements, distributing the cell array but replicating the vector:
>> s = struct('strings',{'hello','yes'},'lengths',[5 3])
s =
1x2 struct array with fields:
strings
lengths
>> s(1)
ans =
strings: 'hello'
lengths: [5 3]
>> s(2)
ans =
strings: 'yes'
lengths: [5 3]
ARGH... I think I found the answer. struct() has multiple behaviors, including:
Note If any of the values fields is
an empty cell array {}, the MATLAB
software creates an empty structure
array in which all fields are also
empty.
and apparently if you pass a member of a 0x0 structure as an argument, it's like some kind of empty phantom that doesn't really show up in the argument list. (that's still probably a bug)
bug2.m:
function bug2(arg1, arg2)
disp(sprintf('number of arguments = %d\narg1 = ', nargin));
disp(arg1);
test case:
>> nothing = struct('something',{})
nothing =
0x0 struct array with fields:
something
>> bug2(nothing,'there')
number of arguments = 2
arg1 =
>> bug2(nothing.something,'there')
number of arguments = 1
arg1 =
there
This behaviour persists in 2008b, and is in fact not really a bug (although i wouldn't say the designers intended for it):
When you step into add_something(S,'boing') and watch the first argument (say by selecting it and pressing F9), you'd get some output relating to the empty structure S.
Step into add_something(S.something,'test') and watch the first argument, and you'd see it's in fact interpreted as 'test' !
The syntax struct.fieldname is designed to return an object of type 'comma separated list'. Functions in matlab are designed to receive an object of this exact type: the argument names are given to the values in the list, in the order they are passed. In your case, since the first argument is an empty list, the comma-separated-list the function receives starts really at the second value you pass - namely, 'test'.
Output is identical in R2008b:
>> bug1
X=
str=
boing
X=
test
str=
??? Input argument "str" is undefined.
Error in ==> bug1>add_something at 11
disp(str);
Error in ==> bug1 at 4
add_something(S.something,'test'); % weird behavior