According to De Morgan law:
¬(P ˄ Q) ↔ (¬P) ˅ (¬Q)
¬(P ˅ Q) ↔ (¬P) ˄ (¬Q)
In Python 3.5 when I run:
A = True
B = True
x = not(A and B)==(not A) or (not B)
y = not(A or B)==(not A) and (not B)
print('x is :', x, '\ny is :' ,y)
This returns:
x is : True
y is : False
Question: why y is False?
Try adding some parentheses -- == is higher precedence than or.
Here is the precedence table
Try this:
y = not(A or B)==((not A) and (not B))
It was evaluating
not(A or B) == (not A)
first.
Operator priority is tripping you up. In Python, the == operator has higher priority than not. The expression not a == b is read as not (a == b) rather than (not a) == b, because the former is usually more useful than the latter.
Therefore, your y should look like:
y = (not(A or B)) == ((not A) and (not B))
And your x should look like:
x = (not(A and B)) == ((not A) or (not B))
Then you'll get the right results. (Your x is also wrong, and is getting a True result for the wrong reasons: it's actually evaluating (not ((A and B) == (not A)) or (not B) which works out to (not (True == False)) or False which works out to True or False. But what you actually wanted was (not (A and B)) == ((not A) or (not B)), which works out to (not True) == (False or False), which works out to False == False. As I said, your x is getting a True result for the wrong reasons.)
Related
The assignment is to write a recursive function that receives 2 whole non-negative numbers b, x, and returns True if there's a natural integer n so that b**n=x and False if not. I'm not allowed to use any math operators or loops, except % to determine if a number is even or odd.
but i do have external functions that i can use. Which can add 2 numbers, multiply 2 numbers, and divides a number by 2. also i can write helper function that i can use in the main function.
this is what i got so far, but it only works if b is in the form of 2^y (2,4,8,16 etc)
def is_power(b, x):
if b == x:
return True
if b > x:
return False
return is_power(add(b, b), x) # the func 'add' just adds 2 numbers
Furthermore, the complexity needs to be O(logb * logx)
Thank you.
You can essentially keep multiplying b by b until you reach, or pass, n.
A recursive implementation of this, using a helper function, could look something like this:
def is_power(b, x):
if b == 1: # Check special case
return x == 1
return helper(1, b, x)
def helper(counter, b, x):
if counter == x:
return True
elif counter > x:
return False
else:
return helper(mul(counter, b), b, x) # mul is our special multiplication function
Use the function you say you can use to multiply 2 numbers like:
power = False
result = b
while result < x:
result = yourMultiplyFunction(b,b)
if result == x:
power = True
break
print(power)
Question was EDITTED (can't use loops):
def powerOf(x, b, b1=-1):
if b1 == -1:
b1 = b
if (b == 1) and (x == 1):
return True
elif ( b==1 ) or (x == 1):
return False
if b*b1 < x:
return powerOf(x, b*b1, b1)
elif b*b1 > x:
return False
return True
print(powerOf(625, 25))
A solution that is O(logb * logx) would be slower than a naive sequential search
You can get O(logx / logb) by simply doing this:
def is_power(b,x,bn=1):
if bn == x: return True
if bn > x: return False
return is_power(b,x,bn*b)
I suspect that the objective is to go faster than O(logx/logb) and that the complexity requirement should be something like O(log(logx/logb)^2) which is equivalent to O(log(n)*log(n)).
To get a O(log(n)*log(n)) solution, you can convert the problem into a binary search by implementing a helper function to raise a number to a given power in O(log(n)) time and use it in the O(log(n)) search logic.
def raise_power(b,n): # recursive b^n O(logN)
if not n: return 1 # b^0 = 1
if n%2: return b*raise_power(b*b,n//2) # binary decomposition
return raise_power(b*b,n//2) # of power over base
def find_power(b,x,minp,maxp): # binary search
if minp>maxp: return False # no matching power
n = (minp+maxp)//2 # middle of exponent range
bp = raise_power(b,n) # compute power
if bp == x: return True # match found
if bp > x: return find_power(b,x,minp,n-1) # look in lower sub-range
return find_power(b,x,n+1,maxp) # look in upper sub-range
def max_power(b,x):
return 2*max_power(b*b,x) if b<x else 1 # double n until b^n > x
def is_power(b,x):
maxp = max_power(b,x) # determine upper bound
return find_power(b,x,0,maxp) # use binary search
Note that you will need to convert the *, + and //2 operations to their equivalent external functions in order to meet the requirements of your assignment
from z3 import *
x = Real('x')
s = Solver()
s.add(x > 1 or x < -1)
print(s.check())
if s.check() == sat:
print(s.model())
I want to solve a or expressions , how can i do it?
when z3 told me "Symbolic expressions cannot be cast to concrete Boolean values"
Python's or is not symbolic aware. Instead, use z3py's Or:
from z3 import *
x = Real('x')
s = Solver()
s.add(Or(x > 1, x < -1))
r = s.check()
print(r)
if r == sat:
print(s.model())
This prints:
sat
[x = -2]
Note that I'd also avoid two separate calls to check, by storing the result in a variable first. (Which I called r above.) In general, the second call to check will be cheap since you haven't added any constraints after the first, but this makes the intention clearer.
I have a set of three variables x, y, z and I want to check if they all share the same value. In my case, the value will either be 1 or 0, but I only need to know if they are all the same. Currently I'm using
if 1 == x and 1 == y and 1 == z:
sameness = True
Looking for the answer I've found:
if 1 in {x, y, z}:
However, this operates as
if 1 == x or 1 == y or 1 == z:
atleastOneMatch = True
Is it possible to check if 1 is in each: x, y, and z?
Better yet, is there a more concise way of checking simply if x, y, and z are the same value?
(If it matters, I use Python 3.)
If you have an arbitrary sequence, use the all() function with a generator expression:
values = [x, y, z] # can contain any number of values
if all(v == 1 for v in values):
otherwise, just use == on all three variables:
if x == y == z == 1:
If you only needed to know if they are all the same value (regardless of what value that is), use:
if all(v == values[0] for v in values):
or
if x == y == z:
To check if they are all the same (either 1 or 2):
sameness = (x == y == z)
The parentheses are optional, but I find it improves readability
How about this?
x == y == z == 1
In my case, the value will either by 1 or 2, but I only need to know if they are all the same
Is it possible to check if 1 is in each: x, y, and z?
Better yet, is there a more concise way of checking simply if x, y, and z are the same value?
Sure:
x == y == z
which is equivalent to
(x == y) and (y == z)
If you have an arbitrary (nonzero) number of values to compare:
all(values[0] == v for v in values[1:])
You could use something similar to what you have:
sameness = (len({x, y, z}) == 1)
This allows for any number of variables. For example:
variables = {x, y, z, a, b, ...}
sameness = (len(variables) == 1)
Note: Creating a set means that each variable needs to be hashed and the hashed values need to be stored, but all() with a generator expression is short-circuiting and keeps track of only two values at a time. Therefore, besides its readability, the generator expression is more efficient.
Another way:
sameness = all(e == 1 for e in [x, y, z])
[x,y,z].count(1)
will count how many variables have 1 as value
Below all() and any() functions in python can server the purpose.
all() act as "AND": if all the values in any ittertable object is equal to given condition value, then Return True else return False.
Examples
assert all(b == True for b in [True,True,True,True]) == True
assert all(b == True for b in [False,True,True,True]) == False
any() act as "OR": if any one value in any ittertable object is equal to given condition value, then Return True else return False.
Examples
assert any(b == True for b in [False,False,False,True]) == True
assert any(b == True for b in [False,False,False,False]) == False
If you had more variables, this way might be most concise:
{x} == {y, z}
(Not as fast as x == y == z, but the question asked for concise, not for fast.)
I have a scrip that automatically generates equations.
The equations are constructed using sympy symbols.
I would like to know whether or not these is a way to check if the equations are linear in terms of certain variables.
eg.
a, b, c, d = sympy.symbols('a, b, c, d')
eq1 = c*b*a + b*a + a + c*d
check for the following: is eq1 linear in terms of a, d?
True
A function is (jointly) linear in a given set of variables if all second-order derivatives are identically zero (including mixed ones). This can be checked as follows:
def is_linear(expr, vars):
for x in vars:
for y in vars:
try:
if not sympy.Eq(sympy.diff(expr, x, y), 0):
return False
except TypeError:
return False
return True
In the loop, every derivative is taken and checked for equality to zero. If sympy cannot decide if it's zero (raising TypeError) then it's not identically zero.
Output:
>>> is_linear(eq1, [a,d])
True
>>> is_linear(eq1, [a,c])
False
To check for separate linearity (e.g., separately in a and separately in b), drop mixed partial derivatives:
def is_separately_linear(expr, vars):
for x in vars:
try:
if not sympy.Eq(sympy.diff(expr, x, x), 0):
return False
except TypeError:
return False
return True
Output:
>>> is_separately_linear(eq1, [a,d])
True
>>> is_separately_linear(eq1, [a,c])
True
A simpler way would be to check the degree of the expression as a polynomial in each variable.
In [17]: eq1 = c*b*a + b*a + a + c*d
In [18]: degree(eq1, a)
Out[18]: 1
In [19]: degree(eq1, d)
Out[19]: 1
and expression is linear if the polynomial degree is <= 1.
If you know the expression is a polynomial in your variables, you can also just check for powers that contain the variable.
In [21]: [i for i in eq1.atoms(Pow) if i.base == a]
Out[21]: []
In [22]: eq2 = b*a**2 + d + c
In [23]: [i for i in eq2.atoms(Pow) if i.base == a]
Out[23]:
⎡ 2⎤
⎣a ⎦
To expand on the answer from 404, if fxy=0, then fyx=0. Thus, the computation time can be cut in half for the mixed derivatives solution.
from itertools import combinations_with_replacement
def is_linear(expr, variables):
combs = combinations_with_replacement(variables, 2)
try:
return all(sympy.Eq(sympy.diff(expr, *t), 0) for t in combs)
except TypeError:
return False
def logical_xor(a, b): # for example, -1 and 1
print (a < 0) # evaluates to True
print (b < 0) # evaluates to False
print (a < 0 != b < 0) # EVALUATES TO FALSE! why??? it's True != False
return (a < 0 != b < 0) # returns False when it should return True
print ( logical_xor(-1, 1) ) # returns FALSE!
# now for clarification
print ( True != False) # PRINTS TRUE!
Could someone explain what is happening? I'm trying to make a one liner:
lambda a, b: (a < 0 != b < 0)
All comparison operators in Python have the same precedence. In addition, Python does chained comparisons. Thus,
(a < 0 != b < 0)
breaks down as:
(a < 0) and (0 != b) and (b < 0)
If any one of these is false, the total result of the expression will be False.
What you want to do is evaluate each condition separately, like so:
(a < 0) != (b < 0)
Other variants, from comments:
(a < 0) is not (b < 0) # True and False are singletons so identity-comparison works
(a < 0) ^ (b < 0) # bitwise-xor does too, as long as both sides are boolean
(a ^ b < 0) # or you could directly bitwise-xor the integers;
# the sign bit will only be set if your condition holds
# this one fails when you mix ints and floats though
(a * b < 0) # perhaps most straightforward, just multiply them and check the sign
Your code doesn't work as intended because != takes higher precedence than a < 0 and b < 0. As itzmeontv suggests in his answer, you can simply decide the precedence yourself by surrounding logical components with parentheses:
(a < 0) != (b < 0)
Your code attempts to evaluate a < (0 != b) < 0
[EDIT]
As tzaman rightly points out, the operators have the same precedence, but your code is attempting to evaluate (a < 0) and (0 != b) and (b < 0). Surrounding your logical components with parentheses will resolve this:
(a < 0) != (b < 0)
Operator precedence: https://docs.python.org/3/reference/expressions.html#operator-precedence
Comparisons (i.a. chaining): https://docs.python.org/3/reference/expressions.html#not-in
You can use this
return (a < 0) != (b < 0)
Comparisons can be chained arbitrarily, e.g., x < y <= z is equivalent to x < y and y <= z, except that y is evaluated only once (but in both cases z is not evaluated at all when x < y is found to be false).
So it becomes
(a < 0) and (0 != b) and (b < 0)
See https://docs.python.org/3/reference/expressions.html#not-in
In Python, comparison operators are of the same precedence, and they are non-associative. There is a separate rule for sequences of comparison operators, the chaining rule. Python documentation states about that:
if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.
Further, a op1 b and b op2 c and ... y opN z evaluates left to right.
a < 0 and 0 != b and b < 0
a < 0 will evaluated to False, and the further evaluation will be stopped due to short-circuit evaluation. So, the whole expression will be evaluated as False.