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

< 4.2 Ternary Operators| Contents | 5.0 Iteration >

# Summary¶

Branching (if-else) statements allow functions to take different actions under different circumstances.

Ternary operators allow single line branching statements

# Problems¶

Write a function

`my_tip_calc(bill, party)`

, where`bill`

is the total cost of a meal and`party`

is the number of people in the group. The tip should be calculated as 15% for a party strictly less than six people, 18% for a party strictly less than eight, 20% for a party less than 11, and 25% for a party 11 or more. A couple of test cases are given below.

```
def my_tip_calc(bill, party):
# write your function code here
return tips
```

```
# t = 16.3935
t = my_tip_calc(109.29,3)
print(t)
```

```
# t = 19.6722
t = my_tip_calc(109.29,7)
print(t)
```

```
# t = 21.8580
t = my_tip_calc(109.29,9)
print(t)
```

```
# t = 27.3225
t = my_tip_calc(109.29,12)
print(t)
```

Write a function

`my_mult_operation(a,b,operation)`

. The input argument,`operation`

, is a string that is either`'plus'`

,`'minus'`

,`'mult'`

,`'div'`

, or`'pow'`

, and the function should compute: \(a+b\), \(a-b\), \(a∗b\), \(a/b\), and \(a^b\) for the respective values for`operation`

. A couple of test cases are given below.

```
def my_mult_operation(a,b,operation):
# write your function code here
return out
```

```
x = np.array([1,2,3,4])
y = np.array([2,3,4,5])
```

```
# Output: [3,5,7,9]
my_mult_operation(x,y,'plus')
```

```
# Output: [-1,-1,-1,-1]
my_mult_operation(x,y,'minus')
```

```
# Output: [2,6,12,20]
my_mult_operation(x,y,'mult')
```

```
# Output: [0.5,0.66666667,0.75,0.8]
my_mult_operation(x,y,'div')
```

```
# Output: [1,8,81,1024]
my_mult_operation(x,y,'pow')
```

Consider a triangle with vertices at \((0,0)\), \((1,0)\), and \((0,1)\). Write a function

*my_inside_triangle(x,y)*where the output is the string ‘outside’ if the point \((x,y)\) is outside of the triangle, ‘border’ if the point is exactly on the border of the triangle, and ‘inside’ if the point is on the inside of the triangle.

```
def my_inside_triangle(x,y):
# write your function code here
return position
```

```
# Output: 'border'
my_inside_triangle(.5,.5)
```

```
# Output: 'inside'
my_inside_triangle(.25,.25)
```

```
# Output: 'outside'
my_inside_triangle(5,5)
```

Write a function

*my_make_size10(x)*, where*x*is an array and output is the first 10 elements of*x*if*x*has more than 10 elements, and output is the array*x*padded with enough zeros to make it length 10 if*x*has less than 10 elements.

```
def my_make_size10(x):
# write your function code here
return size10
```

```
# Output: [1,2,0,0,0,0,0,0,0,0]
my_make_size10(range(1,2))
```

```
# Output: [1,2,3,4,5,6,7,8,9,10]
my_make_size10(range(1,15))
```

```
# Output: [3,6,13,4,0,0,0,0,0,0]
my_make_size10(5,5)
```

Can you write my_make_size10 without using if-statements (i.e., using only logical and array operations)?

Write a function

*my_letter_grader(percent)*, where grade is the string ‘A+’ if*percent*is greater than 97, ‘A’ if*percent*is greater than 93, ‘A-‘ if*percent*is greater than 90, ‘B+’ if*percent*is greater than 87, ‘B’ if*percent*is greater than 83, ‘B-‘ if*percent*is greater than 80, ‘C+’ if*percent*is greater than 77, ‘C’ if*percent*is greater than 73, ‘C-‘ if*percent*is greater than 70, ‘D+’ if*percent*is greater than 67, ‘D’ if*percent*is greater than 63, ‘D-‘ if*percent*is greater than 60, and ‘F’ for any*percent*less than 60. Grades exactly on the division should be included in the higher grade category.

```
def my_letter_grader(percent):
# write your function code here
return grade
```

```
# Output: 'A+'
my_letter_grader(97)
```

```
# Output: 'B'
my_letter_grader(84)
```

Most engineering systems have redundancy. That is, an engineering system has more than is required to accomplish its purpose. Consider a nuclear reactor whose temperature is monitored by three sensors. An alarm should go off if any two of the sensor readings disagree. Write a function

*my_nuke_alarm(s1,s2,s3)*where*s1*,*s2*, and*s3*are the temperature readings for sensor 1, sensor 2, and sensor 3, respectively. The output should be the string ‘alarm!’ if any two of the temperature readings disagree by strictly more than 10 degrees and ‘normal’ otherwise.

```
def my_nuke_alarm(s1,s2,s3):
# write your function code here
return response
```

```
#Output: 'normal'
my_nuke_alarm(94,96,90)
```

```
#Output: 'alarm!'
my_nuke_alarm(94,96,80)
```

```
#Output: 'normal'
my_nuke_alarm(100,96,90)
```

Let Q(x) be the quadratic equation \(Q(x) = ax^2 + bx + c\) for some scalar values

*a*,*b*, and*c*. A root of \(Q(x)\) is an*r*such that \(Q(r) = 0\). The two roots of a quadratic equation can be described by the quadratic formula, which is

A quadratic equation has either two real roots (i.e., \(b^2 > 4ac\)), two imaginary roots (i.e., \(b^2 < 4ac\)), or one root, \(r = − \frac{b}{2a}\).

Write a function *my_n_roots(a,b,c)*, where *a*, *b*, and *c* are the coefficients of the quadratic \(Q(x)\), the function should return two values: *n_roots* and *r*. *n_roots* is 2 if *Q* has two real roots, 1 if *Q* has one root, −2 if *Q* has two imaginary roots, and *r* is an array containing the roots of *Q*.

```
def my_n_roots(a,b,c):
# write your function code here
return n_roots, r
```

```
# Output: n_roots = 2, r = [3, -3]
n_roots, r = my_n_roots(1,0,-9)
print(n_roots, r)
```

```
# Output: n_roots = -2, r = [-0.6667 + 1.1055i, -0.6667 - 1.1055i]
my_n_roots(3,4,5)
```

```
# Output: n_roots = 1, r = [1]
my_n_roots(2,4,2)
```

Write a function

*my_split_function(f,g,a,b,x)*, where*f*and*g*are handles to functions \(f(x)\) and \(g(x)\), respectively. The output should be \(f(x)\) if \(x≤a\), \(g(x)\) if \(x≥b\), and \(0\) otherwise. You may assume that \(b>a\).

```
def my_split_function(f,g,a,b,x):
if x<=a:
return f(x)
elif x>=b:
return g(x)
else:
return 0
```

```
# Output: 2.713
my_split_function(np.exp,np.sin,2,4,1)
```

```
# Output: 0
my_split_function(np.exp,np.sin,2,4,3)
```

```
# Output: -0.9589
my_split_function(np.exp,np.sin,2,4,5)
```