Decisions

Tasks

Learning Outcomes

By the end of this lesson, you should be able to:

  1. Identify conditional statements in Python code
  2. Integrate logical expressions in conditional statements
  3. Write simple conditional statements
  4. Write a sequence of conditional statements using if-elif-else structure
  5. Write nested conditional statements

Key Terms/Concepts

Introduction

In the previous three lessons, you learned how to write sequential Python statements. Sequential statements refer to sequence of commands that are executed one after the other in the given order. In Lesson 4, you learned about functions which execute a named block of code when a function call is invoked. This lesson discusses conditional statements.

Conditional statements are Python commands that enable the execution of blocks of code based on the satisfaction of specific condition(s). Such commands exist in almost all structural and procedural programming languages. This conditional execution of code blocks set up multiple mutually exclusive execution paths in program code.

We start simple by introducing the if statement. Then, you will gradually expand the if statement into if-else statements, then elif statements, and finally nested if-else statements. In addition, we look deeper into simple and compound logical statements. 

if Statements

The simplest conditional statement is the if statement. As the name suggests, a block of code is executed 'only if' a specific condition is satisfied. The Python syntax for if-statements is:


if <logical  expression>:
    <block of code>

The first line starts with the keyword if. This keyword is followed by a space, then by a logical expression, followed by a colon (:). As you may recall from Lesson 3, a logical expression is an expression that evaluates to either True or False.

The if defines the start of a code block. Like the function def line, all code that belongs to the if are indented with the same indentation.

if blocks may be used within main program code or within functions, or with other if blocks (these are nested ifs.)

Some simple if statements:

if cost > 0.00: # compares variable to float
if weight < 100: # compares variable to int
if name == "David": # compares variable to string
if first >= last: # compares variable to variable
if result == True: # compares variable to boolean

It is possible, but not particularly useful, to write:

if 3 > 5: # compares raw number to raw number
if True: # tests True

as these statements always evaluate to either True or False, which is pointless. Useful ifs always involve a variable.

A more common design mistake is to use a statement that theoretically could evaluate to True or False, but practically evaluates to a fixed Boolean value. An example of such statement is the following:


if exam_score > 200: 
  print(‘Good score’)

In the context of a exam a valid score is a number between 0 and 100, the above statements will always, practically speaking, evaluate to False since no valid score is ever greater than 100. Again, such code is redundant and should be avoided.

To understand the importance of the above discussion, I invite you to put on some special goggles and look into the mind of a successful programmer. When looking, do not be distracted by the variety of commands and complex statements in the programmer's mind. Focus on how the mind operates during coding. 

You should observe that the mind is not only focused on writing the current line of code, but it predicts how the overall program behaves with some expectation of outputs. So, the mind is coding without losing the big picture and while keeping an eye on the expected output. Such a mind is unlikely to write redundant statements.

Alas! We do not have such goggles to enjoy looking into good programmers' minds. However, we can imitate these good programmers in their good programming practices. Through some patience and diligence, you could be one of them.

The following trivial function uses an if ti

A Simple Score Checker

def pass_exam(score):
    """
    -------------------------------------------------------
    Determines if an exam score is a pass.
    Use: passed = pass_exam(score)
    -------------------------------------------------------
    Parameters:
        score - numeric score (0 <= float <= 100)
    Returns:
        passed - True if score >= 50, False otherwise (bool)
    -------------------------------------------------------
    """
    passed = False

    if score >= 50:
        passed = True
    return passed

if-else Statements

Structure of if-else Statement:

The if statement provides a mechanism to execute code when a condition is satisfied. However, the statement does not specify an alternate code if the condition was not satisfied. The if-else statement provides such a mechanism.

The structure of the if-else statement is as follows:


if <logical expression>:
    <block code 1> 
else:
    <block code 2>

Observe how the else command appear on a separate line and has the same indentation as the if statement. Also, observe how block code 1 and 2 are both on the same indentation level.

Similar to the if-statement, in an if-else statement, both block 1 and 2 can contain a single or multiple lines of code. It is illegal to leave either block with no lines of code. Also, remember to include the colon after the keyword else. This has proven to be a common syntax error among students learning Python.

The if-else statement is like a toggle switch. You can only activate one side at a single time, but not both. If the logical expression evaluates to True, block code is executed and block code 2 is ignored. On the other hand, if the logical expression evaluates to False, block code 1 is ignored and block code 2 is executed.

Let us re-write the code for example 5.2.A using an if-else statement:

Code Listing 3: Solution to example 5.2.A using if-else statement

 def get_grade(score):
   if score 0 or score > 100:
        print(‘Error: invalid score’)
        return “ERROR”
   if score >= 50:
        grade = “Pass”
   else:
        grade = “Fail”
   return grade
10.
 #Test the function
 score = float(input(‘Enter student score: ‘))
 grade = get_grade(score)
 print(f‘result = {grade}’)

This solution is better than the one provided earlier, because it provides better readability.

As you can see, the logical expression only appears with the if statement (line 5), and the else statement (line 7) has no expressions. This is true for all else statements.

The above solution is not the only possible way to construct the if-else statement. The if-else statement could also be written as:


if score < 50:
    grade = “Fail”
else:
    grade = “Pass”

In terms of syntax, there is no preference to the former or later solution. However, as humans we normally think of 'positive' statements before 'negative' statements. Therefore, it could be argued that the first solution is slightly better in terms of readability.

5.3.2 Example of if-else Statement

Let us look into another example that uses if-else statement.

Example

Implement the function get_parity.

The function receives a parameter called num, representing a random integer.

The function finds the parity of the number and returns a string with value of Even or Odd.

Before we start coding, we need to think first on how we can determine if a number is even or odd. In mathematics, a number is even if it is divisible by 2 and is odd if it is not divided by 0. You already know this from your early school years. The relevant question here is how can we translate 'divisible by 2' to code?

Going back to mathematics, if number X is divisible by Y, then it means the remainder of dividing X by Y is 0. In Python, the modulo operator % comes to our rescue. Let us look at the solution:

5.3.3 Example with Multiple if-else Statements

In this subsection, we will look into a program that uses multiple if-else statements.

Example

Implement the function classify_num.

The function receives a parameter called num, representing a random integer.

The function finds the parity of the number, and also whether it is positive or negative.

The function does not return any value. Instead, the function prints one of the following to the console:


<num> is an even positive number
<num> is an even negative number
<num> is an odd positive number
<num> is an odd negative number

We have already seen how to find out if a number is even or odd. So, we can borrow that code in our solution. Let us start with:


def classify_num(num):
    if num%2 == 0:
        print(f‘{num} is an even ‘)
    else:
        print(f‘{odd} is an odd ‘)

The only difference to the previous solution is that we replaced the parity assignment with a print statement.

Next, we need to add another if-else statement to find out if the number is positive or negative.


    if num > 0:
        print(‘positive number’)
    else:
        print(‘negative number’)

The final step is to make both print statements work together to produce a single line. To do that, we need to ensure that the print statement in the first if-else block does not end with a new line. This could be done by adding end='' at the end of the print statements.

The full solution is provided below:

elif Statements

5.4.1 Structure of an elif Statement

The if-else statement supports us with a solution for scenarios that have an answer of Yes/No. Many real-life scenarios require answers beyond yes and no. For instance, a student grade is normally assigned on a scale of A,B,C,D and F, compared to the simple Pass/Fail scheme. To address this issue, Python has the elif statement, which allows for a multi-decision process.

The elif statement is not a stand-alone command. It is an extension of the if-else structure that you learned in the previous sections. It has the following structure:


if <logical expression 1>:
    <block code 1> 
elif <logical expression 2>:
    <block code 2>
...
elif <logical expression n-1>
    <block code n-1>
else:
    <block code n>

The above structure allows for multi-decisions without a limit on the maximum number of decisions. If you want to make n decisions, then you will have one if statement, n-2 elif statements and one else statement, all working together. The total number of blocks will also be n blocks.

A decision here simply means a question that has a True/False answer. However, when all decisions are organized sequentially, they allow a multi-answer to the question. Let us follow through how the interpreter executes this structure:

  • The interpreter starts by evaluating logical expression 1 in the if-statement. If the answer is Yes/True, the interpreter goes to block 1 and executes all lines within that block. When it is done, it jumps to the line after the if-elif-else statements.
  • If the answer is No/False, it goes to the first elif statement and evaluates the second logical expression.
  • If the answer is Yes/True, it executes block 2, and then exits. If the answer is No/False, it moves to the following elif statement, and so forth.
  • If all logical expressions evaluate to No/False, the else statement will be activated and block n will be executed.

Here is an example.

5.4.2 Example of elif Statement

Example 5.4.A:

Re-implement the function get_grade. Such that the function returns the following based on the score value:


- [100,90] -> “A”
- (90,80] -> “B”
- (80,70] -> “C”
- (70,60] -> “D”
- (60,0] -> “F”

By looking at the above problem, we can see that there are multiple decisions to be made and so we need to use elif. The first if statement would be to check for the value of 'A' and the else statement at the end would be for the 'F'.

Below is the solution:

Nested if Statements

So far, you have seen the if statement, the if-else statement and the if-elif-else statement. You have also seen two if-else statements.

However, the discussion will not be complete without introducing the concept of nested if-else statements. In order not to make your learning experience of conditional statements overwhelming, we will touch on the subject briefly. When you feel comfortable with if statements and its variants, you will find the subject of nested if-else statements simple to comprehend.

Nested if-statements mean using an if-else structure inside another if-else structure. It is like a hierarchy in which you can have multiple layers of if-else statements within each other.

The following code is a re-implementation of the solution to 5.3.B using nested if statements.

Code Listing 10: Solution to example 5.3.B using nest if statements

 def classify_num(num):   
     if num%2 == 0: #number is even
        print(f‘{num} is an even ‘,end=’’)
    if num > 0:
        print(‘positive number’)
    else:
        print(‘negative number’)
     else: #number is odd
        print(f‘{num} is an odd ‘,end=’’)
        if num > 0:
            print(‘positive number’)
        else:
            print(‘negative number’)
    return

In the above solution, the if statement has a nested if-else structure. Also, the else statement has a nested if-else structure. In the initial solution, the program checks for even/odd using an if-else statement, and then checks for positive/negative using another if-else statement. In this new solution, the program checks for even and odd, and in each scenario it checks for positive/negative.

Using multiple if-else statements or nested if-else statements is a design consideration for the programmer. For the specific example of 5.3.B, the non-nested solution provides better writability because it avoids redundancy in the code. However, there could be other scenarios where using nested if-else statements would be a better choice.

What programmers seem to agree on is that having unnecessary nested layers of if-else is not a good programming practice. Below is an example of the bad practice:

Code Listing 11: Solution to example 5.4.A using nested if-else statements

 def get_grade(score):
   if score > 100 or score < 0:
        print(‘Error: invalid score’)
        grade = “ERROR”
   else:
        if score >= 90:
            grade = “A”
        else:
            if score >=80:
                grade = “B”
            else:
                if score >=70:
                    grade = “C”
                else:
                if score >= 60:
                    grade = “D”
                    else:
                        grade = “F”
   return grade

If you have got this so far, it means you have now a complete overview of conditional statements in Python. During your reading, you might be wondering why we skipped the concept of logical expressions, despite it being an important component of the conditional statements topic. The rationale goes back to the observation that some students struggle when learning about conditional statements if it is mixed with too many details about logical expressions. Therefore, we decided to move the discussion to the end when you are comfortable enough with if-else statements.

Before proceeding, I recommend that you take a short break and then come back with a refreshed mind.

Revisiting Logical Expressions

The concept of logical expressions and operators were briefly introduced in Lesson 3. The emphasis of Lesson 3, however, was on arithmetic expressions not logical expressions. We are revisiting the topic here because of its strong relevance to conditional statements.

Python, like most languages, has three main logical operators: and, or and not. These operators work on Boolean values and produce Boolean results. We will provide a separate discussion for each operator.

5.7.1 Logical not Operator

The simplest logical operator is the unary not operator. The operator toggles the value of a Boolean variable or literal. If it is True, it makes False, and if it is False it makes it True.

Let us see how this works in if-else statements.

Example

A museum, during the summer season, is offering eight new galleries to its visitors. Tickets sold during the summer season allow non-member guests to access galleries 2 to 6, while members can access galleries 1 to If a user has a golden membership, then they have exclusive access to gallery 8, in addition to the other galleries. 

Implement the function deny_access(member, golden). The function receives two Boolean parameters, Member and Gold. The function should print a statement outlining which galleries have been denied access based on the membership level.

Below is the solution:

5.7.2 Logical and Operator

The logical and operator returns True only if both operands are True. It evaluates to False, if either operand (or both) is False.  Here is an example of how it works in if-statements:

It is interesting how logical operators allow us to write code that resembles the English language.

There is a little trick to learn about the and operator. If there are multiple operands in a logical expression that uses an and operator, then it only takes one operand to be False to force the entire expression to evaluate to False.

For example, the following statement will evaluate to false, if any parameter is False:

If member and golden and VIP:

So, what happens if a user is not a member? The interpreter checks the value of member and finds that it is False, so it drops the rest of the expression, because regardless of the value of the remaining parameters, the expression will evaluate to False. We call this short-circuit.

5.7.3 Logical or Operator

The logical or operator returns True if any operand is True. It evaluates to False, only if both operands are False. Here is an example:

The or operator is different than the and operator in some aspects and is similar in others. Study the following table:

Table 1: Comparison between logical or and logical and operators
A B A and B A or B
True True True True
True False False True
False True False True
False False False False

You can see that both operators produce True if both operands are True, and produce False if both operands are False, but differ in the output if operands have different values. Therefore, it is inaccurate to think of the and-or operators as opposites (complements) of each other.

Note that the short-circuit for the or operator happens if the interpreter detects any operand with the value True.

5.7.4 Compound Logical Expressions

Logical expressions can use a combination of logical operators in a single expression. Some of these expressions are easy to analyze, but others would require some analysis to predict the output.

Study the following example:

The study of logical operators is the focus of a discipline in computer science called digital logic design. This is also the title of one of the courses which you will take in your computer science degree. If you like such analysis, you will find the course a joyful experience.

Conclusion

In Lesson 5, you have learned about conditional statements in Python. You can now read and write conditional statements using if and if-else structures. You have also learned how to expand such expressions using the if-elif-else structure. In addition, you are now more familiar with logical expressions and know how to use them in conditional statements.

In this week’s assignment, you will get a chance to practice problem-solving using Python. You should be able to recognize that there are multiple approaches to solve the problems, and each approach comes with its own advantages in terms of writability and readability.

In the upcoming lesson, you will carry what you learned here and apply it to a new topic which is the while loops. The topic of while loops is a good bridge between the topic of conditional statements and iterative statements.

Check Weekly Schedule for Assessments

5.8.2 References

  1. Peter Wentworth, Jeffrey Elkner, Allen B. Downey and Chris Meyers. (October 2012). How to think like a Computer Scientist. Learning with Python 3: Chapter 5: Conditionals.Open Book Project. ACM50, 1 Retrieved on July 15, 20