Course Content
1.
Python Variables
0 min
3 min
9
2.
The Print Function
4 min
4 min
0
3.
Numbers and Math in Python
0 min
1 min
0
4.
What is Machine Learning?
0 min
6 min
0
5.
Strings in Python
0 min
11 min
0
6.
Comments in Python
0 min
4 min
0
7.
Functions in Python
0 min
26 min
0
8.
String Formatting with F-Strings
0 min
3 min
0
9.
Conditionals, Booleans, and If Statements
0 min
12 min
0
10.
Intro to Python Lists
0 min
6 min
0
11.
Intro to Python Lists - Exercises
0 min
2 min
6
12.
Lists as a Sequence of Values
0 min
6 min
0
13.
Coming Soon...
0 min
1 min
0
- Save
- Run All Cells
- Clear All Output
- Runtime
- Download
- Difficulty Rating
Loading Runtime
Booleans
In this lesson we're going to introduce a new datatype called "booleans" (sometimes also called "bools" for short). Just like numbers, and strings, booleans are a kind of value that we can store to a variable. Booleans are easy, because there's only two options for values that we can store. Those values are:
True
or False
–and that's it.
These values should not be wrapped in quotation marks, (or else they'll be considered to be strings) and in Python, the capitalization on these values is very important. The first letter of both of these values should always be capitalized.
Let's store one of these values to a variable, print it out, and check out its data type.
True
<class 'bool'>
We could also have used False
to the same effect.
False
<class 'bool'>
Conditions
Alright, so True
and False
are the only options for this type of variable, but how will booleans be useful to the code that we write?
Well, typically when we're programming we won't directly save the values of True
or False
to a variable (we absolutely can do that if we want, I mean, we literally just did that), but most likely, these values will be generated within our code as the result of something called a "condition". A condition is an "expression" or in other words a short piece of code that evaluates to either True
or False
. That means that when Python is running our code some parts of that code will resolve to either True
or False
. Let's write some examples of conditions to better demonstrate what I mean.
In order to create a condition, we have to compare two things. In this instance let's use the numbers 10 and 5, and let's use a "greater than" sign >
to compare them. Is 10
greater than 5
? Yes, it is, so this condition evaluates to True
.
True
Notice that I didn't explicitly write the value of True
anywhere in my code, but that's what Python understood as it evaluated the expression –or in other words as it ran the code.
Similarly, if I change the symbol in the middle and I write 10 < 5
... Well, is 10
less than 5
? No, it's not, so this condition will evaluate to False
.
False
These are two examples of conditions, and you'll notice that each of these expressions has a symbol in the middle that allows the values on the left and right to be compared to each other. These expressions can only evaluate to either True
or False
. Remember that symbols in Python that do something specific are called "operators". So here we've used two "comparison operators" –the "greater than" symbol in the first example and "less than" symbol in the second example. There are six common comparison operators in Python:
Comparison Operators
==
- The "equality operator" aka ("equal to")!=
- The "inequality operator" aka ("not equal to")>
- The "greater than operator"<
- The "less than operator">=
- The "greater than or equal to operator"<=
- The "less than or equal to operator"
These symbols are also sometimes referred to as a "conditional operators" or "relational operators" -so don't be alarmed if you see different terminology used to discuss them in other places. Like always I want to explicitly call out this terminology because it's as much part of the "language" of Data Science as Python is.
The Equality Operator (==) is not the same thing as the Assignment Operator (=).
I also want to point out that the equality operator ==
(two equals signs) is not the same thing as the variable assignment operator =
(one equals sign). In Python, we use two equals signs to check for equality, and one equals sign means to assign values to a variables.
Control Flow
Ok, so we've learned about how we can use comparison operators to write simple conditions that compare two values. These expressions as a whole will evaluate to either one of two boolean values: True
or False
. You're doing great if you can follow all of the new terminology that I just used.
Ok, now back to our original question of –How will booleans (and more importantly conditions that evaluate to one of two booleans) be useful in the code that we write?
Well, using these conditions we can cause different lines of code to run depending on if these conditions are met or not. In other words, if a certain condition evaluates to True
then we run some lines of code, our program reacts in a predetermined way. Or if the condition evaluates to False
then our program reacts in some other way. The act of controlling how our program runs based on if certain conditions are or are not met is called "Control Flow", and it's an absolutely critical part of programming –in any programming language.
Examples of Control Flow
We use "Control Flow" all the time in our daily lives even when we're not coding.
Is it raining outside? If it is, if that's True, I'll take an umbrella. If it's not, if it's False that it's raining outside, then I won't.
Is the light green at the traffic signal? If so, then I'll move forwards. If it's yellow, I'll slow down. And If it's red, then I'll come to a stop.
Notice how I'm saying if
and then
a lot?
"If it's raining... then I'll do something."
"If the light's green... then I'll do something."
This if-then thinking is the basis of Control Flow, now we just have to learn how to express if-then thinking in our code. Let's look at a concrete example to demonstrate.
Expressing Control Flow in Code
Imagine that we're writing a program for a school that looks at students' scores and tells them whether or not they passed the class. Let's say that this class is graded as pass/fail, meaning, that if a student gets a high enough score they will pass the course, but if it's too low they will fail.
Let's say that a student has to get a score of 70 or higher (out of 100 points possible) in order to pass the course.
How might we use a condition to respond to and execute different lines of code based on a student's score? Well, we need one more piece of the puzzle in order to do this. We need something called an if statement.
If Statements
To show you how if statements work, to start off, let's say that a particular student has a score of 85
. Let's make a variable called score
and assign it the value of 85
.
Next we'll write our if statement. We'll first write the Python reserved keyword if
–that's why it goes purple is because it's a reserved keyword. Then we put a space and next we write our condition. Let's use the condition score >= 70
. So if this condition evaluates to True
then the student will have passed the class. If it evaluates to False
, then the student will have failed the class.
After we write our condition we finish the opening line of our if statement with a colon :
. You'll recall that when we write functions we also put a colon at the end of the first line. The colon says, "Hey, there's some stuff that's going to come after this that is going to be considered to be "inside" of the if statement". And just like when we wanted code to be inside of a function, we also have to indent any code that we want to be inside of the if statement.
So we'll indent the next line, and for now we'll just print out a message, something like "Congratulations, you passed the course!"
Let's go ahead and run the code.
Congratulations, you passed the course!
Nice! we see the message was printed out because the score
variable held the value of 85
, and that caused the condition to evaluate to True
, (because 85 is indeed greater than 70). Because the condition was met, the indented block of code below (in this case just our print statement) was executed.
This if statement has allowed us to add if then logic to our code. If a student's scores is greater than or equal to 75, print out the message.But what if a student scored less than 70? What would our code do in that case? Let's try it.
Let's change the score
variable to 50
, and see what happens.
Well as you can see, if a students' score is less than 70
, our code currently doesn't do anything. One thing we can do to address this oversight is to add another if statement, something like...
If score
is less than 70
, print "I'm sorry, you failed the course."
I'm sorry, you failed the course.
Nice! Now our code responds with the correct message based on the value that is saved to the score
variable. (Which in a real scenario would come from the course's grade-book or something like that.)
In theory, we could do all of our control flow with if statements just like the one's we've written above, but many times, when we have multiple conditions that we want to respond to –particularly if the conditions we're testing are related or similar to each other– there's a slightly better (and more readable) tool that we can use.
We can use something called if-else statements.
If-else Statements
If-else statements are a way that we can combine the two conditions we're checking above into a single more coherent body of code. We start off in much the same way –by writing the first if statement exactly like we did previously– but this time, instead of writing a second if statement. We're going to write the reserved keyword else
followed by a colon. This line of else:
should not be indented.
the else:
block will cover any instances that were not addressed by the above if-statement. In other words if the if statement's condition is False, then the else statement will be triggered, no questions asked.
In this case, because our condition is binary (you either pass the course or you fail the course), this else
statement is doing exactly the same thing as the second if statement that we wrote before, it runs whenever the condition evaluates to False
.
Feel free to change the value that we're assigning to the score
variable here to test it out for yourself.
Aside from improvements to the readability and coherence of the code here. If else statements are also slightly more efficient from a computation standpoint than using multiple if statements, because the second half of the expression doesn't have to evaluate a completely separate second condition anymore. The else
portion only runs if the condition (or conditions –plural– as we'll see in a minute) above it do not evaluate True
.
Whenever I see an else:
statement I like to imagine that it's actually saying "otherwise" but that longer word would be more typing, and we know how programmers like to avoid typing whenever they can.
If the student's score is greater than or equal to 70, print the congratulatory message, OTHERWISE print out the failure condolence message.
I'm sorry, you failed the course.
Let's switch the score back to 70
now, and as I run the code please notice that if the condition in the first if statement evaluates to True
then the else
block is ignored.
Congratulations, you passed the course!
If-elif-else Statements
Okay, so if-else statements are really handy for evaluating binary scenarios like pass/fail, but what if the scenarios that we want to check are more complex? Maybe the class isn't pass/fail but rather gives out letter grades based on the range that a student's score falls into.
Let's pretend that the class policy –as stated in the syllabus I'm sure– indicates the following grade cutoffs:
- Grade of "A" for scores of 90 and above.
- Grade of "B" for scores of 80 and above.
- Grade of "C" for scores of 70 and above.
- Grade of "D" for scores of 60 and above.
- Grade of "F" (or a failing grade) for scores below 60.
To implement this more complex scenario in code we'll use an if-elif-else statement. Which you'll see is really just an extension of an if-else statements, but we're going to use a new keyword elif
(also followed by a condition and then a colon :
–just like in a regular if statement.) that will allow us to test extra conditions after the initial if statement, but before we reach the else
statement at the bottom. By the way, elif
is shorthand for "else-if". So it's like we're saying, hey, if the condition in the first if statement didn't evaluate to true, check this condition next.
Order is very important
Okay, so let's try and translate our class policy into code here. I'm going to use the correct code syntax for our if-elif-else statement, but I'm going to make a big mistake in the logic that I'm using. You'll see what I mean. This will help me make a very important point about if-elif-else statements.
You received the grade of "F" in the class.
Pause the video and see if you can tell what's wrong with my code before I point it out to you.
Ok, so let's test out a score of 50
. That looks good.
What if we test out a score of 60
? That looks good too.
Ok, now a score of 70
... Uh oh, that's not the message the we wanted to print out. What has gone wrong? A student with a score of 70
should have receive the grade of "C"
not the grade of "D"
.
So what has gone wrong?
Let's walk through the code line by line just like Python would. This is an important debugging skill for us to practice.
You received the grade of "D" in the class.
What's going on here is that the way in which we order the different branches of the if-elif-else statement can be very important. Because Python evaluates our code from top to bottom, as a general rule of thumb we want to test the most specific condition first, at top of the statement, and then have the conditions get more general as we move down, ending with the else
statement as our catch-all if none of the conditions above that were met (AKA evaluated to True
).
The reality here is that the way we've written our conditions currently allows for some overlap. A score of 95 is greater than 90, but it's also greater than 80, and greater than 70, and 60, etc., so which branch of the if statement should be triggered when a student's score is 95?
The key thing to be aware of is that once Python finds a branch of the statement whose condition evaluates to True
, that Python will run that branch of the statement and then ignore all of the others, even if there happen to be other conditions that would also evaluate to True
below it.
In a perfect world we would prefer to take the time to think through how we write the conditions so that we avoid this kind of overlap, but we can sometimes save ourselves some headache by just putting the most specific condition first, so that if it's met, the rest of the more general (and potentially overlapping) conditions are ignored.
The most specific condition in this instance here is if a student's score is greater than or equal to 90. The next most specific condition is if a student's score is greater than or equal to 80, and so on.
So if we order our statements in that way, the code will run as expected in all cases. Try changing the student's score to see for yourself.
You received the grade of "C" in the class.
Putting it in a Function
Lastly, it bothers me that we have this code all out loose responding to a hard-coded variable at the top of the expression, let's wrap it in a function that we can dynamically pass a student's score to.
We'll call our function final_class_grade
and we'll pass it a score
, and then instead of printing out the messages, let's return them. This will have the effect of causing them to be printed to the output section of the code cell just like if we had used the print function (because notebooks will automatically output the last value in a cell for us).
You received the grade of "D" in the class.
Okay, I think that's enough for one lesson. In the exercises I'll try to gradually ramp up the difficulty and complexity of the if statements that are required so that the concepts will have a chance to sink in before the exercises get too difficult.