Consider a simple if/else block in Python like the one below:
if x:
print 'True'
else:
print 'False'
Where x could be a comparison, a condition or simply a string/list/object. How can I open a python shell and find out what if x would evaluate to without writing the loop? i.e. is x True or False for a certain corner case value.
For example, if x is an empty list. Can I open python shell, assign x = [] and then write print <function of x> that'll output True or False on execution. What is that <function of x>?
I feel I'm asking a rather silly question and can't think straight right now but I often find myself opening a shell, assign a corner case value to a variable and write an if/else to see what corner values would evaluate to True/False. I'm just looking for a shorter way to find out on the shell, without writing the 4-line loop.
You are looking for the function bool.
>>> bool([])
False
>>> bool(['monty'])
True
What the Python Docs say.
Convert a value to a Boolean, using the standard truth testing
procedure. If x is false or omitted, this returns False; otherwise it
returns True. bool is also a class, which is a subclass of int. Class
bool cannot be subclassed further. Its only instances are False and
True.
Your four lines should be the same as
print(bool(x))
Related
a=True and 1/0
print(a)
The output for the above code fragment shows an error.
While the output for the below code fragment :
a=False and 1/0
print(a)
Is False
Why is that so? From the layman point of view, since 1/0 is undefined, error should be displayed in each case.
Similarly if I take a = True or 1/0, output is true while an error for False or 1/0
I tried different versions of this:
a=1/0 or False
print(a)
or
a=1/0 or True
print(a)
Both of which display an error (division by zero)
I realized that it has something to do with the order I take them in and the boolean operators I use.
In any case, why am I getting an output and in some cases?
Both and and or are short circuited i.e. if the first input is respectively false or true, the rest of the inputs are not evaluated at all. That is why both False and 1/0 as well as True or 1/0 can return results, while other variations do not.
Python exhibits short-circuit evaluation semantics for and and or expressions. What that means is that, if the result of the entire expression can be determined from the left-hand-side, then the right-hand-side needn't be evaluated.
False and a
Here, we first evaluate the expression False (which is a literal and equal to the Python value False). Now, and is only true if both sides are true, and we've already found one side which is false. So no matter what a evaluates to, the result is False. Hence, we don't evaluate the right-hand-side because it's unnecessary.
Likewise,
True or a
Since True is truthy and or only requires one of its arguments to be truthy, whatever a evaluates to, the result is True.
This is commonly used to do several veins of error checking in one line. Python doesn't have a null-safe access operator, so we can do the next best thing.
if person is not None and person.salary is not None:
...
Without short-circuit evaluation, the person.salary is not None would evaluate, even in the case where person is actually None, which is an error. We'd have to write the more verbose
if person is not None:
if person.salary is not None:
...
which does nothing for readability.
Likewise, we can use or to short circuit error conditions.
if person is None or person.salary is None:
raise(MyCustomException("This person doesn't have a job"))
Again, if person happens to be None, we don't want person.salary to evaluate at all, or we'll get an AttributeError rather than our nice, informative custom exception. Without short-circuiting, we'd have to resort to the much uglier
if person is None:
raise(MyCustomException("This person doesn't have a job"))
if person.salary is None:
raise(MyCustomException("This person doesn't have a job"))
In case of False, It is not necessary to check more after and - it is due to the optimization, so 1/0 is never executed.
On the other hand: a=1/0 and False will not work as 1/0 is evaluated first.
and operator stops when a False is encountered to save resources.
Here:
a=False and 1/0
Division is never computed.
The same you can check with or operator: it stops when True is validated:
a=True or 1/0
Will give True.
As I have started learning Python recently, I came across this boolean concept and I execute this expression bool("0"), but I got a confusing result as True of this expression, can anybody tell me why this happens.
bool("0") evaluates to True because"0" in this case is a non-empty string. It's useful for things like :
if str: #check if str is not empty
#do something
bool(0) on the other hand evaluates to False.
It is because it will return True for every non-empty strings,lists,etc.
If int type varieble is zero Interpreter shows it as False .bool("0") evaluates to True because"0" in this case is a non-empty string,NOT intSee it full in one photo
Strongly related question.
When writing docstrings for my functions in python, I sometimes want to write something like this about argument specifications:
def foo(bar):
"""
Do some stuff.
bar : callable
must return True if XXX and False otherwise.
"""
if bar(...):
... # code goes here
However, this is not perfectly precise, because in this example bar could be returning any object that will be evaluated to True in the if-statement when the conditions XXX is fulfilled. Such a callable would be a perfectly valid argument to pass to foo.
How should I formulate my documentation to reflect that foo does not strictly requires bar's output to be a boolean?
My first move was to write something like "[...] must return an object that will be evaluated to True if ...", but I find it obfuscated.
This is a slang question! I've always wanted to answer one of these!
Ahem.
The term for something that evaluates to True when used in an if statement is "truthy". The term for something that evaluates to False when used in an if statement is "falsy" or "falsey". So, your documentation can be written like this:
def foo(bar):
"""
Do some stuff.
bar : callable
must return a truthy value iff XXX.
"""
if bar(...):
... # code goes here
"Iff" is more slang, this time from the mathematical world. It means "if and only if". These words are commonly used in programming contexts, so I expect most programmers will understand them; if not, truthy, falsy, falsey and iff all come up with their respective correct meanings when searched in a search engine.
I'm not sure if there's a standard for this, but based on python's Truth Value Testing you would probably be safe writing something like
def foo(bar):
"""
Do some stuff.
bar : callable
when tested for truth value, return value should evaluate to True if and only if XXX.
"""
if bar(...):
... # code goes here
I would suggest that is is just fine to say "must return True if XXX and False otherwise." Because of duck typing, I read this the way you intend. Further, this seems to be standard in how the Python standard library documents things.
In fact, if you do strictly require the value to be True or False and use this language, I will have a very bad day tracking down this bug!
As others have said, "truthy" and "falsy" are fine, well-understood alternatives if you are still concerned.
I can't use if statements and loops in my assignment so I was wondering how I would rewrite this line:
if (not float(gravity).is_integer()):
It's just checking to see whether or not gravity is a float or integer so it can pass more code.
My guess is that the assignment is trying to teach you a paradigm of "Ask forgiveness not permission".
In that case:
try:
gravity = float(gravity)
# Do floaty gravity stuff
except (TypeError, ValueError):
gravity = some_default_value_you_can_handle_some_other_way
You can use shortcut operators to achieve logical flow without an if statement.
E.g.
float(gravity).is_integer() and do_stuff()
The second part will only execute if the first part is true.
Alternatively you can use
float(gravity).is_integer() or do_stuff()
where the second part will only execute if the first part is false.
UPDATE
I just read the comment about how the function is simply meant to evaluate if two sides yield an integer hypotenuse. So unless I misunderstood what you're after here, in that case, the whole point is that you don't need an if statement to decide whether you should then explicitly return True or False by yourself; you can simply return the output of the evaluation of is_integer() directly, since this will evaluate to either True or False anyway.
You could use assert in combination with a try block:
try:
assert(not float(gravity).is_integer())
print("evaluated to true")
except:
print("evaluated to false")
Replace the print statements with the code you want to execute in case it evaluates to true or false.
I found this kind of expression several times in a python program:
if variable is not None:
dothings(variable)
It seems strange to me, and I think that it has no more sense than:
if variable:
dothings(variable)
Maybe I don't know Python enough, and the expression is explained somewhere?
variable could be 0, or False, or [], or (); be 'falsy' in other words, and then the if statement would be skipped.
See Truth testing for more detail on what is considered false in a boolean context.
In short, testing if variable is not None allows variable to be anything else, including values that would otherwise be considered False in a boolean context.
Some values are falsy, but are not None. You may still want to dothings() to those values.
Here are the things that are falsy in Python 2. (You may want to change the '2' in the URL to a '3' to get the values for Python 3, but it didn't change much.)
E.g.
i = 0
if i is not None:
print i # prints i
if i:
print i # prints nothing
In the google voice python implementation I came across this as well, their use was during a function call. The parameters are defaulted to "None" and then when the function is called they can check if the values are changed or the default.
I.E.
def login (user=None, password=None)
if user is None:
user = input('Please enter your username');
...
return <something>;
called by
login()
OR
login(user='cool_dude')
OR
any combination of user/password you wish.
Additionally your "update" of the logic implies that variable == true or false. That is not correct for all cases (it may work in some cases but I'm throwing them out, since it's not a general case). What you are testing by using the "NONE" logic is whether the variable contains anything besides NONE. Similar to what I was saying above, all the "login function" was doing was determining if the user passed anything, not whether the value was valid, true, etc.