WEBVTT 00:00:00.150 --> 00:00:02.130 - [Presenter] How does the computer evaluate expressions 00:00:02.130 --> 00:00:05.220 with the logical operators and or and not? 00:00:05.220 --> 00:00:07.800 To find out, let's explore the order of operations 00:00:07.800 --> 00:00:09.900 for compound Boolean expressions. 00:00:09.900 --> 00:00:11.730 Imagine we're working on a program to check 00:00:11.730 --> 00:00:13.920 if a specific song matches the filters 00:00:13.920 --> 00:00:15.870 for a specific playlist. 00:00:15.870 --> 00:00:18.540 This expression asks, are the song's beats per minute 00:00:18.540 --> 00:00:21.120 both greater than or equal to 150, 00:00:21.120 --> 00:00:24.090 and less than or equal to 180? 00:00:24.090 --> 00:00:25.770 Logical operators like this and 00:00:25.770 --> 00:00:27.780 come last in the order of operations. 00:00:27.780 --> 00:00:31.110 So the computer evaluates the two sides separately first. 00:00:31.110 --> 00:00:34.590 Let's say the variable BPM contains the value 200. 00:00:34.590 --> 00:00:36.690 The comparison operators greater than or equal to 00:00:36.690 --> 00:00:39.240 and less than or equal to have the same level of precedence, 00:00:39.240 --> 00:00:41.580 so the computer evaluates left to right. 00:00:41.580 --> 00:00:43.650 So we substitute in that 200 00:00:43.650 --> 00:00:46.290 on the left-hand side first and simplify. 00:00:46.290 --> 00:00:48.900 200 is greater than or equal to 150, 00:00:48.900 --> 00:00:51.150 so this evaluates to true. 00:00:51.150 --> 00:00:53.400 Then we jump to the right-hand side. 00:00:53.400 --> 00:00:56.460 200 is not less than or equal to 180, 00:00:56.460 --> 00:00:58.620 so this evaluates to false. 00:00:58.620 --> 00:01:00.300 Now that we've simplified both sides down 00:01:00.300 --> 00:01:03.060 to a Boolean value, we evaluate the and. 00:01:03.060 --> 00:01:05.940 An expression with the and operator only evaluates to true 00:01:05.940 --> 00:01:07.500 if both sides are true. 00:01:07.500 --> 00:01:10.440 So a true and a false evaluates to false. 00:01:10.440 --> 00:01:12.521 And boom, the computer has its answer. 00:01:12.521 --> 00:01:13.920 Let's try an expression 00:01:13.920 --> 00:01:15.990 where there are multiple logical operators. 00:01:15.990 --> 00:01:17.130 This asks the question, 00:01:17.130 --> 00:01:20.100 is the genre any of the spellings of lo-fi? 00:01:20.100 --> 00:01:24.780 Let's say the variable genre contains the string lo-fi. 00:01:24.780 --> 00:01:26.460 We evaluate the expressions around 00:01:26.460 --> 00:01:29.340 the logical operators first and then apply the ors. 00:01:29.340 --> 00:01:31.140 We start with the leftmost expression. 00:01:31.140 --> 00:01:34.230 These strings are not equal, so this evaluates to false. 00:01:34.230 --> 00:01:35.730 We jump to the second expression. 00:01:35.730 --> 00:01:38.580 These strings are equal, so this evaluates to true. 00:01:38.580 --> 00:01:40.980 And then the third part, these strings are not equal, 00:01:40.980 --> 00:01:42.960 so this evaluates to false. 00:01:42.960 --> 00:01:45.660 Now that we're all simplified, we take a look at the ors. 00:01:45.660 --> 00:01:48.150 An expression with the OR operator evaluates to true 00:01:48.150 --> 00:01:50.790 if at least one of the sides is true. 00:01:50.790 --> 00:01:54.000 False or true evaluates to true and then 00:01:54.000 --> 00:01:57.060 true or false evaluates to true. 00:01:57.060 --> 00:01:58.377 Now you may be thinking, 00:01:58.377 --> 00:02:01.350 "Whoa, whoa, did I even need to evaluate that last part?" 00:02:01.350 --> 00:02:03.990 Once I knew that second expression evaluated to true, 00:02:03.990 --> 00:02:06.780 I knew that my final answer was going to be true. 00:02:06.780 --> 00:02:07.860 As it's evaluating, 00:02:07.860 --> 00:02:10.320 the computer makes the same optimization. 00:02:10.320 --> 00:02:13.890 We called this short circuit evaluation or lazy evaluation. 00:02:13.890 --> 00:02:16.080 In its laziness, the computer stops evaluating 00:02:16.080 --> 00:02:18.210 as soon as it knows the final answer. 00:02:18.210 --> 00:02:20.640 With the or operator the computer stops evaluating 00:02:20.640 --> 00:02:23.040 as soon as it finds a side that evaluates to true 00:02:23.040 --> 00:02:25.140 because no matter what's on the other side, 00:02:25.140 --> 00:02:27.540 the expression will always evaluate to true. 00:02:27.540 --> 00:02:29.400 True or true evaluates to true 00:02:29.400 --> 00:02:32.310 and true or false also evaluates to true. 00:02:32.310 --> 00:02:34.140 With the and operator we have the opposite. 00:02:34.140 --> 00:02:36.000 The computer stops as soon as it finds 00:02:36.000 --> 00:02:38.160 a side that evaluates to false. 00:02:38.160 --> 00:02:39.390 No matter what's on the other side 00:02:39.390 --> 00:02:41.280 the whole expression will evaluate to false. 00:02:41.280 --> 00:02:43.410 Because false and true evaluates to false 00:02:43.410 --> 00:02:46.740 and false and false also evaluates to false. 00:02:46.740 --> 00:02:48.840 Okay, so the computer's saving itself some work. 00:02:48.840 --> 00:02:51.750 Why do I care? Consider this Boolean expression. 00:02:51.750 --> 00:02:52.650 It looks pretty sensible, 00:02:52.650 --> 00:02:55.980 but what if the variable group size contains the value zero? 00:02:55.980 --> 00:02:57.720 The computer can't divide by zero. 00:02:57.720 --> 00:02:59.400 So this gives a runtime error. 00:02:59.400 --> 00:03:01.320 Well, we could just not do that, 00:03:01.320 --> 00:03:03.660 but we might not control the value of group size. 00:03:03.660 --> 00:03:05.610 Maybe it's set by user input. 00:03:05.610 --> 00:03:07.560 To solve this, we can check that group size 00:03:07.560 --> 00:03:09.570 doesn't equal zero first. 00:03:09.570 --> 00:03:11.820 If group size is equal to zero, the left-hand side 00:03:11.820 --> 00:03:14.430 will evaluate to false and the computer will short circuit. 00:03:14.430 --> 00:03:15.510 It'll jump to the conclusion 00:03:15.510 --> 00:03:17.460 that the whole expression must evaluate to false 00:03:17.460 --> 00:03:19.470 and won't bother evaluating the right-hand side, 00:03:19.470 --> 00:03:21.480 thus avoiding the division by zero. 00:03:21.480 --> 00:03:23.610 We can use this pattern across our programs, 00:03:23.610 --> 00:03:26.190 taking advantage of short circuit evaluation to check 00:03:26.190 --> 00:03:29.040 for preconditions that allow us to avoid possible errors. 00:03:29.880 --> 00:03:32.070 Last bit. What about the not operator? 00:03:32.070 --> 00:03:33.750 The not operator takes precedence 00:03:33.750 --> 00:03:36.000 over the and and or operators. 00:03:36.000 --> 00:03:37.680 That means this expression really asks, 00:03:37.680 --> 00:03:39.300 is the genre not equal to rock 00:03:39.300 --> 00:03:41.970 and is the BPM greater than 130? 00:03:41.970 --> 00:03:44.910 Now, we wanna be careful about overusing the not operator 00:03:44.910 --> 00:03:46.920 when we don't need to because it tends 00:03:46.920 --> 00:03:48.600 to make things more confusing. 00:03:48.600 --> 00:03:50.490 For example, this expression is just equivalent 00:03:50.490 --> 00:03:54.810 to genre not equals rock and BPM greater than 130. 00:03:54.810 --> 00:03:56.370 If instead I put parentheses here, 00:03:56.370 --> 00:03:58.680 I would be negating the whole expression. 00:03:58.680 --> 00:04:03.090 This asks, is it not both a rock song and a fast song? 00:04:03.090 --> 00:04:05.370 That's equivalent to the expression is the genre 00:04:05.370 --> 00:04:09.300 not equal to rock or is the BPM less than or equal to 130? 00:04:09.300 --> 00:04:11.460 If either of these conditions is true, 00:04:11.460 --> 00:04:13.950 then this and expression would evaluate to false, 00:04:13.950 --> 00:04:16.590 which means not it would evaluate to true. 00:04:16.590 --> 00:04:18.240 Now you're probably starting to understand 00:04:18.240 --> 00:04:21.060 why I said to use the not operator sparingly. 00:04:21.060 --> 00:04:23.460 If you do need to negate a compound Boolean expression, 00:04:23.460 --> 00:04:24.870 it's often easier to understand 00:04:24.870 --> 00:04:27.000 if you break it down into multiple parts. 00:04:27.000 --> 00:04:28.200 Otherwise, the not operator 00:04:28.200 --> 00:04:30.480 tends to make your program a bit less readable. 00:04:30.480 --> 00:04:33.510 Just like if I said something like "I prefer not blue colors 00:04:33.510 --> 00:04:35.937 or I'm going to not not in this video now."