I am creating a "Basic Search" bar that users can type in terms.
I am unsure of the order of operations for boolean logic.
If someone types terms(With no quotes):
A and B or C
What is the correct way to treat this?
(A and B) or (C)
OR
(A) and (B or C)
Wikipedia to the rescue, this should help:
http://en.wikipedia.org/wiki/Order_of_operations#Programming_languages
From the looks of things, it would appear that AND takes precedence over OR in most languages.
Based on Quetzalcoatl's response, the correct answer for the OP question is:
(A and B) or C
That's the equivalent for "A and B or C"
Although Quetzalcoatl's link (http://en.wikipedia.org/wiki/Order_of_operations#Programming_languages) speaks about programming languages (as this site does), a more common precedence is specified for general logic in wikipedia:
https://en.wikipedia.org/wiki/Logical_connective#Order_of_precedence
(A) and (B or C)
and means intersection or "like" union
Like in math
"AND" is like a multiplier and "OR" like a sum
in a "truth table"
OR
A | B | result
true | true | true
true | false | true
true | false | true
false | false | false
AND
A | B | result
true | true | true
true | false | false
true | false | false
false | false | false
Related
I am using excel 2010 and I am having for each customer id certain events that can be true or false.
Furthermore a user can configure the order in which the true events for a customer ID should be given back.
So for example I have the following customers with the following events:
| Customer ID | Event 1 | Event 2 | Event 3 | Event 4 |
|------------- |--------- |--------- |--------- |--------- |
| 1 | TRUE | FALSE | TRUE | FALSE |
| 2 | FALSE | TRUE | FALSE | FALSE |
| 3 | TRUE | TRUE | TRUE | TRUE |
| 4 | FALSE | TRUE | FALSE | FALSE |
| 5 | TRUE | FALSE | TRUE | TRUE |
| 6 | TRUE | TRUE | FALSE | FALSE |
| 8 | FALSE | FALSE | TRUE | TRUE |
| 9 | TRUE | TRUE | FALSE | TRUE |
Secondly, the order all true events should be given back can be prioritized:
| Events | Prioritized (1...most important - 4... least important) |
|--------- |--------------------------------------------------------- |
| Event 3 | 1 |
| Event 1 | 2 |
| Event 2 | 3 |
| Event 4 | 4 |
So for example, for customer with ID 3 the following output and order of events should be given:
For a customer with ID 8 the following output and order of events should be given:
My example excel looks like the following:
I was thinking of using several IFs, however in reality I have around 100 events and 10.000 customers.
Any suggestions how to implement this in excel?
I appreciate your replies!
Use this array formula:
=IFERROR(INDEX($H$3:$H$6,AGGREGATE(15,7,(ROW($H$3:$H$6)-MIN(ROW($H$3:$H$6))+1)/(INDEX(INDEX(B:E,MATCH($A$19,A:A,0),0),N(IF({1},MODE.MULT(IF({1},MATCH($H$3:$H$6,$B$2:$E$2,0)*{1,1})))))=TRUE),ROW(1:1))),"")
Being an array formula you need to put this in B19 hit Ctrl-Shift-Enter and then copy down.
The one caveat is the list of order be sorted in order. This does not look at the number in column I but the order in Column H that the events are listed.
N(IF({1},MODE.MULT(IF({1},MATCH($H$3:$H$6,$B$2:$E$2,0)*{1,1}))))) creates an array of the relative column numbers(B:E) in order they are listed in Column H.
INDEX(B:E,MATCH($A$19,A:A,0),0) returns the the row where the customer id is found.
INDEX(INDEX(B:E,MATCH($A$19,A:A,0),0),N(IF({1},MODE.MULT(IF({1},MATCH($H$3:$H$6,$B$2:$E$2,0)*{1,1}))))) returns the full array of TRUE/FALSE from the correct row in the correct order.
The aggregate then returns the first relative column number that is true and then the second and the third... as it is dragged down to the outer index. Which then returns the correct value from column H.
If no True is found at the correct k then it returns an error and the IFERROR returns a null string.
I came up with an option that's not perfect but should work.
First of all I'd convert your table to a list so it would look like that:
Right, after I'd create a Helper Column that would act as unique_Reference id for each true column showing the id and the priority:
The value would be "id"_"priority" using the formula (for Cell B3):
=IF(E3=TRUE,C3&"_"&VLOOKUP(D3,$G$3:$H$7,2,FALSE),"")
And then, I'd create the result list which have the issue of getting blanks due to not using array formulas for saving calc time:
Where formula for cell L3 (event with max priority) would be:
=+IF(ISERROR(VLOOKUP($L$2&"_"&K3,$B$3:$D$8,3,FALSE)),"",VLOOKUP($L$2&"_"&K3,$B$3:$D$8,3,FALSE))
I want to count the occurrence of values in column "b" based on column "a" value. I am not sure how to do this in excel.
E.g.
A | B | C
abc | 123 | True
abc | 321 | False
abc | 123 | True
xyz | 987 | True
xyz | 987 | True
qwe | 567 | False
qwe | 765 | False
basically I am trying to see if column b value is repeated for each array of values in column a.
So, D2 counts how many and E2 shows true / false as per your column C.
I prefer to use array formulas for these sort of things.
=ARRAYFORMULA(SUM(IF($A$2:$A$8=A2,IF($B$2:$B$8=B2,1))))
I am trying to set up a table that will allow for very quick classification of sites across about 50 different characteristics. The method I have thought of but am unsure if it's possible is as follows.
Worksheet A: the raw data about 100R x 50C with each cell
describing a characteristic of that row where the last column is the
overall classification.
Worksheet B: a table of about 5R x 50C with the columns
corresponding to the columns in Worksheet A.
A row of Worksheet B would look something like:
* | * | * | 1 | * | 3 | * | Y | * | ... | * | * | * |
And a row from Worksheet A that corresponds with this data would look something like:
A | B | C | 1 | 5 | 3 | Z | Y | 1 | ... | F | 2 | X | High Priority
Where the asterisks indicate a wildcard where I don't care what the content is. All of the other cells would be required conditions. Then I was thinking of applying an array formula on the last column to get the classification. Something like:
{=IF(AND(A2:BV2='Worksheet B'!$A$2:$BV$2), "High Priority", "Low Priority")}
But Excel takes the asterisks as literal string content and evaluates it as FALSE.
Is there a way to make this work? Or an alternative method that would be just as simple to implement?
I got to the bottom of it with a reasonably elegant solution. Please post criticisms if there is a situation where this won't work.
={IF(SUM(IF(A2:BV2='Worksheet B'!A2:BV2,0,1))=COUNTIF('Worksheet B'!A2:BW2,"x"),"Top Priority", "Low Priority")}
Where x is for those cells in which I don't care about the outcome. So instead of "*", I am using "x" in the cells above such that Worksheet B is more like:
x | x | x | 1 | x | 3 | x | Y | x | ... | x | x | x |
If anyone is interested, the formula works by counting all of the mismatched elements and checking them against the number of cells with "x" in the result. If these two numbers are equal, the number of mismatches is equal to the number of cells we don't care about.
Let's say I have two DataFrames -- df1 and df2 -- both with the columns foo and bar. The column foo is a CRC32 hash value like 123456, the column bar is a boolean field that defaults to False.
In pyspark, what is an efficient way to compare the values of foo across the two DataFrames, writing the column bar to True in the event they do not match.
e.g., given the following two DataFrames:
# df1
foo | bar
-------|------
123456 | False
444555 | False
666777 | False
888999 | False
# df2
foo | bar
-------|------
938894 | False
129803 | False
666777 | False
888999 | False
I woud like a new DataFrame that looks like the following, with two True columns where they hashes have changed:
# df3
foo | bar
-------|------
938894 | True <---
129803 | True <---
666777 | False
888999 | False
Any guidance would be much appreciated.
UPDATE 7/1/2018
After successful use of the accepted answer for quite some time, encountered a situation makes the solution not a great fit. If multiple rows from one of the joined DataFrames have the same value for foo as a row from the other DataFrame in the join, it results in a cartesian product growth of rows on that shared value.
In my case, I had I had CRC32 hash values based on an empty string, which results in 0 for the hash. I also should have added, that I do have a unique string to match the rows on, under id here (may have oversimplified situation), and perhaps this is the thing to join on:
It would create situations like this:
# df1
id |foo | bar
-----|-------|------
abc |123456 | False
def |444555 | False
ghi |0 | False
jkl |0 | False
# df2
id |foo | bar
-----|-------|------
abc |123456 | False
def |999999 | False
ghi |666777 | False
jkl |0 | False
And with the selected answer, would get a DataFrame with more rows than desired:
# df3
id |foo | bar
-----|-------|------
abc |123456 | False
def |999999 | True <---
ghi |0 | False
jkl |0 | False
jkl |0 | False # extra row add through join
I'm going to keep the answer as selected, because it's a great answer to the question as originally posed. But, any suggestions for how to handle DataFrames where the column foo may match, would be appreciated.
ANOTHER UPDATE 7/1/2018, ALTERNATE ANSWER
I was over complicating the issue without the id column to join on. When using that, it's relatively straightforward to join and write transformed column based on direct comparison of fingerprint column:
df2.alias("df2").join(df1.alias("df1"), df1.id == df2.id, 'left')\
.select(f.col('df2.foo'), f.when(df1.fingerprint != df2.fingerprint, f.lit(True)).otherwise(f.col('df2.bar')).alias('bar'))\
.show(truncate=False)
A aliased left join of df2 with df1 and use of when function to check for the not matched logic should give you your desired output
df2.alias("df2").join(df1.alias("df1"), df1.foo == df2.foo, 'left')\
.select(f.col('df2.foo'), f.when(f.isnull(f.col('df1.foo')), f.lit(True)).otherwise(f.col('df2.bar')).alias('bar'))\
.show(truncate=False)
which should give you
+------+-----+
|foo |bar |
+------+-----+
|129803|true |
|938894|true |
|888999|false|
|666777|false|
+------+-----+
I would suggest using a left join and write the code such that when the data is null then you output false and vice versa.
So I'm doing a question that reads as follows
Build a circuit using the abstract syntax for Prop to test if two inputs are equal. Justify that your circuit is correct.
This is the Prop in question.
data Prop = FALSE | TRUE | IN String | NOT Prop | OR Prop Prop | AND Prop Prop
Instinctively I am tempted to write AND(IN "A")(IN "B") and give a truth table to prove it but this seems to simple. Am I missing something?
EDIT: My bad, I ended up making a XNOR gate that solved the problem. I mistook AND for XNOR which was the root cause of the confusion. The solution in the answer field is more elegant than mine so please refer to that.
The two inputs would be equal in two cases: either both are true or both are false. It seems that the given language allows to encode that: you can check if an input is true simply by referencing it, i.e. IN "A", and you can check if an input is false by negating it, i.e. NOT (IN "A"). Then combine these checks with ANDs and an OR, and you're done:
OR
(AND -- Both "A" and "B" are true
(IN "A") -- "A" is true
(IN "B") -- "B" is true
)
(AND -- Both "A" and "B" are false
(NOT (IN "A")) -- "A" is false
(NOT (IN "B")) -- "B" is false
)
.
--------------------------------------------------------------------------
| A | B | NOT A | NOT B | AND A B | AND (NOT A) (NOT B) | Result |
--------------------------------------------------------------------------
| false | false | true | true | false | true | true |
| false | true | true | false | false | false | false |
| true | false | false | true | false | false | false |
| true | true | false | false | true | false | true |
--------------------------------------------------------------------------