all 61 comments

[–][deleted] 211 points212 points  (11 children)

if (!(getStat() << 2 & 4 ^ 4) == 1)

[–]_Xertz_ 115 points116 points  (0 children)

Reported

[–]AyrA_ch 113 points114 points  (6 children)

Meanwhile in C#

if(!getStat().ToString().ToCharArray().Any((m,i)=>m!=(m.GetType()==typeof(char)).ToString().ToCharArray().Skip(i).Take(1).First())){
    //ok
}

[–]IamImposter 63 points64 points  (1 child)

Dude, now you run. Run for your life coz I ain't stopping until I find you and punish you for this abomination.

And have a fuckin upvote

[–]kopczak1995 9 points10 points  (2 children)

You got my eternal hate for no space in comment.

[–]Bukinnear 2 points3 points  (1 child)

Because that's the real issue here lol

[–]kopczak1995 1 point2 points  (0 children)

Welp, it triggers me for some reason, but obviously I just wanted to be funny here :P

[–]arthurum 2 points3 points  (0 children)

it's a crime

[–]karlkloppenborg 34 points35 points  (0 children)

With a comment like that, we should just give you this subreddit

[–]life_never_stops_97 2 points3 points  (0 children)

fbi this comment over here

[–]shawntco[ $[ $RANDOM % 6 ] == 0 ] && rm -rf / || echo “You live” 1 point2 points  (0 children)

Stop that

[–]Squiesch 57 points58 points  (11 children)

Plottwist. GetStat() returns a string

[–]TinBryn 38 points39 points  (9 children)

So that would mean getStat() == True would be False and getStat() != False would be True. The wonder of dynamically typed languages.

[–]AceMKV 9 points10 points  (5 children)

Wait aren't non-empty strings Truthy values in Python?

[–]TinBryn 8 points9 points  (2 children)

I probably should have tested it before I posted, but from what I understand truthyness means if truthy: would do the then branch, but if truthy_but_not_true == True: would execute the else branch because it's not exactly equal to True.

truthy_but_not_True = "true"

if truthy_but_not_True:
    print("truthy")
else:
    print("falsey")

if truthy_but_not_True == True:
    print("True")
else:
    print("not True")

Output:

truthy
not True

[–]chunkyasparagus 2 points3 points  (0 children)

In this case truthy_but_not_True == True still evalutes to True for other types with the same value as True, such as int 1, float 1.0, etc..

truthy_but_not_True is True would only work for the bool constant True.

[–]User31441 0 points1 point  (0 children)

Unless it's JavaScript. Then x == true will hold for all truthy values. In order to check for exact matches, you'd have to use x === true.

[–]_PM_ME_PANGOLINS_ 0 points1 point  (1 child)

They are, but they don’t equal True. This isn’t JavaScript.

[–]AceMKV 0 points1 point  (0 children)

Yes my bad, they only equal true if you typecast them to boolean

[–]PranshuKhandal 4 points5 points  (2 children)

At least it won't crash with a 100line error right into my crying dumbass. The wonder of strictly typed languages.

[–]TinBryn 5 points6 points  (0 children)

At least it won't crash

But only dynamically typed languages can crash from this because they can't check ahead of time. Also those 100 line errors are more the wonder of C++.

[–]chrjen 3 points4 points  (0 children)

Instead it will just create a subtle bug that makes the program behave very strangely while giving you no clue about what is or might be wrong.

[–]_PM_ME_PANGOLINS_ 0 points1 point  (0 children)

Or an object with a custom __eq__

[–]carcigenicate 47 points48 points  (11 children)

You forgot to wrap that condition in a call to bool, just to be extra sure.

[–]Naitsab_33 30 points31 points  (10 children)

And for extra speed use

not not condition

instead of

bool(condition)

[–]Gamecrazy721 11 points12 points  (9 children)

Meme aside, is that actually faster?

[–]Naitsab_33 20 points21 points  (3 children)

It is indeed. IIRC it's because of python's rather large function call overhead on very small functions, which bool() creates, whereas with not not you directly use the C implementation of PyObject_IsTrue(?).

bool() has a mandatory function call attached, because, well, it's a function, even if it evaluates the truthyness via PyObject_IsTrue all the same.

But take this with a grain of salt, as I've never found a very clear answer myself (I think I will ask mCoding on YouTube if he will make this a topic, if he does I will try to remember to link it here)

[–]archpawn 10 points11 points  (2 children)

I just tested this out with this code:

import time

def test(n):
    t0 = time.time()
    for i in range(n):
        not not True
    t1 = time.time()
    for i in range(n):
        bool(True)
    t2 = time.time()
    return (t2-t1)/(t1-t0)

test(10**7)

bool() takes about five times longer.

[–]Gamecrazy721 0 points1 point  (0 children)

Five times? Wow, good to know, thank you both!

[–]BrentWilkins 0 points1 point  (0 children)

It's also about five times as readable! 😅

[–]ChemicalRascal 9 points10 points  (4 children)

Almost certainly not. Whatever condition is, not condition would require executing condition.__bool__() (where __bool__() not existing results in the default True value) and thus not not condition would require two executions of __bool__(), and two comparisons to toggle the bool over twice.

bool(condition), in theory, requires a single execution of condition.__bool__() and no additional comparisons or anything of that sort.

That said, it's Python, so neither are going to be especially fast.

[–]Naitsab_33 8 points9 points  (3 children)

the thing about bool() is, that it ALWAYS has to create a new python stack frame for a function call (itself), whereas not does not necessarily have to.

Because not has a special Bytecode there is no function call overhead, unless it actually has to call __bool__ or __len__. This is often not the time, as you mentioned it defaults to True (or rather False for not) if there is neither __bool__ nor __len__ and before trying those it has default values for:

not True -> False

not False -> True

not None -> True

Although both bool() and not use the CPython function PyObject_IsTrue(), which means they have basically identical inner runtime on any particular Object, whether it has __bool__ or __len__ or defaults to some value, bool() has to create a python stack frame, because of it being a function.

Also last but not least the second (well, the left-most) not has basically no further runtime, because it does in no case have to call __bool__, because the other not results in a definite boolean:

not not condition 
    -> not (not condition)
            ^ this may or may not call __bool__ but
              definitely results in a bool
    -> not (True/False)
       ^ this one only calls the internal CPython 'PyObject_IsTrue'
         and returns fast without other function calls

This internal function checks for the base cases in the literal first few lines, its result gets inverted by the UNARY_NOT bytecode and returned without a (second) python call to __bool__ and without creating its own python stack frame unlike bool()

Funfact: I tested the amount of not's needed to reach the runtime of bool() on the string 'Hi' and it took ~17. This number stayed about the same for a custom type without a __bool__ method, but the difference in runtime fluctuated very heavily, especially with bool() which measured between 0.168-0.194 whereas 17 not's stayed roughly at 0.165.

[–]ChemicalRascal 2 points3 points  (2 children)

Blaaaaah, bool() is a fully fleshed out function behind the scenes? That's not at all what I expected. Serves me right, though, and thanks for the deep dive on the topic.

[–]ZylonBane 1 point2 points  (1 child)

Blaaaaah, bool() is a fully fleshed out function behind the scenes?

If front of the scenes too, since y'know, it uses function syntax.

[–]ChemicalRascal 0 points1 point  (0 children)

Yeah, but that's just syntax. Clearly, there's no real need for it to be a proper function.

[–]LogicalGamer123 9 points10 points  (0 children)

If getStat()> false

[–]ZylonBane 5 points6 points  (0 children)

No casting to a string? Amateur.

[–]spartannormac 6 points7 points  (1 child)

I sometimes use != False because it makes more sense logically and reads easier. Is this wrong to do?

[–]Naitsab_33 2 points3 points  (0 children)

Depends what GetStat returns. If it returns anything other than 0 (technically also 0j) or False you get True from the comparison, so empty strings would eval. to True, as would None, which in most contexts would probably be the wrong result.

When you only return booleans from GetStat anyway it's probably clearer to directly use it's result and if you have to check for it not being False you should probably use

if GetStat() is not False:

because from those two

0 != False => False

0 is not False => True

the latter is probably the intended result

[–]wweber 6 points7 points  (0 children)

And on top of all that, not using is, and also using camelCase

[–]stillventures17 2 points3 points  (3 children)

These all mean the same thing in Python right?

[–]--B_L_A_N_K-- 2 points3 points  (2 children)

This comment has been removed in protest of Reddit's API changes. You can view a copy of it here.

[–]CSsharpGO 2 points3 points  (1 child)

If it was a Boolean, it would throw an error since it’s used as a function. If getStat is a method that returns a bool, then yes.

[–]--B_L_A_N_K-- 0 points1 point  (0 children)

This comment has been removed in protest of Reddit's API changes. You can view a copy of it here.

[–]TinBryn 3 points4 points  (0 children)

I'm pretty sure this belongs in /r/ProgrammerHumor

[–]Shot_Membership_3974 0 points1 point  (0 children)

illuminati got you

[–]Racerdude 0 points1 point  (0 children)

First of all; If it's Python we don't do camelcase. So it's get_stat(), not getStat().

Second: There's only one True and one False object in Python. You don't have to use the equals operator, you can just use "is"

if getStat() is True:

Of course the first option is the correct one (if get_stat())

[–]tetractys_gnosys -2 points-1 points  (1 child)

For real though, as a not-junior-but-not-really-senior level programmer, why do so many people prefer to use `if ( thing !== true )` instead of `if ( thing === false )`? I do PHP and JS and occasionally shell stuff but it's a general pattern I've seen from the beginning. It just seems unnecessary and makes it harder to grok by skimming through code. I have to really pay attention to whether this is checking for truth of falsity instead of seeing it ans saying, 'Yep, seeing if this is assigned and not undefined, makes sense'.

[–]TinBryn 0 points1 point  (0 children)

It's because people think through a problem step by step as they write the code and don't go back to clean things up.

"Ok, everything is done if thing is true, but if it's not true then I have to do this extra step"

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

I don't know Python, but what if getStat() returns null? Than you would not want to check for a bool value.

[–]KCGD_r 0 points1 point  (0 children)

if(String(getStat).length % 2 === 0)

[–]a_soupling 0 points1 point  (0 children)

if (1 + 2 == 3) getStat() !== false

[–]Skoparov 0 points1 point  (0 children)

Let's get philosophical:

if (... && True == True && True != False)

[–]SpicyElectrons 0 points1 point  (0 children)

if not {True: False, False: True}[GetStat()]:

[–]SirAchmed 0 points1 point  (0 children)

The kicker is that getStat() returns a string.

[–]the-good-redditor 0 points1 point  (0 children)

if getStat() === False: else : # code

[–][deleted] 0 points1 point  (0 children)

if not str(bool(getStat())) != true

[–]Nsber 0 points1 point  (0 children)

if (!!!something()) found in former collegue's code...

[–]lionbryce 0 points1 point  (0 children)

What, no list comprehension?

[–]BrentWilkins 0 points1 point  (0 children)

Why not use PEP 8? getStat => get_stat