This notebook contains an excerpt from the Python Programming and Numerical Methods - A Guide for Engineers and Scientists, the content is also available at Berkeley Python Numerical Methods.

The copyright of the book belongs to Elsevier. We also have this interactive book online for a better learning experience. The code is released under the MIT license. If you find this content useful, please consider supporting the work on Elsevier or Amazon!

< CHAPTER 4. Branching Statements | Contents | 4.2 Ternary Operators >

If-Else Statements

A branching statement, If-Else Statement, or If-Statement for short, is a code construct that executes blocks of code only if certain conditions are met. These conditions are represented as logical expressions. Let \(P\), \(Q\), and \(R\) be some logical expressions in Python. The following shows an if-statement construction.

CONSTRUCTION: Simple If-Else Statement Syntax

if logical expression:
    code block

The word “if” is a keyword. When Python sees an if-statement, it will determine if the associated logical expression is true. If it is true, then the code in code block will be executed. If it is false, then the code in the if-statement will not be executed. The way to read this is “If logical expression is true then do code block.”

When there are several conditions to consider you can include elif-statements; if you want a condition that covers any other case, then you can use an else statement.

Note! Python gives the same level of indentation to every line of code within a conditional statement.

CONSTRUCTION: Extended If-Else Statement Syntax

if logical expression P:
    code block 1
elif logical expression Q:
    code block 2
elif logical expression R:
    code block 3
    code block 4

In the previous code, Python will first check if \(\textit{P}\) is true. If \(\textit{P}\) is true, then code block 1 will be executed, and then the \(\textit{if-statement}\) will end. In other words, Python will not check the rest of the statements once it reaches a true statement. However, if \(\textit{P}\) is false, then Python will check if \(\textit{Q}\) is true. If \(\textit{Q}\) is true, then code block 2 will be executed, and the if-statement will end. If it is false, then \(\textit{R}\) will be executed, and so forth. If \(\textit{P}\), \(\textit{Q}\), and \(\textit{R}\) are all false, then code block 4 will be executed. You can have any number of elif statements (or none) as long as there is at least one if-statement (the first statement). You do not need an else statement, but you can have at most one else statement. The logical expressions after the if and elif (i.e., such as P, Q, and R) will be referred to as conditional statements.

TRY IT! Write a function my_thermo_stat(temp, desired_temp). The return value of the function should be the string ‘Heat’ if temp is less than desired_temp minus 5 degrees, ‘AC’ if temp is more than the desired_temp plus 5, and ‘off’ otherwise.

def my_thermo_stat(temp, desired_temp):
    Changes the status of the thermostat based on 
    temperature and desired temperature
    :type temp: Int
    :type desiredTemp: Int
    :rtype: String
    if temp < desired_temp - 5:
        status = 'Heat'
    elif temp > desired_temp + 5:
        status = 'AC'
        status = 'off'
    return status
status = my_thermo_stat(65,75)
status = my_thermo_stat(75,65)
status = my_thermo_stat(65,63)

EXAMPLE: What will be the value of y after the following script is executed?

x = 3
if x > 1:
    y = 2
elif x > 2:
    y = 4
    y = 0

We can also insert more complicated conditional statements using logical operators.

EXAMPLE: What will be the value of y after the following code is executed?

x = 3
if x > 1 and x < 2:
    y = 2
elif x > 2 and x < 4:
    y = 4
    y = 0

Note that if you want the logical statement a < x < b, this is two conditional statements, a < x and x < b. In Python, you can type a < x < b as well. For example:

x = 3
if 1 < x < 2:
    y = 2
elif 2 < x < 4:
    y = 4
    y = 0

A statement is called nested if it is entirely contained within another statement of the same type as itself. For example, a nested if-statement is an if-statement that is entirely contained within a clause of another if-statement.

EXAMPLE: Think about what will happen when the following code is executed. What are all the possible outcomes based on the input values of x and y?

def my_nested_branching(x,y):
    Nested Branching Statement Example
    :type x: Int
    :type y: Int
    :rtype: Int
    if x > 2:
        if y < 2:
            out = x + y
            out = x - y
        if y > 2:
            out = x*y
            out = 0
    return out

Note! As before, Python gives the same level of indentation to every line of code within a conditional statement. The nested if-statement have deeper indentation by increasing four white spaces. You will get an IndentationError if the indentation is not correct, as we saw in the defining of the functions.

import numpy as np
all([1, 1, 0])

There are many logical functions that are designed to help you build branching statements. For example, you can ask if a variable has a certain data type with function isinstance. There are also functions that can tell you information about arrays of logicals like any, which computes to true if any element in an array is true, and false otherwise, and all, which computes to true only if all the elements in an array are true.

Sometimes you may want to design your function to check the inputs of a function to ensure that your function will be used properly. For example, the function my_adder in the previous chapter expects doubles as input. If the user inputs a list or a string as one of the input variables, then the function will throw an error or have unexpected results. To prevent this, you can put a check to tell the user the function has not been used properly. This and other techniques for controlling errors are explored further in Chapter 10. For the moment, you only need to know that we could use the \(\texttt{raise}\) statement with a \(\texttt{TypeError}\) exception to stop a function’s execution and throw an error with a specific text.

EXAMPLE: Modify my_adder to throw out a warning if the user does not input numerical values. Try your function for non-numerical inputs to show that the check works. When a statement is too long, we can use ‘' symbol to break a line to multiple lines.

def my_adder(a, b, c):
    Calculate the sum of three numbers
    # Check for erroneous input
    if not (isinstance(a, (int, float)) \
            or isinstance(b, (int, float)) \
            or isinstance(c, (int, float))):
        raise TypeError('Inputs must be numbers.')
    # Return output
    return a + b + c
x = my_adder(1,2,3)
x = my_adder('1','2','3')
TypeError                                 Traceback (most recent call last)
<ipython-input-13-c3e353c636b0> in <module>
----> 1 x = my_adder('1','2','3')
      2 print(x)

<ipython-input-11-0f3d29eecee0> in my_adder(a, b, c)
     10             or isinstance(b, (int, float)) \
     11             or isinstance(c, (int, float))):
---> 12         raise TypeError('Inputs must be numbers.')
     13     # Return output
     14     return a + b + c

TypeError: Inputs must be numbers.

There is a large variety of erroneous inputs that your function may encounter from users, and it is unreasonable to expect that your function will catch them all. Therefore, unless otherwise stated, write your functions assuming the functions will be used properly.

The remainder of the section gives a few more examples of branching statements.

TRY IT! Write a function called is_odd that returns ‘odd’ if the input is odd and ‘even’ if it is even. You can assume that input will be a positive integer.

def is_odd(number):
    function returns 'odd' if the input is odd, 
       'even' otherwise
    :type number: Int
    :rtype: String
    # use modulo to check if the input is divisible by 2
    if number % 2 == 0:
        # if it is divisible by 2, then input is not odd
        return 'even'
        return 'odd'

TRY IT! Write a function called my_circ_calc that takes a numerical number, r, and a string, calc as input arguments. You may assume that r is positive, and that calc is either the string ‘area’ or ‘circumference’. The function my_circ_calc should compute the area of a circle with radius, r, if the string calc is ‘area’, and the circumference of a circle with radius, r, if calc is ‘circumference’.

def my_circ_calc(r, calc):
    Calculate various circle measurements
    :type r: Int or Float
    :type calc: String
    :rtype: Int or Float
    if calc == 'area':
        return np.pi*r**2
    elif calc == 'circumference':
        return 2*np.pi*r
my_circ_calc(2.5, 'area')
my_circ_calc(3, 'circumference')

Note! The function we write not only working on single value, but on Numpy arrays as well (that is the same operation will apply on each item of the array). See the following example, that we could calculate the circumferences for radius as [2, 3, 4] using a Numpy array.

my_circ_calc(np.array([2, 3, 4]), 'circumference')
array([12.56637061, 18.84955592, 25.13274123])

< CHAPTER 4. Branching Statements | Contents | 4.2 Ternary Operators >