*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
else:
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
author
date
:type temp: Int
:type desiredTemp: Int
:rtype: String
"""
if temp < desired_temp - 5:
status = 'Heat'
elif temp > desired_temp + 5:
status = 'AC'
else:
status = 'off'
return status
```

```
status = my_thermo_stat(65,75)
print(status)
```

```
Heat
```

```
status = my_thermo_stat(75,65)
print(status)
```

```
AC
```

```
status = my_thermo_stat(65,63)
print(status)
```

```
off
```

**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
else:
y = 0
print(y)
```

```
2
```

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
else:
y = 0
print(y)
```

```
4
```

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
else:
y = 0
print(y)
```

```
4
```

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
author
date
:type x: Int
:type y: Int
:rtype: Int
"""
if x > 2:
if y < 2:
out = x + y
else:
out = x - y
else:
if y > 2:
out = x*y
else:
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])
```

```
False
```

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
author
date
"""
# 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)
print(x)
```

```
6
```

```
x = my_adder('1','2','3')
print(x)
```

```
---------------------------------------------------------------------------
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
author
date
: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'
else:
return 'odd'
```

```
is_odd(11)
```

```
'odd'
```

```
is_odd(2)
```

```
'even'
```

**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’.

```
np.pi
```

```
3.141592653589793
```

```
def my_circ_calc(r, calc):
"""
Calculate various circle measurements
author
date
: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')
```

```
19.634954084936208
```

```
my_circ_calc(3, 'circumference')
```

```
18.84955592153876
```

**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 >