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