3.2 Conditionals

1. What Are Conditionals?

The term “conditional” comes from the idea that sometimes we want to run some code conditionally; in other words, we only want to run it if something is true. For example, if the user has modified a document since the last saved, then we want to ask them if they want to save before closing the program. If a user has entered a different password than the one saved, then we want to ask if they want to update the saved password. If a user’s bank balance is insufficient to cover a purchase or the retailer is not trusted, then we want to reject the purchase.

Modern programming couldn’t exist without conditionals like these. They’re a relatively simple principle (but don’t worry if you don’t get them at first), but they’re extremely powerful.

If-Then

The most fundamental form of conditional is the simple if-then statement. If something is true, then do something. We think in terms of conditionals every day. Consider:

  • If it’s cold outside, then wear a long-sleeved shirt.
  • If highway traffic is bad, then take surface streets.
  • If you have a test tomorrow, then study.
  • If you’re a vegetarian, then order the vegetarian entrée.

Each of these is easily phrased in terms of an if-then statement. You check if some condition is true, and if so, you take some action. The “action” could actually be several actions. You could imagine, for example, that if it’s cold outside, then you wear warmer clothing, start the car early so it can warm up, and makeg some hot coffee.

If-Then-Else

A slightly more complicated version of this includes a third part: an else. The else is a different series of actions to perform if the condition wasn’t true in the first place. With an if-then-else structure, you’ll always do one thing or the other.

We can rewrite our real-world examples above in terms of if-then-else:

  • If it’s cold outside, then wear a long-sleeved shirt; else, wear a t-shirt.
  • If highway traffic is bad, then take surface streets; else, take the highway.
  • If you have a test tomorrow, then study; else, go to a party.
  • If you’re a vegetarian, then order the vegetarian entrée; else, order the meat entrée.

Just like the original then, there could be multiple actions that follow an else. The else following the conditional on whether it’s cold outside could be: wear a t-shirt, make some iced coffee, plan to go to the park after school or work, and pack a water bottle. The important thing here is that if-else structures create two alternatives, one of which will always be chosen.

If-Then-Else-If

Sometimes, though, our reasoning might be more complex. We might need multiple pathways depending on different checks. In this case, we might employ an else-if statement. Like an else, an else-if only runs if the original if-then did not. Unlike an else, however, an else-if has its own conditions to check; if the conditions aren’t met, it doesn’t run either.

Consider this more complex version of our weather example: If it’s raining, then wear a raincoat; else, if it’s cold, then wear a long-sleeved shirt; else, wear a t-shirt. Here, we check two things: whether it’s raining, and whether it’s cold. If it’s raining, we don’t need to bother checking if it’s cold: we wear a raincoat regardless. Otherwise, or else, we need to check if it’s cold, and if so, wear a long-sleeved shirt. That’s what makes this an else-if: it only runs if the original if wasn’t true, but it still has its own conditions.

Multiple Else-Ifs

We can chain together multiple else-ifs as well. For example, we could say: if it’s raining, then wear a raincoat; else, if it’s cold, then wear a long-sleeved shirt; else, if it’s hot, then wear a t-shirt; else, if it’s windy, then wear a jacket; else, wear a collared shirt. We must start with if, and we can have at most one else, but we can have any number of else-ifs in between. With this kind of structure, each else-if and else will only execute if no previous condition has executed. If it was cold, then this logic wouldn’t check if it was hot or windy. A collared shirt would only be the result if every previous statement was false.

This might be easier to visualize using a flowchart. From here, we can see that once one of the conditions is true, it changes our path and sends us to one of the results. So, we don’t even check the other questions because we’ve already reached our decision of what to do next. Flowcharts like this can be useful ways of planning out your code if you’re having trouble keeping track of it in text.

Figure 3.2.1

Figure 3.2.1

If we wanted to guarantee we check multiple things, we would just put multiple if-then structures one after the other. For example, imagine we said: if it’s cold, then wear a long-sleeved shirt; if it’s raining, then wear a raincoat. With this logic, we could end up wearing both a long-sleeved shirt and a raincoat if it’s cold and raining; the second statement doesn’t begin with else, so this reasoning checks if it’s raining whether it’s cold or not.

Just as we didn’t have to end an if-then statement with an else, we also don’t have to end an if-then-else-if with an else. For example, consider this reasoning: If you have a test tomorrow, then study; else, if you have class early, then go to bed early. If neither of these conditions is true, then this block doesn’t need to prescribe what you do. We can have an if-then-else-if without having a final else.

Question

How many else-ifs can we chain together in a single if-then-else-if statement?

Answer the question

Answer the question above the continue reading. iTELL evaluation is based on AI and may not always be accurate.

Conditionals Recap

So, to recap: our basic conditional structure is the if-then structure; it checks if some condition is true, and runs some code if so. We can augment our if-then structure with else-if and else. else-if checks additional conditions if the earlier ones were false. else always performs some actions if no previous if or else-if was true.

Right now, I would predict you feel like you kind-of get this and kind-of don’t. If you’re unsure, don’t worry. We’ve covered a lot in this lesson, but the remainder of this chapter is applying just these concepts to different contexts and combining it with what we learned last unit. If you find yourself stuck, try to think about the principles in terms of those real-world decisions instead of coding conditionals.

Question

What is the purpose of using else-if in a conditional structure?

Answer the question

Answer the question above the continue reading. iTELL evaluation is based on AI and may not always be accurate.

2. Conditionals in Python

Now that we’ve covered the basic principles of conditional statements, let’s see them in action. To demonstrate these, let’s use the same running example. Imagine we’re writing some code that will make a recommendation for what someone will wear. Part of this reasoning will be receiving today’s weather as a string, stored in todaysWeather. Our code will print what the user should wear.

If-Then

Let’s start with the simple example: if it’s raining, then the user should wear a raincoat and rainboots. This reasoning is shown in Figure 3.2.2.

Figure 3.2.2

In line 3, we’re creating the variable to store todaysWeather; if we were actually developing a program to do this, we would probably load this value from the Internet, but for testing we would give it a value manually to test the rest of our code. Then on line 6, we use the relational equality operator, ==, to check if todaysWeather is equal to “raining.” Here, it is, so “raincoat” and “rainboots” are printed from lines 8 and 10. What if todaysWeather didn’t equal “raining?”

Figure 3.2.3

In Figure 3.2.3, todaysWeather isn’t “raining,” so the conditional on line 6 is false, and so “raincoat” and “rainboots” don’t get printed. Note the syntax in the code on line 6: we start with the word if, followed by a space. You might sometimes see it followed by an open parenthesis instead; either is fine. Sometimes parentheses will be used if the logical expression is more complex to make it easier to read, but for simple ones like this, parentheses aren’t necessary. Either way, we then put in the condition we’re checking. You’ll notice we’re using the equality (==) operator we introduced last unit; conditional statements are a big reason why logical operators were so important. Finally, we end the line with a colon: a colon is Python’s sign that an indented code block is beginning.

The following line is indented, meaning that it is “under” or “controlled by” the conditional statement on line 6. The indented code is the “then” code; it’s the code that runs if the conditional is true. Anything indented directly under that conditional statement will be controlled by that statement. Here, that’s why line 10 is still controlled by the conditional statement; it’s also indented under it. This is also why line 12 is not controlled by the conditional; it is not indented. So, even when the conditional on line 6 is false, line 12 still runs because it is not indented under line 6.

So, this is our fundamental if statement: the word if, some logical statement that resolves to True or False, a colon, and some indented code. Next, let’s make it more complex.

If-Then-Else

Right now, the code just checks if it’s raining, and recommends a raincoat and rainboots if so. Let’s say that if it’s not raining, we want to recommend a t-shirt and shorts. How do we do that?

We add an else block, and under the else block, we place the lines of code to print “t-shirt” and “shorts.” In Figure 3.2.4, todaysWeather does not equal “raining,” and so the conditional on line 6 is False, and the code it controls does not run. The else code runs if the corresponding conditional statement was False, so here, the else code block (lines 12 and 13) runs and prints “t-shirt” and “shorts.”

Figure 3.2.4

Notice the syntax in line 11, it’s important to get this right: the keyword else must be at the same level of indentation as the original if; this is what tells Python which else corresponds to which if (which will matter later in this chapter). Logically, this makes sense: the else block code runs if the if block code did not run; if else was part of the if block code (that is, indented under it), it wouldn’t run either! As before, else must also be followed by a colon, Python’s sign that an indented code block is beginning.

What happens if the first if statement was true? Then the code under the if statement runs, as shown in Figure 3.2.5. The else code block only runs if the if code block did not run, and so here, the else code does not run. The final line that prints “Done!,” however, lies outside either code block, so it runs in both Figure 3.2.4 and 3.2.5.

Figure 3.2.5

If-Then-Else-If-Else

Now let’s throw our else-if statements into the mix. We’ll start with just two checks: raining or cold.

Figure 3.2.6

The majority of the code in Figure 3.2.6 is the same as the code from Figure 3.2.4, but we’ve put something in between the if and the else. Line 9 is nearly identical to the original if in line 5, but it starts with a slightly different keyword: elif. This is Python’s keyword for else-if. Other than the “el” at the beginning, it perfectly matches the original if. The only necessity for an elif statement is that it must come after an if and before any else at that level of indentation. And, as we said before, we can have more than one, as shown in Figure 3.2.7.

Figure 3.2.7

How does the code in Figure 3.2.7 run? First it creates todaysWeather on line 2 and gives it the value “windy.” Then it checks on line 5 if todaysWeather equals “raining.” It doesn’t, so it skips the conditional’s code block (lines 6 and 7). Then it checks the first elif on line 9. todaysWeather doesn’t equal “cold,” so it skips this code block (lines 10 and 11), too. Then it checks the second elif on line 13. todaysWeather does equal “windy,” though, so it runs the contents of that code block (line 14) and prints “jacket.” Now that one of the parts of the if-then-else-if-else block has run, it doesn’t check the rest. From the start, it goes to the first True conditional it finds, runs its code block, and skips the rest. In this case, that means it skips the elif on line 16 and the else on line 19.

We can preview a later lesson to examine this; later, we’ll talk about using operators along with conditionals. The code in Figure 3.2.8 approaches the same issue twice; note the difference.

Figure 3.2.8

In Figure 3.2.8, we’re trying to print “scarf” if it’s cold and “jacket” if it’s either cold or windy. In the first segment (lines 4 through 10), what happens? The conditional on line 5 triggers (or is True), so its code block runs and prints “scarf.” The second condition (on line 8) is an else-if, so it doesn’t trigger if the first one runs. So, even though the condition in the elif statement is true, it doesn’t run because the first if ran. It’s an _else-_if; it only runs as an alternative to the preceding conditionals.

In the second segment (lines 13 through 17), we resolve this. Instead of making it an elif, we just make it another if. It’s not indented under conditional beginning on line 13, so it runs either way. The second segment checks both conditionals because neither one is an else-if for the other. So, only use else-if if you want the conditional to be skipped if a previous part of the structure was true.

Common Errors

Finally, note that a common error in programming conditionals is to “orphan” the else or the else-if conditionals, as shown in Figure 3.2.9.

Figure 3.2.9

The code in Figure 3.2.9 code gives us a SyntaxError. Why? Between the elif on line 9 and the if on line 5, there is a line (line 7) at the same level of indentation as the if. That breaks the code block of the if on line 5. The elif on line 9, however, has to follow an if; or more specifically, must immediately follow the indented code block that follows an if. As far as Python is concerned, the elif on line 9 is orphaned; it has no corresponding if because line 7 broke the code block of the if on line 5. The same occurs on line 11 before the else, which similarly must follow an if or elif block directly.

3. Conditionals and Operators

We’ve already seen that conditional statements usually use logical expressions built around logical operators to decide what to do. This isn’t always the case; sometimes we might store the result of a logical expression in a boolean, and simply use that boolean inside the conditional instead of the expression itself. Either way, though, conditionals are often used with logical expressions in some way.

So far, we’ve only looked at the equality operator. However, conditionals are used in other ways as well.

Relational and Mathematical Operators

In addition to the equality operator (whether used mathematically or more generally with strings), it is common to use the other relational and mathematical operators with conditionals. We’ve covered one example several times: comparing bank balances. That is a relational expression that would generate True or False based on whether one number is greater than another.

We can embed other mathematical operators within these statements as well. For example, if we wanted to compare a person’s bank balance to a purchase price plus its sales tax, we could perform that mathematical operation right there within the conditional rather than performing it separately and storing it for later comparison in a conditional.

Boolean Functions

We’ve mentioned functions a few times now; we’ll get to them more later, but for now, we know that functions are like custom, more complex operators that take some input and return some output. For example, we’ve mentioned before that some languages (such as Python) have a len() function before, which takes as input something with a length (like a string or a list of items) and produces as output the length of that input (like 12 when the input is “Hello, world”).

Functions can return booleans as well, which means we can use functions in conditionals. For example, we could have a function that takes a filename and checks if the file exists. So, our conditional would basically say, “if this file exists, then...” A lot of the complexity and power around conditionals comes when we start writing custom functions to return booleans.

Boolean Operators

Finally, boolean operators allow us to take other operators and functions and combine them into far more complex conditionals. We can check multiple different conditions, or multiple combinations of conditions. We could have very complex statements, although in practice we generally want to break complex conditionals down into multiple, simpler, nested conditionals.

Returning to our weather and clothing example, we would likely have certain articles of clothing that are worn in multiple kinds of weather. We might wear a jacket in either cold or windy weather, for example. Boolean operators would let us check either of those conditions within a single line: if cold or windy, then wear a jacket.

4. Conditionals and Operators

Let’s take a look at some of the ways we can use conditionals along with operators in Python. We’ll keep these examples simple: mostly if-then-else statements and few elif statements, but note that these can be combined with the advanced structures covered above.

Relational Operators

We’ve covered before the simple way we can use relational operators in conditionals, but let’s look again. What if we wanted to check to see if a buyer has enough funds on a card to make a purchase?

The greater-than-or-equal-to operator returns True if the first number is greater than or equal to the second, False if it is not. Since it returns True or False, we can use it in conditional statement in line 8 of Figure 3.2.10. 

Figure 3.2.10

Here, we see that balance is greater than purchasePrice, so the operator returns True, and the code block under the if statement runs.

Relational and Mathematical Operators

On their own, mathematical operators return other numbers, so they can’t be used on their own in a conditional. The statement “if 3 + 5, then...” doesn’t make sense because 3 + 5 returns 8, not a True or False.

However, we can use mathematical operators along with relational operators. Imagine in our above example if we wanted to compare the balance to the purchase price with sales tax. How would we do that?

In Figure 3.2.11, we’ve created a variable salesTax and given it the value 1.08, which mathematically is the multiplier for an 8% sales tax. Then, in the conditional, we multiply purchasePrice by salesTax. The computer automatically does this before checking the relational operator because of its internal order of operations. In this way, we can use mathematical operators within conditional statements.

Figure 3.2.11

Set Membership Operators

You might remember that one of the things that makes Python unique is easy access to functions that check if something is a member of another set. So, where many languages would have this next example as an example of a boolean function, in Python it’s a unique kind of operator.

Figure 3.2.12 shows a more complicated check for weather and clothing. Instead of checking each type of weather one-by-one and printing the corresponding articles of clothing, we could instead create lists of the weather conditions for each piece of clothing. On line 2, we see one of them: jacketWeather is a list of types of weather that suggest the user should wear a jacket: cold, windy, raining, and snowing.

Figure 3.2.12

The conditional on line 7 checks to see if todaysWeather is one of the items in jacketWeather, and if so, prints jacket on line 8. If we wanted to add another weather condition to the list of conditions that dictate wearing a jacket, we just have to add it to the list jacketWeather. Similarly, we could have lists like this for jackets, scarves, t-shirts, etc., and easily check them. Note that if this is confusing, don’t worry: we haven’t gotten to lists yet. Python’s syntax is accessible enough that you might understand this just based on the natural meaning of the word “in,” but don’t worry if that’s not the case. We’ll talk more about this later.

Question

What does the conditional 'if todaysWeather in jacketWeather' check for in Python?

Answer the question

Answer the question above the continue reading. iTELL evaluation is based on AI and may not always be accurate.

Boolean Functions

If a function returns a boolean, then we can use it in a conditional statement. For example, in Python, there is a function (well, technically a method, but don’t worry about the difference for now) called isdigit() that returns True if the string represents a number, False if it does not. Figure 3.2.13 shows this in action.

Figure 3.2.13

You might initially be confused about why isdigit() is after the variable name (myNumericString.isdigit()) instead of the way we’ve seen functions before (isdigit(myNumericString)). The reason for this is that it’s a method, not a function—but again, we’ll get to the difference later. For now, just know that myNumericString.isdigit() returns True if myNumericString is a number, False if it is not; and, any string can use .isdigit() the same way.

So, within the conditional on line 5 of Figure 3.2.13, we have myNumericString.isdigit(). “12345” is all numbers, so the conditional on line 5 is True, and so it prints on line 6 that the string is numerical. The function (well, method) returns True, so the conditional is true, so the first code block runs. In lines 10 through 13, the opposite happens: “ABCDE” is not numeric, so the conditional is False, so the second code block (line 13, after the else) runs instead. If you’re curious, there are similar methods for checking if a string is all letters (.isalpha()), all letters or numbers (.isalnum()), all lowercase (.islower()), all uppercase (.isupper()), or all whitespace (.isspace()).

Question

What does the isdigit() method in Python do?

Answer the question

Answer the question above the continue reading. iTELL evaluation is based on AI and may not always be accurate.

Boolean Operators

Finally, our boolean operators—and, or, and not—can be used to combine any of these logical expressions together. Let’s look at this with two examples: a simple one from our weather example, and a complex one from our purchasing example.

Figure 3.2.14 is a simplified version of one of our previous examples of elif, this time using just one if. Here, the conditional checks if todaysWeather is either cold or windy. Note the syntax here: to check if one or the other is true, we simply put the word or between the two logical expressions. Here, the first one evaluates to True and the second one evaluates to False, and True or False resolves to True: it’s true that the weather is either cold or windy.

Figure 3.2.14

In Figure 3.2.15, had we used and instead of or, then the conditional would have been False. It would not be true that todaysWeather equals both “cold” and “windy” (and in fact, the way we’ve written this, that would be impossible since “cold” == “windy” itself is False).

Figure 3.2.15

Boolean Operators II

Now let’s try a more complex example. Previously, we’ve mentioned in the context of our purchasing code the idea of checking several conditions: Is the balance sufficient? Is the cardholder the person making the purchase? Is the vendor a trusted vendor?

Figure 3.2.16 shows a complex chunk of code that tests this. We’re putting together three logical expressions in one conditional with a pair of and operators. We check if the balance is greater than the purchase price plus sales tax, and the cardholder is the current customer, and the vendor is a trusted vendor. Only if all three of those things are True do we approve the purchase.

Figure 3.2.16

This can get even more complicated. We might have logical expressions with boolean operators within the larger expression. Observe Figure 3.2.17 and note how it runs.

Figure 3.2.17

First, a syntactical note. The conditional statement on lines 18 and 19 looks weird, doesn’t it? It ends in a slash, the next line is double-indented, and the colon isn’t until after line 19. In Python, this is how we tell the computer, “Interpret these two lines as one line.” Breaking the code between two lines makes it more readable for us as humans, but the computer needs to see it as all one line. So, this line lets us do both. The slash says, “Copy the next line, and put it where this slash is.”

Anyway, on line 13 we’ve added an additional variable: overdraftProtection. Overdraft protection (for this example, anyway) allows the customer to charge more than their balance and pay it off later. If it’s available, then it doesn’t matter if the balance is greater than the purchase price. So, here we have a nested or within our longer and statements. The computer should evaluate whether the balance is sufficient or overdraft protection is available. If either is True, then the first part of the condition is True.

Note that we put parentheses around this or expression on line 18 to force the computer to evaluate it first. In this case, we didn’t actually have to. The computer will automatically evaluate logical operators from left to right. However, it’s always good to use parentheses for human readability, as well as for safety. For example, if we had put the or expression at the end without parentheses, it would have changed the results. So, it’s always good to use parentheses to be clear on the order in which things should be evaluated.

As we said before, we could take these principles and combine them with the complex if-then-else-if-else statement structures from earlier.

Question

What is the purpose of the overdraftProtection variable in the code?

Answer the question

Answer the question above the continue reading. iTELL evaluation is based on AI and may not always be accurate.

5. Nested Conditionals

In our example of evaluating whether a purchase would be approved, there was a weakness. We evaluated whether or not multiple conditions were all true, and if they all were, then we approved the purchase; if not, we rejected it. However, this doesn’t tell us why the purchase was rejected. We know that if it was approved, all the conditions were true, but if it was rejected, we don’t know which part caused the rejection. We can resolve this by using a more complex structure: a nested conditional.

A nested conditional isn’t a special type of control structure like else-if or else. Rather, it’s just one way of applying an existing control structure. If a conditional is true, it runs the code block that the conditional controls. That code block can be anything we want it to be, which means that code block can itself contain conditionals.

Our original reasoning was, “If the balance is sufficient and the customer is the cardholder and the vendor is trusted, approve the purchase; if not, reject it.” We can revise this reasoning a bit to allow us to make decisions based on those individual conditions. This is a bit difficult to explain in paragraph form, so if this is confusing, don’t worry; we’ll use a flowchart in a moment, then code. We might say instead: if the balance is sufficient, check the cardholder; else, reject because of insufficient balance. If the cardholder is the customer, check the vendor; else, reject because of invalid cardholder. If the vendor is trusted, then accept the purchase; else, reject because of untrusted vendor.

Nested Conditionals in a Flowchart

If that was confusing, don’t worry: this kind of branching reasoning is tough to explain in linear text. Instead, let’s take a look at two flowchart views of this.

3.2.2.png

Figure 3.2.18

Figure 3.2.18 was our original approach: one big decision with multiple conditions. If all are true, we go one way; if one is false, we go a different way.

3.2.19

Figure 3.2.19

Figure 3.2.19 is our new approach. Each individual decision is separate. If one is True, we go on to the next decision; if one is False, we go to the dedicated output for that decision. Each conditional governs whether we move on to the next conditional or just exit. In some ways, this is similar to the else-if; however, where an else-if only runs if the previous if was False, a nested if only runs if the previous if was True because it’s part of the code block that only runs if the if statement was True.

6. Nested Conditionals in Python

Let’s take a look at what our previous purchase validation code would look like with nested conditionals.

Ifs Within Ifs

Note that while one major benefit of nested conditionals is that we can take care of more combinations of conditions, another benefit is that in many ways, this code is more readable. Take a look at Figure 3.2.20.

Figure 3.2.20

Remember how we had to break one line of code between two lines just for readability in Figure 3.2.16? With these nested conditionals, we no longer have to do that. Instead, we have three short, simple conditional statements, one under the other on lines 14, 15, and 16. Each is indented under the previous one, meaning each only runs if the previous one also ran. That means the purchase is only approved if the first conditional and the second conditional and the third conditional are all True, which makes it functionally equivalent to our original statement.

However, with this structure, each individual conditional can have its own dedicated else block, meaning we can print exactly why the purchase failed. On line 8, I’ve changed the vendor to an untrusted vendor, and so the code runs until it checks the third conditional on line 16. This condition is False, so it jumps to this conditional’s else block (line 19) and says the vendor was untrusted. This tells us a lot more than our earlier code: it tells us the vendor was untrusted, and the fact that it reached this line also tells us that both the balance was sufficient and the cardholder was valid because this conditional was controlled by those previous conditionals.

Ifs Within Elses

This nesting applies on both sides of the structure as well. We can write code that is functionally equivalent to the above with a completely different structure by nesting our conditionals in the else blocks instead. Check it out in Figure 3.2.21.

This code performs exactly the same, but all the nesting is inside the else portions of the conditional. That’s because instead of checking whether the purchase passes each requirement on lines 15, 18, and 21, it checks whether the purchase fails each requirement; notice how the logical expressions have changed compared to Figure 3.2.20. If the purchase fails a condition, it prints that it’s failed and why; if not, it moves on to the next check. This is like saying that a purchase is approved if none of the checks fail, rather than if all of them pass: these mean the same thing, but they’re organized a little differently.

Figure 3.2.21

7. Conditionals and Scope

We used conditionals as our example for scope in the previous chapter, so you’ve already seen a bit about how these interact. Now that you know what conditionals are, however, let’s revisit this. In Python, the scope of a variable starts when it is created, and ends when one of a number of terminations happen. For now, the only termination you need to know is the program ending: when the program ends and closes, the computer forgets the variables that were created while it was running. There are other times when the scope of a variable ends or is suspended, but for now, you only need to worry about the scope ending when the code ends.

Accessing Variables within Conditionals

So, let’s return to our earlier example of scope in a conditional now that we know what conditionals are, shown here in Figure 3.2.22.

Recall that this code creates the variable result outside the conditional. The scope of result is from line 4 until the program stops running. So, when line 6 inside the conditional comes up to change the value of result, result is still available. This line is within the scope of this variable. Within what we know now (and what we’ll learn until we get to functions), the scope of a variable is from the point at which it is created until the end of the program.

Figure 3.2.22

Creating Variables within Conditionals

Note, however, that there is a risk. Imagine if you create a variable within an if statement’s code block, but then that code block doesn’t run. That means the variable was never created, and so if you try to access the variable outside the code block, your code will crash. You can see this happening in Figure 3.2.23.

Figure 3.2.23

If we set the values of myNum1 and myNum2 such that the conditional doesn’t run and we don’t create result outside the conditional, then our code encounters an error. The scope of result is from the moment it is created until the end of the program, but if line 4 never runs, it is never created; so, when the computer tries to print it in line 5, it is out of scope.

The best way to resolve this, in my opinion at least, is to never create variables inside a conditional that will need to be accessed outside the conditional. In fact, most languages that I know of won’t even let you do what Python is letting you do here; Java, for example, defines a variable’s scope as the current code block, so once the conditional is concluded, the program forgets result altogether even if the code block ran. I, personally, recommend following that convention. There is another way around this issue, though.

If we really want to create a variable inside a conditional to use outside of it, the least we can do is create it within each branch of the conditional, including an else. The if-then-else shown in Figure 3.2.24 guarantees that either the if code block or the else code block will run. Since result is created in both, we guarantee result will have been created when we reach line 7. Again, I personally recommend that you avoid creating variables in conditionals that you need to access outside, but if you do, you can use this to guarantee they’re created.

Figure 3.2.24

Question

What is the best practice for creating variables inside conditionals in programming?

Answer the question

Answer the question above the continue reading. iTELL evaluation is based on AI and may not always be accurate.

8. Conditionals and Turtles

Now that we have conditionals at our disposal, we can really start to create a way for the user to control turtles with their input alone. Let’s create an interface with two possible commands the user can give: turn and forward. Let’s also assume the user is going to enter two such commands, so we’ll run the same code twice.

Turn and Forward

So what does this look like in code? It’s actually surprisingly short, as seen in TurnandForward.py.

We let the user input two commands, and so we’ve copied all the code twice (and left the comments out the second time); later, we’ll learn how to do this more efficiently. For now, it means we’re mostly interested in lines 4 through 17; line 1 just sets up our turtle, and lines 19 through 27 just repeat lines 4 through 17. So, let’s walk through this code piece by piece.

First, line 4 gets the command from the user as a string and stores it in command. Then, line 7 runs a simple logical expression for string equality to see if the command the user put in was “turn.” If so, then line 9 asks the user to put in an angle, and line 11 executes that turn.

If the user didn’t input “turn” as the command, then the code skips lines 9 and 11 and checks in line 13 if the command was “forward.” If so, line 15 asks the user to input a distance, and line 17 executes the move forward. Then, lines 19 through 27 repeat the process.

Notice a couple of things here. First, notice that this code reuses command in lines 19 through 27. There’s no need to create a second variable to store the command because the previous command will be overwritten. The same goes for angle and distance; if the user enters two forward commands, then distance in the first one will be overwritten the second time.

You can extend this code in a lot of ways: you could add more commands, for example. You can find the list of commands available for the turtle graphics package at https://docs.python.org/3.5/library/turtle.html.

Turn, Forward, or Error

However, with the current design of this code, what happens if the user enters invalid commands? Try running TurnandForward.py, but enter words like “up” and “down” instead of “turn” and “forward”.

What happens? Nothing! Why is that? Well, the words “up” and “down” (or any other words besides “turn” and “forward”) don’t cause any of the conditionals to resolve to True, so they’re skipped. In part, that’s a good thing: it means our code doesn’t crash if we enter invalid commands (as it will right now if we enter strings for angle or distance, but we’ll handle that later). But it’s also a bad thing: the user doesn’t know why the code doesn’t do anything! How do we repair this?

Simple! We just add an else at the end of each conditional that prints that the command was invalid, as shown in TurnForwardorError.py. For usability, it’s good to give the user feedback on what exactly they could have done as well, so we print the commands the code could have understood, “turn” and “forward”. So, this is one way we can improve this code.

There remains lots of room for improvement in this code, of course. For one, why only execute two commands? With these two commands alone, the user can only ever draw a single line in one direction. Would it be better for the user to be able to execute as many commands as they want until they choose to exit? We’ll cover that when we come to loops next lesson. Second, why only these primitive little options like “forward” and “turn?” Wouldn’t it be nice if we could have singular commands for “octagon” or “star?” We’ll cover that when we come to functions. Third, the code crashes if the user doesn’t put in a valid number for “distance” or “angle.” Wouldn’t it be better if it gave them feedback the way it does if they enter an invalid angle? We’ll cover that when we come to error handling. By the end of this unit, you’ll have a script that can run any number of user-inputted commands, and the ability to write custom commands like “octagon” yourself!

Question

What happens if the user enters invalid commands in the current code?

Answer the question

Answer the question above the continue reading. iTELL evaluation is based on AI and may not always be accurate.

Last updated at