Avoiding repetition when testing for empty fields in an if statement - matlab

I'm wondering if there is a way to avoid repeating myself in the code below:
if (isfield(A,'test') && isempty(A.test)) || ~isfield(A,'test')
statement1
else
statement2
end
alternatively, this is equivalent to:
if isfield(A,'test')
if isempty(A.test)
statement1
else
statement2
else
statement1
end
In the first example, I've repeated the isfield condition and in the second statement1 is repeated. Is there a neat way to do this without repetition?
Thanks,
Rich

Simply
if isfield(A,'test') && ~isempty(A.test)
statement2
else
statement1
end
is enough.
Because using the operator && the statement isempty(A.test) is just tested if isfield(A,'test') is true, otherwise it is skipped anyway.
expr1 && expr2 represents a logical AND operation that employs
short-circuiting behavior. With short-circuiting, the second operand
expr2 is evaluated only when the result is not fully determined by the
first operand expr1. For example, if expr1 = 0, then the following
statement evaluates to false, regardless of the value of expr2.
Testing:
A = struct % Case1
%A.test = 5 % Case2
%A = 5 % Case3
if isfield(A,'test')
if isempty(A.test)
disp(1)
else
disp(2)
end
else
disp(1)
end
if isfield(A,'test') && ~isempty(A.test)
disp(2)
else
disp(1)
end
For all 3 testing cases the results are the same.

I think either
if ~isfield(A,'test') || isempty(A.test))
statement1
else
statement2
end
or
if isfield(A,'test') && isempty(A.test)
statement2
else
statement1
end
will do what you need.
MATLAB's || and && operators short-circuit, so if the first operands evaluate to true (in the first case) or false (in the second case), the second operand is not evaluated and won't cause an error.

Don't think there's any other way, other than storing the condition in a boolean variable and passing it on, like this -
cond1 = isfield(A,'test');
if (cond1 && isempty(A.test) || ~cond1)
statement1
else
statement2
end
Though I must add, I would rather prefer the IF-ELSE style that you have adopted in your second approach. The case when 'test' field doesn't exist for A, it would throw error if you do only isempty(A.test), but with the double checking of that alongwith isfield(A,'test'), I think MATLAB ignores the error.

Related

Operands to the || and && operators must be convertible to logical scalar values. Symbolic vars

Operands to the || and && operators must be convertible to logical scalar values.
the code is to evaluate the editfield if they are empty, there an equation is inserted in each one; what I am trying to do is that if the fields of the editfield are empty, the error will appear, but if not, the code will be executed; the error I mention in the title
cla;
syms x y ;
Eqn1=str2sym(app.Ecu1.Value);
Eqn2=str2sym(app.Ecu2.Value);
if (isnan(Eqn1) || isnan(Eqn2))
errordlg('File not found','File Error');
else
%ejecute code
end

Trying to understand if statements in Scala

I am trying to understand why my code doesn't work! I am trying to solve the classic balance parentheses problem and Im getting a no such element on my third if statement which doesn't make sense to me because I thought my second if statement would avoid that case but I dont think my second if statement is returning?
def balance(chars: List[Char]): Boolean = {
def check(left: Int,right: List[Char]): Boolean = {
if (left < 0) false
if (right.isEmpty) left == 0
if (right.head == ')') check(left + 1, right.tail)
else check(left - 1, right.tail)
}
check(0,chars.filter(x => (x == ')') || (x == '(')))
}
Following up on my comment. I don't believe that you are actually getting a Null Pointer exception. Scala doesn't encourage the use of nulls and I don't know of any case where the standard library will return a null. Nulls are encapsulated by Option.None in Scala (or see upcoming explicit nulls in Scala 3) and even when you are integrating with a Java library, it is recommended that you wrap the null behavior in an option.
That being said, under the assumption that you are getting a No Such Element Exception in reality, let's look at you code.
Understanding the return behavior in Scala
A Scala function will take the last value in it's body as it's return value. In your case it is this block
if (right.head == ')') check(left + 1, right.tail)
else check(left - 1, right.tail)
Since the previous if blocks are not conditionally linked together all 3 of them will be evaluated. Even if one of the first two evaluates the true, Scala will NOT return and continue to evaluate because it sees more code in the function body it has not computed yet.
So in this case even if the second condition is true, the third one still gets evaluated.
Use the full ternary syntax and add else
if (left < 0) false else
if (right.isEmpty) left == 0 else
if (right.head == ')') check(left + 1, right.tail)
else check(left - 1, right.tail)
More on ternary syntax here
Let us desugar check definition a little bit:
def check(...) =
{
if (left < 0) false else (); // expression 1
if (right.isEmpty) left == 0 else (); // expression 2
return if (right.head == ')') check(...) else check(...); // expression 3 (last expression)
}
Note how the semicolons ; make it clear we have three separate expressions in the expression block, and only the last one is passed to return. Now the two key concepts to understand are
conditional expressions if (𝑒1) 𝑒2 else 𝑒3 are first-class values (and not control statements)
the "returned" value of the whole block expression is only the value of the last expression in the block
Hence to fix the issue, as suggested by others, we need to connect the three separate expressions into a single expression of the form if...else if ... else if ... else.

Why does this if statement give an output despite the && conditions not being satisfied?

I have been trying to execute a piece of code with some if conditions. This is a simple version of it.
X=100;Y=100;
if ((((X+1) && (Y+1))<=99) && (((X+1) && (Y+1))<=102))
disp(X);
end
Despite both X and Y not satisfying the first condition, I still get the output as 100. I have tried all combinations of & and && to make the and operations in the work. I checked the difference between the two and I found that & is a logical bit-wise operator while && is a short-circuit operator, which probably doesn't change much in this context. What's the error with this syntax?
Of course the code works when I do this:
X=100;Y=100;
if (X+1)<=99 && (Y+1)<=99 && (((X+1) && (Y+1))<=102)
disp(X);
end
But this is so inefficient when there are lot of conditions and each sub-condition must include the constraints. I'm sure this must be answered somewhere and this question might be a duplicate, so please point me to the answer.
So it looks like you understand what (X+1)<=99 && (Y+1)<=99 does. Let's look at ((X+1) && (Y+1))<=99:
&& requires a logical value on each side. a && b will turn a and b into logicals, effectively becoming a~=0 && b~=0. Thus:
((X+1) && (Y+1) ) <= 99
((X+1)~=0 && (Y+1)~=0) <= 99
( true && true ) <= 99
1 <= 99
true
Of course the truth value of (X+1)~=0 and (Y+1)~=0 could be different, but here you see this. In MATLAB, true is equal to 1 in a non-logical context, as when compared to 99.
If you want to simplify this expression, use max instead of &&:
X=100;Y=100;
if max(X+1,Y+1)<=99 && max(X+1,Y+1)<=102
disp(X);
end
If the max of a and b is smaller than 99, then both a and b are smaller than 99.
(Obviously, the statement can be further simplified to if max(X+1,Y+1)<=102, since if the second inequality holds than so must the first.)

Comparing Multiple File Types in an if Statement

I am importing a file into a function using [filepath, name, ext]=fileparts(thisFile);. I would then like to use a series of if statements that will operate on the file depending on its type; however, come files will have the same initial set up and so I would like to be able to include them all in an if statement. My current implementation: elseif (ext == '.s3p'). If I put in something like: elseif (ext == '.s2p' || '.s3p') the compiler whines,
Operands to the || and && operators must be convertible to logical scalar values.
You see my logic. Is there anything that I can do to make this work?
Thank you in advance!
You probably want strcmp, not ==. With a==b you get element-wise comparison. So you get a logical vector as result; and if a and b have different number of characters you get an error.
The fact that the output of == is a logical vector of element-wise comparisons is what causes the m-lint message. || and && require scalar arguments.
Lastly, in (ext == '.s2p' || '.s3p') you probably meant (ext == '.s2p' || ext == '.s3p').
Combining all of the above:
elseif strcmp(ext,'.s2p') || strcmp(ext,'.s3p')
For clarity and readability, you may prefer to use the ismember function with a cell array of the extensions to compare with:
elseif ismember(ext, {'.s2p' ,'.s3p'})
or, as pointed out by Cris Luengo,
elseif any(strcmp(ext, {'.s2p', '.s3p'}))
Better yet, instead of a series of elseif statements you may prefer to use switch, which implicitly applies strcmp / ismember for each case:
switch ext
case {'sp2', 'sp3'}
% Do stuff
case {'aaa', 'bbb'}
% Do stuff
otherwise
error('Unrecognized extension')
end

Nested-if statements

If I have this layout
if (condition)
if (condition)
do_something
else
do_something1
else
do_something1
end
end
Is there a way that when I get to the first else, that it runs do_something1 without me having to retype the code for do_something1? So I'd like to jump from the first else, to the second one
If I understand your question correctly, you can replace:
if (condition1)
if (condition2)
do_something
else
do_something1
else
do_something1
end
end
with:
if (condition1 & condition2)
do_something
else
do_something1
end
You could use something like
if(condition && condition{
doSth.
}else{
doSth2
}
&& is a "and" Java Operator look for "and" Operator for Matlab, there is one for sure.