Boolean logic - simplifying sum of products - boolean

I've got a question that asks to synthesise the simplest possible sum of products expression for a given function. Basically the function is 1 if AB == CD, and 0 otherwise, which works out like this:
(!A && !B && !C && !D) || (!A && B && !C && D) || (A && !B && C && !D) || (A && B && C && D)
None of the terms differ by only one bit, so I can't see a way to group them together and simplify them that way. I've drawn up a Karnaugh map as below, but that doesn't seem to help, as I can't group more than one 1 together.
\ AB 00 01 11 10
CD +---+---+---+---+
00 | 1 | 0 | 0 | 0 |
+---+---+---+---+
01 | 0 | 1 | 0 | 0 |
+---+---+---+---+
11 | 0 | 0 | 1 | 0 |
+---+---+---+---+
10 | 0 | 0 | 0 | 1 |
+---+---+---+---+
So my question is, is the expression above already the simplest possible sum of products expression?

I think your Karnaugh map is equivalent to: ((A && C) || (!A && !C)) && ((B && D) || (!B && !D))
That would be simpler, I think.

Related

How to detect streaks of continuous activity in Postgres?

I want to aggregate data based on streaks of continuous activity.
DDL:
CREATE TABLE t_series (t date, data int)
INSERT INTO t_series VALUES
(date '2018-03-01',12),
(date '2018-03-02',43),
(date '2018-03-03',9),
(date '2018-03-04',13),
(date '2018-03-09',23),
(date '2018-03-10',26),
(date '2018-03-11',28),
(date '2018-03-14',21),
(date '2018-03-15',15)
I want an intermediate output as:
          t | data | period
------------+------+------
 2018-03-01 | 12 | 1
 2018-03-02 | 43 | 1
 2018-03-03 | 9 | 1
 2018-03-04 | 13 | 1
 2018-03-09 | 23 | 2
 2018-03-10 | 26 | 2
 2018-03-11 | 28 | 2
 2018-03-14 | 21 | 3
 2018-03-15 | 15 | 3
And the final output as:
period | sum
--------+-----
      1 | 77
      2 | 77
      3 | 36
I have tried using below but doesn't seem to work:
SELECT *, SUM(CASE WHEN diff IS NULL
                     OR diff <2 THEN 1 ELSE NULL END) OVER (ORDER BY t) AS period
       FROM (SELECT *, t - lag(t, 1) OVER (ORDER BY t) AS diff
             FROM t_series
       ) AS x;
Could anyone please suggest a fix.
Thanks in advance.
I came up with this solution:
SELECT period, SUM(data) AS sum
FROM (
SELECT t, data, SUM(groups) OVER (ORDER BY t) AS period
FROM (
SELECT t, data,
CASE
WHEN diff IS NULL OR diff = 1 THEN 0
ELSE 1
END AS groups
FROM (
SELECT t, data, t - LAG(t) OVER (ORDER BY t) AS diff
FROM t_series
) d
) g -- your intermediate output
) p
GROUP BY period
ORDER BY period
;
Result:
period | sum
--------+-----
0 | 77
1 | 77
2 | 36
The only difference is that my period starts with 0, but I think it's ok

How to generate the columns based on the unique values of that particular column in pyspark?

I have a dataframe as below
+----------+------------+---------------------+
|CustomerNo|size |total_items_purchased|
+----------+------------+---------------------+
| 208261.0| A | 2|
| 208263.0| C | 1|
| 208261.0| E | 1|
| 208262.0| B | 2|
| 208264.0| D | 3|
+----------+------------+---------------------+
I have another table df that consists of customerNo's only. I have to create columns of unique comfortStyles and have to update the total_items_purchased in df
My df table should look like
CustomerNo,size_A,size_B,size_C,size_D,size_E
208261.0 1 0 0 0 1
208262.0 0 2 0 0 0
208263.0 0 0 1 0 0
208264.0 0 0 0 3 0
Can anyone tell me how to do this?
You can use pivot function to rearrange the table.
df = (df.groupBy('CustomerNo')
.pivot('size')
.agg(F.first('total_items_purchased'))
.na.fill(0))

Parse json with same key to different columns

Schema of my json is next
and field Reports_Rows_Rows_Cells if it not null looks like next:
[Row(Attributes=[Row(Id='account', Value='bd9e85e0-0478-433d-ae9f-0b3c4f04bfe4')], Value='Business Bank Account'),
Row(Attributes=[Row(Id='account', Value='bd9e85e0-0478-433d-ae9f-0b3c4f04bfe4')], Value='10105.54'),
Row(Attributes=[Row(Id='account', Value='bd9e85e0-0478-433d-ae9f-0b3c4f04bfe4')], Value='4938.48')]
What I want is to create table which has all above columns and column Reports_Rows_Rows_Cells should look like
-------- |-------|Reports_Rows_Rows_Cells_Value | Reports_Rows_Rows_Cells_Value | Reports_Rows_Rows_Cells_Value|
| Business Bank Account |10105.54 | 4938.48
Not after parsing json my table look like next:
-------- |-------|Reports_Rows_Rows_Cells_Value|
| Business Bank Account |
| 10105.54 |
| 4938.48 |
My code which I use to parse json
def flatten_df(nested_df):
# for ncol in nested_df.columns:
array_cols = [c[0] for c in nested_df.dtypes if c[1][:5] == 'array']
for col in array_cols:
nested_df = nested_df.withColumn(col, explode_outer(nested_df[col]))
nested_cols = [c[0] for c in nested_df.dtypes if c[1][:6] == 'struct']
if len(nested_cols) == 0:
return nested_df
flat_cols = [c[0] for c in nested_df.dtypes if c[1][:6] != 'struct']
flat_df = nested_df.select(flat_cols +
[F.col(nc+'.'+c).alias(nc+'_'+c)
for nc in nested_cols
for c in nested_df.select(nc+'.*').columns])
return flatten_df(flat_df)

spark delete previous row based on the new row with some conditions match

I have dataframe like below
type f1 f2 value
1 a xy 11
2 b ab 13
3 c na 16
3 c dir 18
3 c ls 23
I have to delete a previous row some some of conditions matches with next row,
for example from the above table, when column fields of type == type(row-1) && f1 == f1(row-1) && abs(value - value (row-1)) < 2 , when this condition matches I want to delete the previous row.
so I my table should like below
type f1 f2 value
1 a xy 11
2 b ab 13
3 c dir 18
3 c ls 30
I am thinking that we can make use of lag or lead features but not getting exact logic
Yes, its can be done using .lead()
import org.apache.spark.sql.expressions._
//define window specification
val windowSpec = Window.partitionBy($"type",$"f1").orderBy($"type")
val inputDF = sc.parallelize(List((1,"a","xy",11),(2,"b","ab",13),(3,"c","na",16),(3,"c","dir",18),(3,"c","ls",23))).toDF("type","f1","f2","value")
inputDF.withColumn("leadValue",lead($"value",1).over(windowSpec))
.withColumn("result", when(abs($"leadValue" - $"value") <= 2, 1).otherwise(0)) //check for condition
.filter($"result" === 0) //filter the rows
.drop("leadValue","result") //remove additional columns
.orderBy($"type")
.show
Output:
+----+---+---+-----+
|type| f1| f2|value|
+----+---+---+-----+
| 1| a| xy| 11|
| 2| b| ab| 13|
| 3| c|dir| 18|
| 3| c| ls| 23|
+----+---+---+-----+
Here as we already are partitioning by type & f1 we need not check for their equality condition

SQL query to aggregate data based on months (Postgres)

The table that I querying is :
table testing_table:
testType | period_from | period_to| copies |
1 | 20180101| 20181201| 1|
2 | 20180101 | 20191201| 1|
3 | 20190101| 20191201| 1|
I want to loop through the array and use the below query to generate values like this:
DateVar | ABTEST | CDTEST | EFTEST |
20180101| 4| 0| 0|
20180201| 3| 4| 2|
dateVar = ['20180101','20180201','20180501'].
I am trying to develop an sql query like this:
SELECT
SUM (
CASE
WHEN (testType = 1 AND (period_from <= dateVar AND period_to >= dateVar)) THEN
copies
ELSE
0
END
) AS "ABTEST",
SUM (
CASE
WHEN (testType = 2 AND (period_from <= dateVar AND period_to >= dateVar)) THEN
copies
ELSE
0
END
) AS "CDTEST",
SUM (
CASE
WHEN (testType = 3 AND (period_from <= dateVar AND period_to >= dateVar)) THEN
copies
ELSE
0
END
) AS "EFTEST"
FROM
testing_table;
I am lost as to what to do with it. Do I look into functions?
I think you should use unnest function to accomplish what you are asking i have written a query you may want to check
SELECT DTVAR,
SUM(CASE
WHEN TestType = 1
THEN copies
ELSE 0
END) AS 'ABTEST',
SUM(CASE
WHEN TestType = 2
THEN copies
ELSE 0
END) AS 'CDTEST',
SUM(CASE
WHEN TestType = 3
THEN copies
ELSE 0
END) AS 'EFTEST'
FROM (
SELECT DTVAR, TestType, sum(copies) AS copies
FROM testing_table
INNER JOIN (
SELECT DTVAR
FROM unnest(dateVar ['20180101','20180201','20180501']) AS DTVAR
) AA
ON (
period_from <= DTVAR
AND period_to >= DTVAR
)
GROUP BY DTVAR, TestType
) A
GROUP BY DTVAR
hope this helps..