Write Pythonic Code Like a Seasoned Developer Transcripts
Chapter: Foundational Concepts
Lecture: Truthiness and boolean statements
0:01 Now that we've got more or less obvious PEP 8 items out of the way, let's talk about a handful of what I consider foundational items.
0:09 They don't fit neatly into some classification like loops, or classes or something like that,
0:15 but they are really important so I put them at the beginning. The first thing I want to talk about is what I am calling truthiness,
0:22 the ability to take some kind of symbol or object in Python and test it and have it tell us whether or not it should evaluate to be True or False.
0:31 So just to remind you in case you don't remember all the nuances of truthiness in Python, there is a list of things that are defined to be False,
0:39 and then if it's not in this list, if it doesn't match one of the items on the list, it's considered to be True.
0:44 So obviously, the keyword "False" is False, empty sequences or collections, lists, dictionaries, sets, strings,
0:52 those types of things, those are all considered to be False even though they are objects which are pointing to real live instances.
0:59 The numerical values zero integer and zero float are False, "None", that is the thing that represents pointing to nothing, is False
1:08 and unlike other languages like say C where the null is actually defined to just be a sort of type def back to the zero,
1:16 "None" is not zero but it's still considered to be False. And if you have a custom type you can actually define its truthiness by
1:23 in Python 3 defining a dunder bool, or Python 2 dunder non-zero. All right, if you are not on that list, then whatever you are testing against is True.
1:33 Now let's just review, that's not Pythonic code per se, so let's see how this leads us to Pythonic behavior around testing for True and False.
1:42 All right, here I have a real basic method I call print truthiness, and let's just test it here, I can say print the truthiness of True
1:55 and we could also test False I suppose, so if I run this, no surprise, True is True, False is False
2:02 and you can see we are using this ternary statement here, "TRUE if" expression, "else FALSE". Now we are not saying if expression == True,
2:11 we are using the implicit truthiness of whatever it is that we are passing, here it's the True and False values, but it could also be a sequence,
2:20 it could be some other kind of expression, all right. So the recommendation for Pythonic tests on True/False like this
2:29 is to do something along these lines, it's to actually use the truthiness inherent in the object itself,
2:35 so you would say something like if I had a val, let's just say it's 7, I would say "if val" and down here I would do something,
2:44 I wouldn't say "if value == True", or "if value is not equal to zero", I would just use the implicit truthiness that here is a number,
2:52 if it's non-zero, which in theory I was testing for, it's True, otherwise it's False. So let's see this for sequences, so if I have some sequence,
3:01 let's make a list, it could be a dictionary or whatever, we could print the truthiness of empty list and we could have our sequence here,
3:10 and you can see an empty list is False, but now if I add something and I run it again, and I test for the list with one item,
3:19 then you can see, now it's coming out to be True. You can see we can put in here numbers like zero, we can put in 11, or even -11,
3:31 and zero of course is False, the others are True. Now we can call this function print_truthiness on "None" as well,
3:38 maybe leave a little comment here, we'll say "for none", if we pass None, it's going to evaluate to be False,
3:44 this is not the best way if you are explicitly expecting None to test for it we'll talk about that as a separate item,
3:50 finally we can define a class called a class or whatever you want to call it and maybe it's going to have some kind of internal collection,
3:58 we'd like to surface that so we could use the instance of this class itself
4:02 in a sort of truthiness way, so down here we'll give it some data like a list here, we'll give it the ability to add an item to its set
4:12 and then we'll go over here and since it's Python 3, we are going to define dunder bool
4:17 and here for bool we can define one of these ternary statements, we can say "return True if self.data" and just leverage
4:25 the truthiness of data itself, "else return False". And then once we do this, we can come down here and say "a = AClass()",
4:32 we can print and of course if we run it empty, we would expect it to be False, and there it is, it's False,
4:40 now if we add and item to it and we print it again, now it evaluates to True. So the Pythonic expectation here or the Pythonic style is
4:51 when you are testing objects, leverage their implicit truthiness, now we'll write something like "this is True if
4:57 the length of data is greater than zero." Now, we don't want to write that, we just want to say "if data", it has an implicit truthiness
5:05 and we are going to leverage that. So here you can see we've got basically the same code,
5:10 True if the expression evaluates to True, via its implicit truthiness, else we'll state False, we've got empty collection and it evaluates to False.
5:18 We add something to the collection and it evaluates to True, however notice we can't actually test the data equal to True
5:25 so we can't say print me the truthiness of "data == True" because that's False, these are not the same things,
5:30 you are basically comparing a list to a singleton True value, a boolean which never is going to be equal, so it's always going to say False,
5:39 but we can leverage the truthiness of data and it will come back as True. Finally, if we are going to create a custom type
5:45 that is itself imbued with truthiness, we give it a dunder bool method and then we just return True or False, depending on how we want it to behave.
5:53 You can see below our empty version is False, our non-empty version is True.