[MUSIC PLAYING] SPEAKER: Well, hello, one and all, and welcome to our short on Boolean expressions. Now, in an earlier short on conditionals, we wrote some game, really, some program to recommend to the user some card games depending on their level of preferred difficulty and the number of preferred players, in this case. So let's think of ways to improve the design of this program. And we left off-- we noted that there's a lot of repetition here in terms of code. In particular, if we look at lines 6 through 11 and lines 13 through 18, we'll notice these are pretty much the same or at least asking the same kinds of questions. Here, we have the same conditional, the same conditional, the same conditional, the same conditional. We could probably do a bit better than this. So in what ways could we do better? Well, let's think through how we could perhaps check to see from the very beginning if the user gave us the right input we're looking for. Remember, we want to make sure the user entered in either "Difficult" or "Casual" and either "Multiplayer" or "Single-player," not some other choice, in this case. So how could we do that? We could actually make use of these conditionals again. If I go down below, where I get the user's input here, and ask a question, I could probably ask a question of, what is the value of difficulty? And is it either "Difficult" or "Casual," or is it not? So I'll go ahead and ask, if, let's say, difficulty == "Difficult," just like this. And if this was all I knew about Boolean expressions, I'd have to leave it as this. But thankfully, I actually don't need to do that if I know more about these things called Boolean expressions, these expressions here that come after our conditionals. Now, it turns out that Boolean expressions are simply these questions that have yes or no values. And we see here one example of a Boolean expression-- difficulty equals equals, meaning is equal to, capital D, "Difficult." That is a question that has a yes or no, true or false response. But I can actually do more than just ask or compare two values in a Boolean expression. I can actually combine Boolean expressions into one longer one using Boolean operators. So in Python, we have access to three of them. And we'll show one here now, one called OR. So it seems to me I care if difficulty is either "Difficult" or "Casual." So I could ask this all in one breath, one question, if you will, using OR as well. And I'll type in some other logical expression here-- difficulty equals equals, is equal to, in this case, "Casual." And now I have one longer logical expression here. Difficulty is equal to "Difficult," or difficulty is equal to "Casual." And now if either one of these two expressions is true, the entire expression will be true as well. But it seems to me that this actually isn't quite what I want. I want to check if the user actually did not enter "Difficult" or "Casual." So thankfully, I can make use of another Boolean operator, one called NOT. And NOT can negate the value of a logical expression. If it is true, it will negate that true to a false. If it is false, it will negate that false to a true value. Or in other words, same equivalent between yes and no values too. So if I were to think about this as one long logical expression, I could encase it in these parentheses. This means this is a separate logical expression that should be evaluated first. Then I can actually prepend this logical operator NOT to take the result of this logical expression here and negate it. And remember, in Python, these logical expressions return true or false values. So if it is true that the user has entered in both-- if it is true that user entered in either "Difficult" or "Casual," our expression here will be false. We'll not do whatever is indented in this particular branch of our code. If, though, the opposite is true, the user has not entered in either "Difficult" or "Casual," we will run whatever code is inside of this particular branch. So what code should we run? Well, we saw below, we wanted to just prompt the user and say, you just need to enter a valid difficulty. So I will copy and paste this print here and put it up top instead. And I think now we could actually get rid of this else in our conditional structure. So we're simplifying things a little bit down below as well. Well, what else should we do? Ideally, our program shouldn't keep running after we tell it to-- after we tell the user to enter a valid difficulty. So we could type, in this case, return, saying this is the end of our program in this particular case. Now, I can a similar thing for the number of players. Why don't I actually just copy and paste this for now, because it's the same structure. And let me try to modify it so it actually fits this new use case here. Well, in this case, I care if a player entered the right number of players. So instead of comparing difficulty, I'll compare players in this case. And I'll ask the question, is players either "Multiplayer" or "Single-player," just like this? And so now, if the user has not done that, I'll go ahead and say, "Enter a valid number of players." Notice the same thing we said down below on lines 18 and 25. So now we can really simplify things. If I get rid of this line, 24 and 25, and even lines 17 and 18, I think we're in a better spot for these conditionals down below. And moreover, we can actually alert the user immediately when they haven't typed in the right value to our program. So what have we done? We've now seen here how we can use these logical expressions-- and actually, Boolean expressions and Boolean operators-- to combine these together and ask more complex questions about user input. We could probably still do a little bit better down below here. One other way to write this would be to specify some more complex questions. Notice how there's some repetition here. I'm having the same conditional structure inside of these two branches. We could make this, I would argue, a little bit better designed or at least a little more readable, in this sense. So what if we did this instead? What if we tried trying to combine these questions into one? Well, here, notice how I'm recommending poker if difficulty is "Difficult" and players is "Multiplayer." Well, I could represent that same question I just asked in English-- is difficulty equal to "Difficult" and players equal to "Multiplayer"-- in a single logical expression using another Boolean operator, one called AND. So I'll go ahead and say, if difficulty == "Difficult" and players == "Multiplayer," in this case, in that case, we would recommend poker. And I think we could really rewrite the entirety of these conditionals now using these more complex Boolean expressions and Boolean operators here. So in the case that difficulty is not "Difficult" and players is not "Multiplayer," well, ask another question. We could ask if difficulty is equal to "Difficult" and, let's say, players is equal to "Single-player," just like this. Well, what I recommend in that case? We should recommend, as we saw before, in this case, Klondike, a more difficult single-player game. In the case that that's not what the user entered, we asked another question, we could say elif. Maybe difficulty in this case is "Casual." And players is equal to-- let's do "Multiplayer," in this case. In that case, we would recommend a game like hearts instead. Now, here, at the very fourth condition, I argue we can use an else because we only gave the player four possible options-- "Difficult" or "Casual," "Multiplayer" or "Single-player"-- which can just recommend really four different games. It's better to think about it as, really, two inputs-- difficulty and players-- each of which have two possible options. Multiplied together gives us four possible outcomes, in this case. So how could we think about this? Well, if it's not these three combinations, there's only one more to recommend. So I will recommend, in this case, the last game, one called clock for casual, single-player card games. So we've now used these Boolean expressions. And we've now used these Boolean operators to make more complex questions and simplify bits of our code. Let's go ahead and test this out and see if it works. I'll open up my terminal. And I will run python of recommendations.py. So let's first test this branch of our code here, lines 3 through 5. If I enter in something other than "Difficult" or "Casual," will I see "Enter a valid difficulty"? Well, I'll type in maybe "Medium" as a difficulty, not a possible option here. I'll hit Enter. And I'll see "Enter a valid difficulty." OK, pretty good. Let's test now this branch here. If I enter in a correct difficulty but an incorrect number of players, hopefully, I'll see "Enter a valid number of players." I'll go ahead and run python recommendations.py. I'll choose maybe "difficult." And I'll type in maybe "Two-player," which, again, is not an option. I'll hit Enter here. And now I'll see "Enter a valid number of players," just as we planned from the beginning. More to test though. If I scroll down, let's try to test these various branches here. Ideally, if I type in both "Difficult" and "Multiplayer," I should see poker, and I do. If I now type in something like "Difficult" and "Single-player," I should see something like Klondike. If I type in something like "Casual" and "Multiplayer," I should see hearts. And finally, if I type in "Casual" or "Single-player"-- or "Casual" and "Single-player," I should now see clock at the very end. So we've rewritten now the very same logic in a different way, thanks to these more complex Boolean expressions and Boolean operators. Certainly, perhaps, more ways to write this code, other ways to incorporate the same logic. But this now highlights the ways we can actually combine various questions into more complex ones as well. That's it for this short. We'll see you next time.