WEBVTT X-TIMESTAMP-MAP=LOCAL:00:00:00.000,MPEGTS:900000 00:00:00.000 --> 00:00:03.395 [MUSIC PLAYING] 00:00:05.340 --> 00:00:07.620 SPEAKER: Well, hello, one and all, and welcome to our 00:00:07.620 --> 00:00:10.030 short on Boolean expressions. 00:00:10.030 --> 00:00:12.450 Now, in an earlier short on conditionals, 00:00:12.450 --> 00:00:16.170 we wrote some game, really, some program to recommend to the user 00:00:16.170 --> 00:00:19.380 some card games depending on their level of preferred difficulty 00:00:19.380 --> 00:00:22.230 and the number of preferred players, in this case. 00:00:22.230 --> 00:00:26.200 So let's think of ways to improve the design of this program. 00:00:26.200 --> 00:00:29.190 And we left off-- we noted that there's a lot of repetition 00:00:29.190 --> 00:00:30.540 here in terms of code. 00:00:30.540 --> 00:00:37.350 In particular, if we look at lines 6 through 11 and lines 13 through 18, 00:00:37.350 --> 00:00:40.530 we'll notice these are pretty much the same or at least 00:00:40.530 --> 00:00:42.880 asking the same kinds of questions. 00:00:42.880 --> 00:00:46.410 Here, we have the same conditional, the same conditional, the same conditional, 00:00:46.410 --> 00:00:47.290 the same conditional. 00:00:47.290 --> 00:00:50.920 We could probably do a bit better than this. 00:00:50.920 --> 00:00:53.770 So in what ways could we do better? 00:00:53.770 --> 00:00:55.800 Well, let's think through how we could perhaps 00:00:55.800 --> 00:00:59.640 check to see from the very beginning if the user gave us 00:00:59.640 --> 00:01:02.084 the right input we're looking for. 00:01:02.084 --> 00:01:04.959 Remember, we want to make sure the user entered in either "Difficult" 00:01:04.959 --> 00:01:09.460 or "Casual" and either "Multiplayer" or "Single-player," not some other choice, 00:01:09.460 --> 00:01:10.660 in this case. 00:01:10.660 --> 00:01:11.960 So how could we do that? 00:01:11.960 --> 00:01:14.710 We could actually make use of these conditionals again. 00:01:14.710 --> 00:01:19.210 If I go down below, where I get the user's input here, and ask a question, 00:01:19.210 --> 00:01:23.140 I could probably ask a question of, what is the value of difficulty? 00:01:23.140 --> 00:01:27.770 And is it either "Difficult" or "Casual," or is it not? 00:01:27.770 --> 00:01:33.400 So I'll go ahead and ask, if, let's say, difficulty == "Difficult," 00:01:33.400 --> 00:01:34.670 just like this. 00:01:34.670 --> 00:01:37.840 And if this was all I knew about Boolean expressions, 00:01:37.840 --> 00:01:40.160 I'd have to leave it as this. 00:01:40.160 --> 00:01:42.550 But thankfully, I actually don't need to do 00:01:42.550 --> 00:01:45.730 that if I know more about these things called Boolean expressions, 00:01:45.730 --> 00:01:48.850 these expressions here that come after our conditionals. 00:01:48.850 --> 00:01:52.290 Now, it turns out that Boolean expressions are simply these questions 00:01:52.290 --> 00:01:54.260 that have yes or no values. 00:01:54.260 --> 00:01:59.770 And we see here one example of a Boolean expression-- difficulty equals equals, 00:01:59.770 --> 00:02:03.140 meaning is equal to, capital D, "Difficult." 00:02:03.140 --> 00:02:07.510 That is a question that has a yes or no, true or false response. 00:02:07.510 --> 00:02:11.710 But I can actually do more than just ask or compare two values 00:02:11.710 --> 00:02:12.920 in a Boolean expression. 00:02:12.920 --> 00:02:15.220 I can actually combine Boolean expressions 00:02:15.220 --> 00:02:19.430 into one longer one using Boolean operators. 00:02:19.430 --> 00:02:22.610 So in Python, we have access to three of them. 00:02:22.610 --> 00:02:26.680 And we'll show one here now, one called OR. 00:02:26.680 --> 00:02:34.360 So it seems to me I care if difficulty is either "Difficult" or "Casual." 00:02:34.360 --> 00:02:37.930 So I could ask this all in one breath, one question, if you will, 00:02:37.930 --> 00:02:40.340 using OR as well. 00:02:40.340 --> 00:02:43.190 And I'll type in some other logical expression here-- 00:02:43.190 --> 00:02:47.630 difficulty equals equals, is equal to, in this case, "Casual." 00:02:47.630 --> 00:02:52.460 And now I have one longer logical expression here. 00:02:52.460 --> 00:02:57.530 Difficulty is equal to "Difficult," or difficulty is equal to "Casual." 00:02:57.530 --> 00:03:00.580 And now if either one of these two expressions is true, 00:03:00.580 --> 00:03:04.480 the entire expression will be true as well. 00:03:04.480 --> 00:03:08.030 But it seems to me that this actually isn't quite what I want. 00:03:08.030 --> 00:03:12.880 I want to check if the user actually did not enter "Difficult" or "Casual." 00:03:12.880 --> 00:03:18.180 So thankfully, I can make use of another Boolean operator, one called NOT. 00:03:18.180 --> 00:03:22.790 And NOT can negate the value of a logical expression. 00:03:22.790 --> 00:03:26.240 If it is true, it will negate that true to a false. 00:03:26.240 --> 00:03:30.320 If it is false, it will negate that false to a true value. 00:03:30.320 --> 00:03:33.600 Or in other words, same equivalent between yes and no values too. 00:03:33.600 --> 00:03:38.830 So if I were to think about this as one long logical expression, 00:03:38.830 --> 00:03:41.090 I could encase it in these parentheses. 00:03:41.090 --> 00:03:43.840 This means this is a separate logical expression that 00:03:43.840 --> 00:03:46.180 should be evaluated first. 00:03:46.180 --> 00:03:51.850 Then I can actually prepend this logical operator NOT 00:03:51.850 --> 00:03:56.630 to take the result of this logical expression here and negate it. 00:03:56.630 --> 00:04:01.850 And remember, in Python, these logical expressions return true or false values. 00:04:01.850 --> 00:04:05.770 So if it is true that the user has entered in both-- 00:04:05.770 --> 00:04:09.190 if it is true that user entered in either "Difficult" or "Casual," 00:04:09.190 --> 00:04:11.180 our expression here will be false. 00:04:11.180 --> 00:04:15.760 We'll not do whatever is indented in this particular branch of our code. 00:04:15.760 --> 00:04:20.019 If, though, the opposite is true, the user has not entered in either 00:04:20.019 --> 00:04:24.520 "Difficult" or "Casual," we will run whatever code is inside of this 00:04:24.520 --> 00:04:26.080 particular branch. 00:04:26.080 --> 00:04:27.980 So what code should we run? 00:04:27.980 --> 00:04:30.670 Well, we saw below, we wanted to just prompt the user 00:04:30.670 --> 00:04:33.740 and say, you just need to enter a valid difficulty. 00:04:33.740 --> 00:04:38.900 So I will copy and paste this print here and put it up top instead. 00:04:38.900 --> 00:04:40.870 And I think now we could actually get rid 00:04:40.870 --> 00:04:43.460 of this else in our conditional structure. 00:04:43.460 --> 00:04:47.740 So we're simplifying things a little bit down below as well. 00:04:47.740 --> 00:04:49.760 Well, what else should we do? 00:04:49.760 --> 00:04:53.815 Ideally, our program shouldn't keep running after we tell it to-- 00:04:53.815 --> 00:04:55.940 after we tell the user to enter a valid difficulty. 00:04:55.940 --> 00:04:58.990 So we could type, in this case, return, saying 00:04:58.990 --> 00:05:03.430 this is the end of our program in this particular case. 00:05:03.430 --> 00:05:06.150 Now, I can a similar thing for the number of players. 00:05:06.150 --> 00:05:09.470 Why don't I actually just copy and paste this for now, 00:05:09.470 --> 00:05:10.970 because it's the same structure. 00:05:10.970 --> 00:05:15.240 And let me try to modify it so it actually fits this new use case here. 00:05:15.240 --> 00:05:21.390 Well, in this case, I care if a player entered the right number of players. 00:05:21.390 --> 00:05:25.190 So instead of comparing difficulty, I'll compare players in this case. 00:05:25.190 --> 00:05:32.780 And I'll ask the question, is players either "Multiplayer" or "Single-player," 00:05:32.780 --> 00:05:34.050 just like this? 00:05:34.050 --> 00:05:38.360 And so now, if the user has not done that, I'll go ahead and say, 00:05:38.360 --> 00:05:41.260 "Enter a valid number of players." 00:05:41.260 --> 00:05:46.930 Notice the same thing we said down below on lines 18 and 25. 00:05:46.930 --> 00:05:48.660 So now we can really simplify things. 00:05:48.660 --> 00:05:54.470 If I get rid of this line, 24 and 25, and even lines 17 and 18, 00:05:54.470 --> 00:05:58.110 I think we're in a better spot for these conditionals down below. 00:05:58.110 --> 00:06:01.520 And moreover, we can actually alert the user immediately 00:06:01.520 --> 00:06:05.820 when they haven't typed in the right value to our program. 00:06:05.820 --> 00:06:07.000 So what have we done? 00:06:07.000 --> 00:06:11.618 We've now seen here how we can use these logical expressions-- and actually, 00:06:11.618 --> 00:06:13.410 Boolean expressions and Boolean operators-- 00:06:13.410 --> 00:06:19.200 to combine these together and ask more complex questions about user input. 00:06:19.200 --> 00:06:22.830 We could probably still do a little bit better down below here. 00:06:22.830 --> 00:06:28.810 One other way to write this would be to specify some more complex questions. 00:06:28.810 --> 00:06:31.070 Notice how there's some repetition here. 00:06:31.070 --> 00:06:35.040 I'm having the same conditional structure inside of these two branches. 00:06:35.040 --> 00:06:38.160 We could make this, I would argue, a little bit better 00:06:38.160 --> 00:06:41.370 designed or at least a little more readable, in this sense. 00:06:41.370 --> 00:06:44.350 So what if we did this instead? 00:06:44.350 --> 00:06:50.020 What if we tried trying to combine these questions into one? 00:06:50.020 --> 00:06:55.440 Well, here, notice how I'm recommending poker if difficulty is "Difficult" 00:06:55.440 --> 00:06:58.230 and players is "Multiplayer." 00:06:58.230 --> 00:07:01.900 Well, I could represent that same question I just asked in English-- 00:07:01.900 --> 00:07:05.550 is difficulty equal to "Difficult" and players equal to "Multiplayer"-- 00:07:05.550 --> 00:07:10.650 in a single logical expression using another Boolean operator, 00:07:10.650 --> 00:07:12.510 one called AND. 00:07:12.510 --> 00:07:15.450 So I'll go ahead and say, if difficulty == "Difficult" 00:07:15.450 --> 00:07:22.060 and players == "Multiplayer," in this case, in that case, 00:07:22.060 --> 00:07:24.990 we would recommend poker. 00:07:24.990 --> 00:07:30.000 And I think we could really rewrite the entirety of these conditionals now using 00:07:30.000 --> 00:07:34.720 these more complex Boolean expressions and Boolean operators here. 00:07:34.720 --> 00:07:39.660 So in the case that difficulty is not "Difficult" 00:07:39.660 --> 00:07:42.480 and players is not "Multiplayer," well, ask another question. 00:07:42.480 --> 00:07:47.820 We could ask if difficulty is equal to "Difficult" and, let's say, 00:07:47.820 --> 00:07:51.690 players is equal to "Single-player," just like this. 00:07:51.690 --> 00:07:53.850 Well, what I recommend in that case? 00:07:53.850 --> 00:07:57.420 We should recommend, as we saw before, in this case, Klondike, 00:07:57.420 --> 00:07:59.850 a more difficult single-player game. 00:07:59.850 --> 00:08:03.700 In the case that that's not what the user entered, we asked another question, 00:08:03.700 --> 00:08:05.010 we could say elif. 00:08:05.010 --> 00:08:08.280 Maybe difficulty in this case is "Casual." 00:08:08.280 --> 00:08:11.490 And players is equal to-- 00:08:11.490 --> 00:08:13.810 let's do "Multiplayer," in this case. 00:08:13.810 --> 00:08:20.190 In that case, we would recommend a game like hearts instead. 00:08:20.190 --> 00:08:24.450 Now, here, at the very fourth condition, I 00:08:24.450 --> 00:08:30.450 argue we can use an else because we only gave the player four possible options-- 00:08:30.450 --> 00:08:33.600 "Difficult" or "Casual," "Multiplayer" or "Single-player"-- 00:08:33.600 --> 00:08:37.110 which can just recommend really four different games. 00:08:37.110 --> 00:08:41.400 It's better to think about it as, really, two inputs-- 00:08:41.400 --> 00:08:45.480 difficulty and players-- each of which have two possible options. 00:08:45.480 --> 00:08:49.570 Multiplied together gives us four possible outcomes, in this case. 00:08:49.570 --> 00:08:51.730 So how could we think about this? 00:08:51.730 --> 00:08:55.800 Well, if it's not these three combinations, there's only one 00:08:55.800 --> 00:08:56.950 more to recommend. 00:08:56.950 --> 00:09:01.530 So I will recommend, in this case, the last game, one called clock 00:09:01.530 --> 00:09:05.790 for casual, single-player card games. 00:09:05.790 --> 00:09:08.340 So we've now used these Boolean expressions. 00:09:08.340 --> 00:09:12.750 And we've now used these Boolean operators to make more complex questions 00:09:12.750 --> 00:09:14.920 and simplify bits of our code. 00:09:14.920 --> 00:09:17.930 Let's go ahead and test this out and see if it works. 00:09:17.930 --> 00:09:19.140 I'll open up my terminal. 00:09:19.140 --> 00:09:23.350 And I will run python of recommendations.py. 00:09:23.350 --> 00:09:28.810 So let's first test this branch of our code here, lines 3 through 5. 00:09:28.810 --> 00:09:32.550 If I enter in something other than "Difficult" or "Casual," 00:09:32.550 --> 00:09:35.590 will I see "Enter a valid difficulty"? 00:09:35.590 --> 00:09:39.900 Well, I'll type in maybe "Medium" as a difficulty, not a possible option here. 00:09:39.900 --> 00:09:40.860 I'll hit Enter. 00:09:40.860 --> 00:09:43.860 And I'll see "Enter a valid difficulty." 00:09:43.860 --> 00:09:45.010 OK, pretty good. 00:09:45.010 --> 00:09:47.500 Let's test now this branch here. 00:09:47.500 --> 00:09:52.690 If I enter in a correct difficulty but an incorrect number of players, 00:09:52.690 --> 00:09:56.290 hopefully, I'll see "Enter a valid number of players." 00:09:56.290 --> 00:09:59.080 I'll go ahead and run python recommendations.py. 00:09:59.080 --> 00:10:02.370 I'll choose maybe "difficult." 00:10:02.370 --> 00:10:06.720 And I'll type in maybe "Two-player," which, again, is not an option. 00:10:06.720 --> 00:10:07.830 I'll hit Enter here. 00:10:07.830 --> 00:10:11.550 And now I'll see "Enter a valid number of players," 00:10:11.550 --> 00:10:13.860 just as we planned from the beginning. 00:10:13.860 --> 00:10:15.090 More to test though. 00:10:15.090 --> 00:10:18.740 If I scroll down, let's try to test these various branches here. 00:10:18.740 --> 00:10:26.910 Ideally, if I type in both "Difficult" and "Multiplayer," I should see poker, 00:10:26.910 --> 00:10:28.060 and I do. 00:10:28.060 --> 00:10:33.090 If I now type in something like "Difficult" and "Single-player," 00:10:33.090 --> 00:10:35.830 I should see something like Klondike. 00:10:35.830 --> 00:10:41.880 If I type in something like "Casual" and "Multiplayer," I should see hearts. 00:10:41.880 --> 00:10:48.450 And finally, if I type in "Casual" or "Single-player"-- or "Casual" 00:10:48.450 --> 00:10:53.040 and "Single-player," I should now see clock at the very end. 00:10:53.040 --> 00:10:57.390 So we've rewritten now the very same logic in a different way, 00:10:57.390 --> 00:11:02.100 thanks to these more complex Boolean expressions and Boolean operators. 00:11:02.100 --> 00:11:05.050 Certainly, perhaps, more ways to write this code, other ways 00:11:05.050 --> 00:11:06.440 to incorporate the same logic. 00:11:06.440 --> 00:11:09.700 But this now highlights the ways we can actually combine various questions 00:11:09.700 --> 00:11:12.380 into more complex ones as well. 00:11:12.380 --> 00:11:13.910 That's it for this short. 00:11:13.910 --> 00:11:16.620 We'll see you next time.