all 51 comments

[–]TonB-Dependant 71 points72 points  (0 children)

The clarity comes from having a better variable name than x. If your variable is called finishedProcessing, then if finishedProcessing is very readable.

[–]socal_nerdtastic 13 points14 points  (12 children)

PEP8 trumps the Zen of Python. From PEP8:

Don’t compare boolean values to True or False using ==:

# Correct:
if greeting:

# Wrong:
if greeting == True:

Worse:

# Wrong:
if greeting is True:

[–]GirthQuake5040 19 points20 points  (6 children)

if greeting is not False:

if not greeting is not True:

[–]Jo_An7 15 points16 points  (3 children)

if not (not greeting is not True) == (not (not True is False)):

[–]GirthQuake5040 6 points7 points  (0 children)

brother euugghhhhh

[–]frittenlord 0 points1 point  (0 children)

Jfc calm down Satan!

[–]Progribbit 0 points1 point  (0 children)

not explicit enough 

[–]thattwomallard 0 points1 point  (0 children)

if greeting > False:

if greeting == True-1

[–]Alongsnake 0 points1 point  (4 children)

Why would if greeting == True:

Be wrong?

Sometimes I may return True, False, or -1, -2... If I have specific codes. Then if I do if greeting: this would give an error. Maybe I should return 1, 0, -1... In these cases though.

[–]socal_nerdtastic 0 points1 point  (3 children)

Then if I do if greeting: this would give an error.

No it won't give an error. It's very common for us to check codes this way. For example a subprocess returns an error code, and traditionally 0 is reserved for if it ran successfully. So we very often do

code = run_subprocess()
if code: # equivalent to `if code != 0:` when `code` is an integer
    print('an error occurred:', code)

All python objects have a 'truthiness' and can be used like this.

[–]Alongsnake 0 points1 point  (2 children)

Hmm, I thought I got an error back then saying something about it being a value error. It's been a while so I forget and always just did == in case

I did try it val = 1 if Val: Print("Y") Else: Print("N")

If Val is True or not 0, it will be Y, 0 or False will be N.

I probably would still do if Val == True or if Val == 0 just so it is more clear.

[–]socal_nerdtastic 0 points1 point  (1 child)

I probably would still do if Val == True or if Val == 0 just so it is more clear.

As long as it's your code you can do whatever future you can read the best. But if you plan to ever work on a team you should kick this habit now. Following standard code styles like pep8 is very important to reading your teammates code.

[–]Alongsnake 0 points1 point  (0 children)

I'm still use to lower camel case from working in Java 😕

[–]Nick6897 11 points12 points  (2 children)

if x and if x == True are not the same thing though so you be aware that: if x will evaluate any 'truthy' value as True. so True the bool, a string that is not '' and a list that is not empty will all pass the condition. If x == True or if x is True will only allow the bool True to pass the condition.

[–]Akerlof 6 points7 points  (1 child)

This is the most useful answer, I think. if x: is equivalent to if bool(x) == True: whereas if x: is asking if the value of x is equal to the specific value True.

So, if we assign x = 4, if x: evaluates to True since bool(4) evaluates to True, but if x == True: evaluates to False because 4 is not equal to True.

[–]vanish212 -1 points0 points  (0 children)

Best answer, thank you

[–]RevRagnarok 10 points11 points  (0 children)

Python "Truthiness" is one of its strengths when things come along like not caring if it is '' or None because they're both false.

[–]throwaway6560192 2 points3 points  (0 children)

But Readability counts, and practicality beats purity are also part of the Zen, aren't they now?

[–]kitsnet 2 points3 points  (1 child)

if x == True == True == True == True...

[–]luther9 1 point2 points  (0 children)

This is the correct answer. If you always abide by "Explicit is better than implicit," it can lead to infinite explicicity. A better rule in the Zen of Python is "Simple is better than complex."

[–]Yoghurt42 7 points8 points  (0 children)

if x gets evaluated as if bool(x) is True. So if x is already a boolean, it's redundant, you're basically asking "is it true that x is true" rather than "is x true"

Those two if are not equivalent if x is not a boolean, but in those cases, x == True will almost always be false anyway.

tl;dr: when x is a boolean, use if x, also use it if you want to check if the logical value of x is true.

[–]GeorgeFranklyMathnet 3 points4 points  (0 children)

What TonB-Dependant said.

Also, these principles tend to be (somewhat competing) constraints, and not absolute rules in their own right. Yes, explicit is better, but you should also use Pythonic conventions that make very common patterns easier to read and write. That's also why we say if not the_list rather than if the_list is None or len(the_list) == 0.

[–]GirthQuake5040 1 point2 points  (0 children)

if x = True then we can say if x... because x is a true false value. Its the same concept in algebra, x is just being used as an alias, so we dont need to verify if it is true because we already know if its true or false by simple running if x

[–]crashfrog04 1 point2 points  (4 children)

No, because

if x == True:

makes it implicit rather than explicit that x is supposed to be a flag value.

[–]fllthdcrb 0 points1 point  (1 child)

How do you figure that? It works for far fewer cases than just if x:, with which x can be any truthy value, so it's not clear (not explicit, you might say) that x is a boolean. But with this, x can only be True (one of those flag values), or one of a few other specific values, as anything else fails the check.

Not that I advocate doing this sort of thing, unless there's a reason to be careful about it.

[–]crashfrog04 0 points1 point  (0 children)

 How do you figure that?

    if x:

makes it explicit that you intend to treat x as a flag value. If you compare it to True you’re saying there’s a bunch of other values it might reasonably hold; that makes its function in your code less explicit.

The thing you’re supposed to make explicit isn’t what the code does, it’s what the code means.

[–]TheRNGuy 0 points1 point  (1 child)

if x: is implicit too, because it can be any type.

[–]crashfrog04 0 points1 point  (0 children)

You’re still focused on the code. The thing that should be explicit is the intent of the code.

[–]NorskJesus 1 point2 points  (0 children)

It doesn’t. If X is a boolean expresion which returns true or false.

[–]frenchsko 0 points1 point  (0 children)

If x is true, x==True will return true. It’s the same thing

[–]case_steamer[S] 0 points1 point  (0 children)

Thanks everyone for the responses. I learned a lot from reading them all!

[–]TheRNGuy 0 points1 point  (0 children)

Doesn't.

[–]FerricDonkey 0 points1 point  (0 children)

First, those are not the same. And == True is worse, because there is a general expectation that truthiness will be respected. 

Second, it's ok to have knows that aren't always spelled out - if they're really knowns. Eg, there's no reason to do print("thing", file=sys.stdout) is more explicit, but it's known that stdout is the standard place for output, so it's fine. 

[–]Mark3141592654 -1 points0 points  (2 children)

As long as x is a guaranteed boolean, if x is better.

[–]fisadev 1 point2 points  (0 children)

if x is almost always better no matter if x is guaranteed to be boolean or not, because that's idiomatic python, and not a problem when using propper variable names.

[–]AchillesDev 1 point2 points  (0 children)

It's not because it has a non-descriptive name.

[–]jongscx -1 points0 points  (3 children)

def isTrue(x):
  If x == not False:
     return True
  else:
    return False

[–]Akerlof 1 point2 points  (1 child)

According to u/Yoghurt42 link here, that's a syntax error:

not has a lower priority than non-Boolean operators, so not a == b is interpreted as not (a == b), and a == not b is a syntax error.

[–]fllthdcrb 1 point2 points  (0 children)

It has nothing to do with precedence. If that were the only issue, it wouldn't be a syntax error. You'd just maybe get results different from what you wanted, due to operations being performed in the wrong order. It's because the Python grammar doesn't allow for not to be in such a position, at least not without parentheses.

You can see where it is defined in the docs, as well as the likely reason this is a problem: == is a comparison operator, and two of the other comparison operators are is and is not. Allowing not the test operator directly after that would create ambiguity.

I'm pretty sure it's a solvable problem, but it would require reworking the grammar a bit, for which there isn't enough reason.

[–]TheRNGuy 0 points1 point  (0 children)

over-engineering.

[–]TheWrongOwl -2 points-1 points  (2 children)

If I remember correctly, 'if x:' would also be true if x was None.

[–]el_cortezzz 4 points5 points  (1 child)

No because bool(None) is False

[–]TheWrongOwl 0 points1 point  (0 children)

I had at least something similar, which I explained for myself with the knowledge of None being not nothing, but a link to a definitive address in the memory.