Logical operator Python - python

Probably a very basic question but I can not solve this.
That's my code:
if type(lines_r).__name__ == 'NoneType' or type(lines_l).__name__ == 'NoneType':
no_detected.append(i)
else: ...
Now, I don't want to use and/or operators because in this case I just want:
if the first condition is true <(lines_r) == Nonetype> so it'll be -No.detected- and, not connected to the other condition, I want to do the same thing for the other one (lines_l).
Because the 2 conditions could be not related in time (they are not at the same time both true or both false so I can't use AND + if I use OR then the condition is true if only one of the two is NoneType, and that's not what I want).
[The variables are str]
What's the best way to write this?
*EDIT
That's the things that I'm calculating
lines_r = cv2.HoughLinesP(Ske_conn_right[i],
rho = 1,
theta =np.pi/180,
threshold = 4,
minLineLength=2,
maxLineGap=7)
lines_l = cv2.HoughLinesP(Ske_conn_left[i],
rho = 1,
theta =np.pi/180,
threshold = 4,
minLineLength=2,
maxLineGap=7)
I'm doing detection of moving objects in a video. The results are arrays that could have some 0 values (in a simplistic way where objects are not detected).
lines_l or lines_r could result in a Nonetype obj

You can use instanceof to check if a value has a particular type, but here you should simply check if the value is None:
if lines_r is None or lines_l is None:
no_detected.append(i)

if both of your conditions are not related maybe you could use a if and else if statement
if type(lines_r).__name__ == 'NoneType':
no_detected.append(i)
elif type(lines_l).__name__ == 'NoneType':
no_detected.append(i)
else: ...
Then again that's the same thing as using an or statement, but it's just more similar to how you explained your logic

If you want the condition to be true only if one of line_r and line_l is None, you can test the variables first and then test if the results are not equal:
if (lines_r is None) != (lines_l is None):
no_detected.append(i)

Related

Python - How to find which condition is true in if statement?

I have an if statement has many conditions, for example:
if(0 > 1 or 9 < 10 or 2 == 1):
print('Hello World!')
so i wanna know which is the right condition that let the if statement continues to print hello world? "without using another if statement or elif"
In my code I have lots of conditions so it's difficult to use a lot of else statements to just know what is the right condition was.
In general, it's impossible - each condition is evaluated, we can only get a result.
However, if instead of ors, we have them stored* in a list like this:
conditions = [0>1, 9<10, 2==1] # it gets evaluated here!*
if any(conditions):
print('Hello World!')
we could get the index of the True element by doing conditions.index(True).
[*] But be aware that conditions doesn't consist of pure conditions but of Trues and Falses because they got evaluated. That's why I said it's impossible to get the condition itself.
I don't know why you would ever want to use this but okay...
You need to return a value which has a special __bool__ so I would define a class.
The class will have one instance variable, index to indecate the first True condition, or None if there's no True condition.
The __bool__ function then only needs to check whether index is None:
class Any:
def __init__(self, *conditions):
self.index = None
for i, cond in enumerate(conditions):
if cond:
self.index = i
break
def __bool__(self):
return self.index is not None
Example usage:
if o := Any(0 > 1, 9 < 10, 2 == 1):
print(f'The index of the first True condition is {o.index}')
For hard coded conditions like in your example, a good IDE should have an indicator and propose that you simplify the condition.
If you have variables in the condition, this will of course not be possible. In such a case, I would refactor the code and introduce additional semantics by using a variable name for the individual boolean parts of the condition.
In PyCharm, the shortcut Ctrl+Alt+V extracts a condition into a variable.
A more realistic example (before):
class Customer:
def __init__(self, age, totalsales, paymenttype):
self.age = age
self.totalsales = totalsales
self.paymenttype = paymenttype
c = Customer(21, 3000, 2)
if c.age > 18 or c.totalsales > 5000 or c.paymenttype == 1:
print('Hello World!')
After:
c = Customer(21, 3000, 2)
is_adult = c.age > 18
is_vip = c.totalsales > 5000
is_payed_in_advance = c.paymenttype == 1
if is_adult or is_vip or is_payed_in_advance:
print('Hello World!')
When you reach the if-statement, you can inspect each part of the condition in the debugger.
Note that this may change the behavior of your program, because with the changed code, each condition is evaluated, whereas short circuiting may have been applied before. However, I never ran into a situation where this caused a problem.
Chained boolean expressions will be evaluated from left to right. If one of the chained statements is evaluated as being True, the remaining conditions will not be checked.
Assuming second_condition is fulfilled and hence will be evaluated as True, the following pseudo-code snipped would evaluate first_condition as False and then enter the if statement because of second_condition being True. However, third_condition will not be checked as another check before was already evaluated as True and thus the complete statement will become True:
if (first_condition or second_condition or third_condition):
pass
Knowing which condition was evaluated as True is not possible with the approach shown above. Therefore, I would suggest rewriting your checks as follows:
def handle_true(condition):
pass
if first_condition:
handle_true('first')
elif second_condition:
handle_true('second')
elif third_condition:
handle_true('third')
else:
pass
The if/elif will be evaluated in the same way as your chained or expression. If one condition fails, the next will be checked. If one of the given conditions is evaluated as True the branch will be entered. If none of the given conditions is fulfilled, the default else will be entered.
Combining this with the small helper function handle_true() should do the trick and not only provide a way to check which condition fired, but also provide a single place for handling any True condition.
I think that a good option will be to create a list of condition and to check you the item of your list in a loop.
cond=[True, False, True, 5>10,True,False,1==1,3<-1,'a' == 'a'] # assume this is your list
for i in range(len(cond)):
if cond[i]:
print(i) # will return the Item adress correspending to True
You can do:
print(0 > 1) print(9 < 10)
It will print true or false

Passing an array as an argument in Python

I'm not sure if this is even possible but I'm trying to create a python program that identifies polynomials and identifies all the properties of them. I was trying to make a function similar to the switch() function, and the way that I was going to get around making hundreds of functions for each number of cases for arguments, I wanted to make one of the arguments an array, currently it's throwing me a bunch of errors and I really don't know what I'm supposed to be doing because they don't explain themselves, I've looked around and haven't found anything that works, any help would be greatly appreciated, I'm fairly certain there is a similar function in python but any articles on it are quite confusing, thank you, below is the function I was trying to make.
def switch(checked, check):
for(item in check):
if(item == check):
return True
return False
If you need to simulate a switch statement you can use a helper function like this one:
def switch(v): yield lambda *c: v in c
You can then use it in a C-like style:
x = 3
for case in switch(x):
if case(1,2):
# do something
break
if case(3):
# do something else
break
if case(4,5,7):
# do some other thing
break
else:
# handle other cases
Or you can use if/elif/else statements:
x = 3
for case in switch(x):
if case(1,2): # do something
elif case(3): # do something else
elif case(4,5,7): # do some other thing
else: # handle other cases
To check if something is an item of a list, you don't need to loop through the list. You can just use the in operator:
d = ['abc', 'xyz', 1, 99]
if 'abc' in d:
# True
# do something
if 'mno' in d:
# False
# do something
Did you mean this?
def switch(checked, check):
for item in check:
if item == checked:
return True
return False

Defining a default argument after with None: what if it's an array?

I'm passing an argument to a function such that I want to delay giving the default parameter, in the usual way:
def f(x = None):
if x == None:
x = ...
The only problem is that x is likely to be a numpy array. Then x == None returns a boolean array, which I can't condition on. The compiler suggests to use .any() or .all()
But if I write
def f(x = None):
if (x == None).any():
x = ...
this won't work if x goes to its default value, because then None == None is a Boolean, which has no .any() or .all() methods. What's my move here?
When comparing against None, it is a good practice to use is as opposed to ==. Usually it doesn't make a difference, but since objects are free to implement equality any way they see fit, it is not always a reliable option.
Unfortunately, this is one of those cases where == doesn't cut it, since comparing to numpy arrays returns a boolean mask based on the condition. Luckily, there is only a single instance of None in any given Python program, so we can actually check the identity of an object using the is operator to figure out if it is None or not.
>>> None is None
True
>>> np.array([1,2,3]) is None
False
So no need for any or all, you can update your function to something like:
def f(x=None):
if x is None:
print('None')
else:
print('Not none')
In action:
>>> f()
None
>>> f(np.array([1,2,3]))
Not none

Python does not allow multiple return() statements in ternary; possible alternative that is also aesthetically pleasing?

I am developing a text based RPG (graphics will be implemented later) and I am writing a method to determine whether a room a player is trying to go to exists or not. In this method I have multiple logic statements that determine what room the player is trying to get to based on the direction they enter and whether that "room" == 0 (my place holder for an empty space in the world/dungeon array). Although I can write a conventional logic statement for this:
if condition:
if otherCondition:
return(True)
else:
return(False)
a ternary is much more aestheticaly pleasing:
if condition:
return(True) if otherCondition else return(False)
But of course, that does not work. I am looking for something that functions as the conventional logic statement but is also "pleasing to the eye", like a ternary. In my code the logic statement is repeated four times, and the conventional logic statement would be displeasing to read.
I am using Python 3.5.1 on Windows 7.
The issue with your statement isn't the ternary part, it's the repeated return. Instead use:
if condition:
return True if otherCondition else False
Here, the result of the expression True if otherCondition else False is returned.
This could be written more concisely as:
if condition:
return bool(otherCondition)
Use just a single return with ternary statement:
return 'something' if someCondition else 'something else'
For you case is enough just :
if condition:
return otherCondition
# or if "otherCondition is not bool you can use: return bool(condition)
z = x if success else y
# this tallies z = success ? x : y, where success is a bool. Either True or False
Here the expression on the right returns x or y depending on if success evaluates to True or False respectively. As this is an expression it can be used with a return statement
return x if success else y
if condition:
return othercondition
Perhaps you should illustrate with an example, because it can be simplified to return the result of the other condition.
if condition:
return otherCondition
What ever happened to just:
if condition:
# tis very simple; if room is equal to 0, the operation is true, thus `True` will be returned
# otherwise `False`.. no mystery
return room == 0

Function that checks if brackets are balanced in python

I have written the following code to check if some input to the function contains balanced brackets:
def balanced_brackets(text):
brackets = [ ('(',')'), ('[',']'), ('{','}'),('<','>')]
s = 0
e = 1
st = Stack()
for i in text:
for pair in brackets:
if i == pair[s]:
st.push(i)
elif i == pair[e] and not st.isEmpty() and st.pop() != pair[s]:
return False
if st.isEmpty():
return True
else:
return False
This code is working for input such as '()(())()' but it failed when I tried it for 'zn()((b)())q())()l()d(r)'. Can anyone help me identify what the problem is? Thanks.
Your problem is with the and not st.isEmpty()==0. When it gets to the unbalanced ')', all the previous ones have balanced out, so st is empty.
If you have a i == pair[e], and your stack is empty, you want to return False.
You also want to return False if you pop and it isn't pair[e]. But you don't want to pop if the stack is empty.
What you have now, in condition 1, just keeps going. You need to change around the condition there so that it accounts for both, or have two elifs. The former can be achieved with some nesting ands and ors.
By the way; unless you want to do something fancy with it, there's no real need to implement a stack. You can just use a list instead, with l.pop, len(l), and l.append.
This works.It needs a stack module to import. It will keep track of matched pairs.
def multi_bracket_validation(input):
""" test for matching brackets and return bool """
if type(input) is str:
open_b = '({]'
closed_b = ')}]'
compare = Stack()
for brac in input:
if brac in open_b:
compare.push(brac)
elif brac in closed_b:
if compare.top is None:
return False
if closed_b.index(brac) != open_b.index(compare.pop().val):
return False
return compare.top is None
return False

Categories