../_images/book_cover.jpg

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!

< 3.5 Functions as Arguments to Functions | Contents | CHAPTER 4. Branching Statements >

Summary

  1. A function is a self-contained set of instructions designed to do a specific task.

  2. A function has its own memory block for its variables.Information can be added to a function’s memory block only through a function’s input variables. Information can leave the function’s memory block only through a function’s output variables.

  3. A function can be defined within another function, called nested function. This nested function can be only accessed by the parent function.

  4. You can define anonymous function using keyword lambda, the so called lambda function.

  5. You can assign functions to variables using function handles.

Problems

  1. Recall that the hyperbolic sine, denoted by \(\sinh\), is \(\frac{\exp{(x)} - \exp{(-x)}}{2}\). Write a function \(my\_sinh(x)\), where the output \(y\) is the hyperbolic sine computed on \(x\). Assume that x is a 1 by 1 float.

Test Cases:

In: my_sinh(0)
Out: 0
   
In: my_sinh(1)
Out: 1.1752
   
In: my_sinh(2)
Out: 3.6269
  1. Write a function \(my\_checker\_board(n)\), where the output \(m\) is an \(n\times n\) array with the following form:

    \[\begin{split} m =\begin{array}{ccccc} 1 & 0 & 1 & 0 & 1\\ 0 & 1 & 0 & 1 & 0\\ 1 & 0 & 1 & 0 & 1\\ 0 & 1 & 0 & 1 & 0\\ 1 & 0 & 1 & 0 & 1 \end{array} \end{split}\]

Note that the upper-left element should always be 1. Assume that n is a strictly positive integer.

Test Cases:

In: my_checker_board(1)
Out: 1
   
In: my_checker_board(2)
Out: array([[1, 0],
            [0, 1]])
   
In: y = my_sinh(3)
Out: array([[1, 0, 1],
            [0, 1, 0], 
            [1, 0, 1]])
   
In: y = my_sinh(5)
Out: array([[1, 0, 1, 0, 1],
            [0, 1, 0, 1, 0], 
            [1, 0, 1, 0, 1], 
            [0, 1, 0, 1, 0], 
            [1, 0, 1, 0, 1]])
  1. Write a function \(my\_triangle(b,h)\) where the output is the area of a triangle with base, b, and height, h. Recall that the area of a triangle is one-half the base times the height. Assume that b and h are just 1 by 1 float numbers.

Test Cases:

In: my_triangle(1, 1)
Out: 0.5

In: my_triangle(2, 1)
Out: 1
   
In: my_triangle(12, 5)
Out: 30
  1. Write a function \(my\_split\_matrix(m)\), where \(m\) is an array, the output is a list [m1, m2] where m1 is the left half of m, and m2 is the right half of m. In the case where there is an odd number of columns, the middle column should go to m1. Assume that m has at least two columns.

Test Cases:

 In: m = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])  
 In: m1, m2 = my_split_matrix(m)  
 Out: m1 = array([[1, 2],
                   [4, 5],
                   [7, 8]])  
 Out: m2 = array([3, 6, 9])
   
  
 In: m = np.ones((5, 5))
 In: m1, m2 = my_split_matrix(m) 
 Out: m1 = array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
 Out: m2 =  array([[1., 1.],
       [1., 1.],
       [1., 1.],
       [1., 1.],
       [1., 1.]])
   
  1. Write a function \(my\_cylinder(r,h)\), where r and h are the radius and height of a cylinder, respectively, and the output is a list [s, v] where s and v are the surface area and volume of the same cylinder, respectively. Recall that the surface area of a cylinder is \(2\pi r^2 + 2\pi rh\), and the volume is \(\pi r^2h\). Assume that r and h are 1 by 1 float.

Test Cases:

In: my_cylinder(1,5)
Out: [37.6991, 15.7080]

In: my_cylinder(2,4)
Out: [62.8319, 37.6991]
  1. Write a function \(my\_n\_odds(a)\), where a is a one-dimensional array of floats and the output is the number of odd numbers in a.

Test Cases:

In: my_n_odds(np.arange(100))
Out: 50

In: my_n_odds(np.arange(2, 100, 2))
Out: 0
  1. Write a function \(my\_twos(m,n)\), where the output is an \(m\times n\) array of twos. Assume that m and n are strictly positive integers.

Test Cases:

In: my_twos(3, 2)
Out: array([[2, 2],
      [2, 2],
      [2, 2]])

In: my_twos(1, 4)
Out: array([2, 2, 2, 2])
  1. Write a lambda function that takes in x and y, and output the value of x - y.

  2. Write a function \(add\_string(s1, s2)\), where the output is the concatenation of the strings s1 and s2.

Test Cases:

In: s1 = add_string('Programming', ' ')
In: s2 = add_string('is', 'fun!')
In: add_string(s1, s2)
Out: 'Programming is fun!'
  1. Generate the following errors:

    • TypeError: fun() missing 1 required positional argument: ‘a’

    • IndentationError: expected an indented block

  2. Write a function \(greeting(name, age)\), where name is a string, age is a float, and the output is a string ‘Hi, my name is XXX and I am XXX years old.’ where XXX are the input name and age, respectively.

Test Cases:

In: greeting('John', 26)
Out: 'Hi, my name is John and I am 26 years old.'

In: greeting('Kate', 19)
Out: 'Hi, my name is Kate and I am 19 years old.'
  1. Let r1 and r2 be the radius of circles with the same center and let r2>r1. Write a function my_donut_area(r1, r2), where the output is the area outside of the circle with radius r1 and inside the circle with radius r2. Make sure that the function is vectorized. Assume that r1 and r2 are one-dimensional array of the same size.

Test Cases:

In: my_donut_area(np.arange(1, 4), np.arange(2, 7, 2))
Out: array([9.4248, 37.6991, 84.8230])
  1. Write a function \(my\_within\_tolerance(A, a, tol)\), where the output is an array or list of the indices in A such that \(|A-a| < \text{tol}\). Assume that A is a one-dimensional float list or array and that a and tol are 1 by 1 floats.

Test Cases:

In: my_within_tolerance([0, 1, 2, 3], 1.5, 0.75)
Out: [1, 2]
   
In: my_within_tolerance(np.arange(0, 1.01, 0.01), 0.5, 0.03)
Out: [47, 48, 49, 50, 51, 52]
  1. Write a function \(bounding\_array(A, top, bottom)\), where the output is equal to the array A wherever bottom < A < top, the output is equal to bottom wherever A <= bottom, and the output is equal to top wherever A >= top. Assume that A is one-dimensional float array and that top and bottom are 1 by 1 floats.

Test Cases:

In: bounding_array(np.arange(-5, 6, 1), 3, -3)
Out: [-3, -3, -3, -2, -1, 0, 1, 2, 3, 3, 3]

< 3.5 Functions as Arguments to Functions | Contents | CHAPTER 4. Branching Statements >