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

< 5.3 Comprehensions | Contents | 6.0 Recursion >

# Summary¶

Loops provide a mechanism for code to perform repetitive tasks; that is, iteration.

There are two kinds of loops: for-loops and while-loops.

Loops are important for constructing iterative solutions to problems.

Comprehensions provide another concise way to iterate sequence.

# Problems¶

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

```
y = 0
for i in range(1000):
for j in range(1000):
if i == j:
y += 1
```

Write a function

*my_max(x)*to return the maximum (largest) value in*x*. Don’t use the built-in Python function*max*.

Write a function

*my_n_max(x, n)*to return a list consisting of the n largest elements of*x*. You may use Python’s*max*function. You may also assume that*x*is a one-dimensional list with no duplicate entries, and that*n*is strictly positive integer smaller than the length of*x*

```
x = [7, 9, 10, 5, 8, 3, 4, 6, 2, 1]
def my_n_max(x, n):
# write your function code here
return out
```

```
# Output = [10, 9, 8]
out = my_n_max(x, n)
print(out)
```

Let

*m*be a matrix of positive integers. Write a function*my_trig_odd_even(m)*to return an array*q*, where q[i, j] = sin (m[i, j]) if m[i, j] is even, and q[i, j] = cos (m[i, j]) if m[i, j] is odd.

Let

*P*be an \(m \times p\) array and Q be a \(p \times n\) array. As you will find later in this book, \(M = P \times Q\) is defined as \(M[i, j] = \sum_{k=1}^{p}P[i, k]\cdot Q[k, j]\). Write a function *my_mat_mult(P, Q) that uses for-loops to compute*M*, the matrix product of*P*and*Q*. Hint: You may need up to three nested for-loops. Do not use the function*np.dot*.

```
import numpy as np
def my_mat_mult(P, Q):
# write your function code here
return M
```

```
# Output:
# array([[3., 3., 3.],
# [3., 3., 3.],
# [3., 3., 3.]])
P = np.ones((3, 3))
my_mat_mult(P, P)
```

```
# Output:
# array([[30, 30, 30],
# [70, 70, 70]])
P = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
Q = np.array([[1, 1, 1], [2, 2, 2], [3, 3, 3], [4, 4, 4]])
my_mat_mult(P, Q)
```

The interest, \(i\), on a principle, \(P_0\), is a payment for allowing the bank to use your money. Compound interest is accumulated according to the formula \(P_n = (1 + i)P_{n-1}\), where n is the compounding period, usually in months or years. Write a function

*my_saving_plan(P0, i, goal)*where the output is the number of years it will take \(P_0\) to become goal at \(i\%\) interest compounded annually.

```
def my_saving_plan(P0, i, goal):
# write your function code here
return years
```

```
# Output: 15
my_saving_plan(1000, 0.05, 2000)
```

```
# Output: 11
my_saving_plan(1000, 0.07, 2000)
```

```
# Output: 21
my_saving_plan(500, 0.07, 2000)
```

Write a function with

*my_find(M)*, where output is a list of indices*i*where M[i] is 1. You may assume that*M*is a list of only ones and zeros. Do not use the built-in Python function find.

```
# Output: [0, 2, 3]
M = [1, 0, 1, 1, 0]
my_find(M)
```

Assume you are rolling two six-sided dice, each side having an equal chance of occurring. Write a function

*my_monopoly_dice()*, where the output is the sum of the values of the two dice thrown but with the following extra rule: if the two dice rolls are the same, then another roll is made, and the new sum added to the running total. For example, if the two dice show 3 and 4, then the running total should be 7. If the two dice show 1 and 1, then the running total should be 2 plus the total of another throw. Rolls stop when the dice rolls are different.

A number is prime if it is divisible without remainder only by itself and 1. The number 1 is not prime. Write a function

*my_is_prime(n)*, where output is 1 if*n*is prime and 0 otherwise. Assume that*n*is a strictly positive integer.

Write a function

*my_n_primes(n)*where primes is a list of the first*n*primes. Assume that*n*is a strictly positive integer.

Write a function

*my_n_fib_primes(n)*, where the output*fib_primes*is a list of the first*n*numbers that are both a Fibonacci number and prime. Note: 1 is not prime. Hint: Do not use the recursive implementation of Fibonacci numbers. A function to compute Fibonacci numbers is presented in Section 6.1. You may use the code freely.

```
def my_n_fib_primes(n):
# write your function code here
return fib_primes
```

```
# Output: [3, 5, 13, 89, 233, 1597, 28657, 514229]
my_n_fib_primes(3)
```

```
# Output: [3, 5, 13]
my_n_fib_primes(8)
```

Write a function

*my_trig_odd_even(M)*, where the output \(Q[i, j] = sin (\pi/M[i, j])\) if \(M[i,j]\) is odd, and \(Q[i, j] = cos (\pi/M[i, j])\) if \(M[i, j]\) is even. Assume that M is a two-dimensional array of strictly positive integers.

```
def my_trig_odd_even(M):
# write your function code here
return Q
```

```
# Output: [[0.8660, 0.7071], [0.8660, 0.4339]]
M = [[3, 4], [6, 7]]
my_trig_odd_even(M)
```

Let \(C\) be a square connectivity array containing zeros and ones. We say that point \(i\) has a connection to point \(j\) , or \(i\) is connected to \(j\) , if \(C [i , j ] = 1\). Note that connections in this context are one-directional, meaning \(C [i , j]\) is not necessarily the same as \(C [ j , i ]\). For example, think of a one-way street from point A to point B. If A is connected to B, then B is not necessarily connected to A.

Write a function *my_connectivity_mat_2_dict(C, names)*, where *C* is a connectivity array and *names* is a list of strings that denote the name of a point. That is, *names[i]* is the name of the name of the *i-th* point.

The output variable *node* should be a dict with the key as the string in *names* and value is a vector containing the indices, j, such that \(C[i,j] = 1\). In other words, it is a list of points that point i is connected to.

```
def my_connectivity_mat_2_dict(C, names):
# write your function code here
return node
```

```
C = [[0, 1, 0, 1], [1, 0, 0, 1], [0, 0, 0, 1], [1, 1, 1, 0]]
names = ['Los Angeles', 'New York', 'Miami', 'Dallas']
```

```
# Output: node['Los Angeles'] = [2, 4]
# node['New York'] = [1, 4]
# node['Miami'] = [4]
# node['Dallas'] = [1, 2, 3]
node = my_connectivity_mat_2_dict(C, names)
```

Turn the list

*words*of lower case characters to upper case using list comprehension.

```
words = ['test', 'data', 'analyze']
```

< 5.3 Comprehensions | Contents | 6.0 Recursion >