Suppose we'd like to write a program fragment that checks whether a variable refers to a valid GPA. A GPA (or grade point average) is a number between 0 and 4. We want our program to print a "valid" or "not valid" message depending on whether the GPA is valid. There are two conditions that need to be true for the GPA to be valid. First, it must be at least 0 and second, it must be at most 4. We're including both 0 and 4 as legal values. If the GPA is at least 0 *and* at most 4, then we know that the GPA is valid; otherwise, it is invalid. You might guess that we will use an if-statement to encode this logic. However, the if-statements that you have seen so far can encode only one condition -- x is less than y, for example, or x is greater than y. But our GPA example requires two conditions: gpa is greater than or equal to 0 *and* gpa is less than or equal to 4. We'll introduce a new operator that handles this task. This operator -- two and signs -- is the logical and operator. Logical and connects two expressions, and the resulting compound expression is true when the expressions on the left and right are *both* true. Let's use logical and to write the GPA example. In this line, we declare a float variable called gpa and give it an initial value of 2.3 -- a valid GPA. We will change this number later to an invalid GPA to further test our program. This if-statement uses the && operator that we just introduced. It includes two conditions: that the GPA is >= 0.0 and that the GPA is <= 4.0. Both of these conditions must be true for the "GPA is valid" message to be printed. In all other cases (that is, when one of the conditions is not true), then the "GPA is not valid" message gets printed. Let's try it. Notice that we get the "success" message. Let's change the 2.3 GPA to an invalid GPA. Let's try a GPA of 5.0. Now, as expected, we get the "invalid" message. Here's a different problem. Imagine that we have two GPAs and we want to determine whether one or both of the GPAs is at least 3.0. We have two conditions again: that the first GPA is at least 3.0 and that the second GPA is at least 3.0. But logical and is not the correct operator to use here. If we used it, then we'd be checking that *both* GPAs are at least 3.0. But that isn't what we want. It would exclude, for example, the case where the first GPA is 3.5 and the second GPA is 2.0. What we want this time is an operator that lets code run if the first condition, *or* the second condition, *or both* conditions, is true. And this new operator is written like this: as two vertical bars. It's called the logical or operator. Let's see this operator in practice to detect whether one or both GPAs are at least 3.0. These lines declare and initialize two variables to hold our GPAs. We've chosen 2.2 and 3.3 here. Notice that the first is at least 3.0 but the second is not. Here is where we use the || operator. We can understand this operator as saying when "gpa1 >= 3.0" or "gpa2 >= 3.0", then the entire condition is true, otherwise it is false. This if-statement will print the first message if one or both GPAs is at least 3.0. Otherwise, it will print the second message. If we run the program now, with GPAs 2.2 and 3.3, then we see that the correct message is printed. Now let's change 2.3 to 1.3. Now both the GPAs are under 3. If we run the program now, we see that the else branch has executed to once again print an accurate message. There is one more operator that we'd like to introduce here, and it's called the not operator. It can come in handy depending on how we think about the conditions for a given problem. For example, let's go back to our earlier task of determining whether a GPA is valid. There is an alternate way to think about this problem. Rather than determining when a GPA is valid, we could instead determine when a GPA is _invalid_. A GPA is invalid if it is less than 0 or greater than 4. To get a valid GPA, then, all we have to do is negate this condition. Whenever a GPA is _not_ invalid, then it is valid. We can write this using the not operator. Here is our new if-condition. We use the not operator, the exclamation mark, to negate the condition of a GPA being invalid. That gives us an alternate way of thinking about a GPA being valid. We have now introduced three operators: &&, ||, and !. These are called boolean or logical operators. One way to remember how these operators work is through their truth tables. Let's look at the truth table for and. This line is saying that if the expr1 is True and expr2 two is True, then the expression "expr1 && expr2" will be True. In fact, that's the only situation where the expression will be True. If either of the operands are False (or if they are both false), the result of a logical and will be false. Compare that to the truth table for ||, where we see that the rightmost colunn is true when we have at least one operand true. The truth table for not is simpler because it takes only one expression. It simply negates the truth value of the expression, from false to true or vice versa. These new logical operators contrast with the kinds of operators you saw in the previous video. These operators -- for example < and <= -- are called relational operators because they "relate" -- or compare -- two items to determine whether something is true or false. The operators in this video are called logical operators. They allow us to combine multiple conditions in various ways.