Here is my code:
df.where((F.col("A") != F.col("B")) | \
(F.col("A").isNotNull()) | \
(F.col("C") == F.col("D"))).show()
When I do this, I do see instances that contradict some of the conditions above. Now, when I structure the code like this, it runs successfully:
df.where((F.col("A") != F.col("B")))\
.where((F.col("A").isNotNull()))\
.where((F.col("C") == F.col("D")))
The first snipper uses the | to combine the three conditions.However, the | checks if any of the conditions evaluate to true rather than all of them.
However, chaining using where clause is equivalent to combining the conditions using and.
Hence, the snippets in the code are not equivalent and produce different results.
For equivalence, you first snipper will become
df.where((F.col("A") != F.col("B")) & \
(F.col("A").isNotNull()) & \
(F.col("C") == F.col("D"))).show()
Related
I'm using strfind with an 'or' comparison like so:
name='hello';
if strfind(name,'hello') | strfind(name,'hi')
disp('yes!')
end
>> yes!
The if statement must evaluate as true, since yes! is displayed.
In contrast, MATLAB doesn't return yes! if the statements are swapped:
if strfind(name,'hi') | strfind(name,'hello')
disp('yes!')
end
Why?
This is because short-circuiting. Short-circuited logical operators are a thing to speed up code. You can have
if veryShort | superlongComputation
so what MATLAB does is first evaluate veryShort and if it is true, then no need to evaluate the second one! The if condition is already met.
In your case strfind(name,'hello') returns 1, but strfind(name,'hi') returns [].
In the first example, as the first thing evaluated returns 1, you get to the display. However in the second case, it returns [], therefore MATLAB evaluates the second thing in the if, and returns 1. Then MATLAB applies the or operations where [] | 1 is an 0x0 empty logical array, so the if is not true.
Note, generally you want to use || to enforce short-circuiting, but | also does it, if it is inside a while or an if:
https://uk.mathworks.com/matlabcentral/answers/99518-is-the-logical-operator-in-matlab-a-short-circuit-operator
Both of the following conditions are empty []:
name='hello';
strfind(name,'hello') | strfind(name,'hi'); % = []
strfind(name,'hi') | strfind(name,'hello'); % = []
As referenced in Ander's answer, the | operator is using short circuiting to skip evaluation of the second condition if the first is false (or empty).
Some quick debugging will give you better understanding if we ignore short-circuiting:
strfind(name,'hi'); % = []
strfind(name,'hello'); % = 1
In both cases you are doing "if empty or non-zero", which is empty and "if []" is false (that conditional statement won't be executed).
What you want to use to be explicit is something like this:
if ~isempty(strfind(name, 'hello')) & ~isempty(strfind(name, 'hi'))
disp('yes!')
end
Here, we guarantee that everything being evaluated in the if statement is a Boolean variable, not empty or an index like strfind returns, so unexpected results are less likely.
There are simpler methods, like using strcmp or ismember if your strings should match exactly. Or contains if you have R2016b or newer:
if contains('hello', {'hello','hi'})
disp('yes!');
end
I'm trying to extract attributes from a regular XML structure; it seems natural to first exclude the elements for which a particular attribute is missing.
I don't know why the following doesn't work (see answer for why I ever got the idea to test vs. null):
val test = <top><el attr="1"></el><el></el><el attr="2"></el></top>
test.child.filter(_ \ "#attr" != null).map(_ \ "#attr")
// ArrayBuffer(1, NodeSeq(), 2)
Why is the middle element still there after the filter?
I've confirmed it's not operator precedence:
test.child.filter(x => (x \ "#attr") != null).map(_ \ "#attr")
// ArrayBuffer(1, NodeSeq(), 2)
Alternatively (assuming this is optimized internally), how could I exclude the NodeSeq() elements after the map step?
Just figured this out. filter wasn't return null, but NodeSeq(), so that the following works:
test.child.filter(_ \ "#attr" != scala.xml.NodeSeq.Empty).map(_ \ "#attr")
// ArrayBuffer(1, 2)
Followed this Q&A to discover how to create the NodeSeq() object by hand
I discovered my problem ultimately derived from crossing my own wires. I initially had been using the following:
test.child.map(_.attributes("attr"))
// ArrayBuffer(1, null, 2)
Which is where I got the idea to test vs. null originally. Of course, if I had stuck with that, my initial approach would have worked:
test.child.filter(_.attributes("attr") != null).map(_ \ "#attr")
// ArrayBuffer(1, 2)
Doxygen 1.8.8 does "warning: preprocessing issue while doing constant expression evaluation"
It can see "iso646.h" ok (it's used all over for logical expressions in C code with no warnings), the warning is only in conditional macro expension like:
#if ((FILENO_A == FILENO_P_AUTROKEEPER_A) or \
(FILENO_A == FILENO_P_AUTROKEEPER_F1_A) or \
(FILENO_A == FILENO_P_AUTROKEEPER_FA_A) or \
(FILENO_A == FILENO_P_AUTROKEEPER_FE_A) or \
(FILENO_A == FILENO_P_AUTROKEEPER_FC_A))
... External functions in P_AutroKeeper_f1.c (GENERAL, also from PROCESS)
#end
We have tried quite much here!-(
If I want to ensure that an if statement only executes if BOTH of two conditions are true, should I be using & or && between the clauses of the statement?
For example, should I use
if a == 5 & b == 4
or
if a == 5 && b == 4
I understand that the former is elementwise and the latter is capable of short-circuiting but am not clear on what this means.
For a scalar boolean condition I'd recommend you use &&. Short-circuiting means the second condition isn't evaluated if the first is false, but then you know the result is false anyway. Either & or && one will be true only if both sides of the expression are true, but & can return a matrix result if one of the operands is a matrix.
Also, I believe in Matlab comparisons should be done with ==, not with = (assignment).
I have hack I need to employ under these conditions:
It's the last page of data.
It's not the first page, either.
There's not a page-size-even number of data items.
So I tried this code:
my $use_hack =
$last_page_number == $current_page_number and
$page_number != 1 and
$total_items % $items_per_page != 0;
And I keep getting this warning Useless use of numeric ne (!=) in void context about the last condition and it's evaluating true when $total_items % $items_per_page = 0.
say 'NOT EVEN' if $total_items % $items_per_page != 0; #works properly, though...
I've tried various combinations of parentheses to get it right, but nothing seems to work.
Okay, operator precedence. and has almost the lowest precedence of any operator in Perl, so Perl was evaluating the expression in a weird order. Switching to && instead got me correct results. Blarg.
The More You Know.
EDIT:
As Philip Potter pointed out below, Perl Best Practices (p.70) recommends always using &&,||, ! for boolean conditions - limiting and or and not for control flow because of their low precedence. (And it even goes so far as to say to never use and and not, only or for fallback logic.)
Thanks, everybody!
Enclose the RHS in parenthesis:
my $use_hack = (
$last_page_number == $current_page_number and
$page_number != 1 and
$total_items % $items_per_page != 0);
Assignment (=) is having higher precedence when compared to and operator. You can take a look at the Perl Operator Precedence.