Creating Nested if Statements
00:00 Now that you can create some branches, it’s time to create some nested branches. To examine nested branches in a bit more detail, seeing as it doesn’t look at any new concepts, you’re going to look at an example. The example is called Evaluate the Winner.
00:15 The situation is that two people are either playing basketball or golf. The input to your program is what they tell you, and they tell you what sport they’ve been playing and their score.
00:27 The job of your program is to evaluate who won. The catch here is that in golf, the lower score wins, but in basketball, the higher score wins. So you can’t just take the score and say whoever got the highest score won.
00:43 You have to check whether they were playing golf or basketball. Go over to IDLE and start up a new file. To get started on your Evalute the Winner program, you’re going to simulate some inputs here.
You can start that by defining some variables. Say you start with
p1_score for player 1. Let’s put that at
p2_score, let’s put that at
9. Since it’s
"Golf", and lower scores win in golf, player 2 would be the winner in this case.
01:20 If this was basketball, since higher scores win in basketball, player 1 would be the winner. Now you’re using these variables to simulate inputs by a user.
01:30 Although you won’t be actually taking user input with this program, maybe later you’ll develop it into something that takes user input. You need to determine who won, but there’s two components to that. You need to determine their score, but the way you interpret the scores depend on the sport that’s being played. So the first thing you should determine is what sport is being played.
So how might you do that in Python? That’s right, with an
So you can check
if sport == "golf":
and you can just echo that with the
print() function. Now you can extend that with
elif sport == "basketball",
and again, you can just echo
"basketball" for now. You’ll work on the logic to determine whether they won or not later on. And finally, you can have a fallback because someone might put in a sport that’s not supported by your program.
So you can say
02:38 There’s a bug in this program right now, as it stands. Can you spot what it is? Basically the input here, you can imagine someone putting in a capital letter to start off with, but you’re checking against a lowercase letter.
So if you save this and run it, you’ll see that it says
Unknown sport! And that’s because of this capitalization of the
"G". So a common pattern to use when taking user input is to cast everything to lowercase, with the
.lower() method on the string.
So now you can go crazy with capitalization, and your program is going to be resilient to that and be able to recognize that that’s
"basketball", you can change a few capital letters in here,
and that’s still going to recognize as
Now that you are able to identify the sport, you’ll need to be able to identify who won. So start off with golf and work on basketball later. What you can do is nest a whole new
if block within this indented block.
if sport == "golf" within that indented block, start another
if, and you can say
if p1_score == p2_score: that’s a draw. So you can print
"It's a draw!" Then you can extend that.
elif p1_score—if it’s golf, the
p1_score should be lower than the
p2_score, and then you can print
"Player 1 wins!"
And finally, you can have a fallback where you print
"Player 2 wins!",
because if it’s not a draw and player 1 hasn’t won, then player 2 must have won. You can add another
elif not have an
else block here, but you want to practice with all the keywords, so you’re going to do ut this way.
How would you extend that for basketball? Well, you can actually just copy-paste pretty much everything in here, and all you need to change is the comparator. So now,
if p1_score > p2_score, then player 1 wins.
05:16 In the other case, player 2 wins. You can test this a little bit. The sport is basketball currently, and player 1 has the higher score, so you expect player 1 to win, and player 1 does win.
So now let’s change this to
"golf", and player 2 wins. Great. How about now we change player 1 to a score of
Player 1 wins! So this looks like it’s working perfectly.
05:54 Okay. It’s time to refactor. Refactoring your code means to rework it in a way that makes it simpler and easier to understand, or just better in general.
06:04 There are a few things that you could do with the code you have so far. Can you spot what it is that you could do to make this a bit simpler and easier to read? When trying to refactor code like this, it’s useful to look for similarities between different indented blocks and see if there’s something in common that you can bring up a level.
06:25 Can you see any similarities between these two? The most obvious one is the first conditional check of both. So if the players’ scores are equal to each other, it’s a draw.
06:37 Now that doesn’t matter whether it’s basketball or golf. It’s the same in both sports. So that’s something you can bring out into the outer level as it were.
So you can say—actually, you can just copy this, link up the whole
if structure—because if you just left this as an
if, then it would do the two checks separately. Delete the first check from both of the inner
if blocks always have to start with an
if. They can’t start with an
So now you have a bit of a larger
if block, but the inner, nested
if blocks are simpler.
So this quite a bit more readable than the last version, but it has an interesting side effect. Now, if the scores are equal, you’ll see that it says
It's a draw! It still works.
But you don’t actually need to put a sport anymore. It will still work and say
It's a draw! It won’t say
Unknown sport! Can you see why this is? Since the
if block goes in order and will first check whether the scores are equal before checking whether the sport is basketball or golf, it has a path to print something and exit the
if block, without even checking the sport. If you wanted to change this behavior, then this refactoring might not be a good idea, but in general, if your program can support more cases, because there aren’t, as far as we know, any sports where an equal score is not a draw, so now your program will support hockey, for instance, although this is more of a side effect, an unintentional side effect.
08:23 If you wanted to do something more explicitly like this, this probably wouldn’t be the best implementation. In any case, refactoring is always full of these trade-offs and musings about what is the best way to write code, but in general, if you can flatten something and make it easier to read and follow, then generally that’s a goood idea.
08:43 And by flatten, I mean take this out from being nested. The Zen of Python says flat is better than nested. And although the nesting level hasn’t changed here—you still have one level of nesting here—the content that is nested is less than before, and you also have less conditions. In the code, you’re only having to check whether it’s a draw once.
09:08 Now with something about refactoring, is that it never seems to be done. You can always do more. You can always make your program work in a slightly different way, and there are always trade-offs.
09:16 There are always things that are good about one way and worse about another way, but by playing with the code, changing it up, seeing how else it might run, what other names you can give the variables, you can really discover and get much better at Python. So give it another shot and see if you can refactor it again.
And that’s it. In this lesson, you looked at an example of evaluating the winner in sports. This gave you the opportunity to build a nested
Become a Member to join the conversation.