# 12.16. Exercises¶

1. Write a function named num_test that takes a number as input. If the number is greater than 10, the function should return “Greater than 10.” If the number is less than 10, the function should return “Less than 10.” If the number is equal to 10, the function should return “Equal to 10.”

2. Write a function that will return the number of digits in an integer.

3. Write a function that reverses its string argument.

4. Write a function that mirrors its string argument, generating a string containing the original string and the string backwards.

5. Write a function that removes all occurrences of a given letter from a string.

6. Although Python provides us with many list methods, it is good practice and very instructive to think about how they are implemented. Implement a Python function that works like the following:

1. count

2. in

3. reverse

4. index

5. insert

7. Write a function replace(s, old, new) that replaces all occurences of old with new in a string s:

test(replace('Mississippi', 'i', 'I'), 'MIssIssIppI')

s = 'I love spom!  Spom is my favorite food.  Spom, spom, spom, yum!'
test(replace(s, 'om', 'am'),
'I love spam!  Spam is my favorite food.  Spam, spam, spam, yum!')

test(replace(s, 'o', 'a'),
'I lave spam!  Spam is my favarite faad.  Spam, spam, spam, yum!')


Hint: use the split and join methods.

8. Write a Python function that will take a the list of 100 random integers between 0 and 1000 and return the maximum value. (Note: there is a builtin function named max but pretend you cannot use it.)

9. Write a function sum_of_squares(xs) that computes the sum of the squares of the numbers in the list xs. For example, sum_of_squares([2, 3, 4]) should return 4+9+16 which is 29:

10. Write a function to count how many odd numbers are in a list.

11. Sum up all the even numbers in a list.

12. Sum up all the negative numbers in a list.

13. Write a function findHypot. The function will be given the length of two sides of a right-angled triangle and it should return the length of the hypotenuse. (Hint: x ** 0.5 will return the square root, or use sqrt from the math module)

14. Write a function called is_even(n) that takes an integer as an argument and returns True if the argument is an even number and False if it is odd.

15. Now write the function is_odd(n) that returns True when n is odd and False otherwise.

16. Write a function is_rightangled which, given the length of three sides of a triangle, will determine whether the triangle is right-angled. Assume that the third argument to the function is always the longest side. It will return True if the triangle is right-angled, or False otherwise.

Hint: floating point arithmetic is not always exactly accurate, so it is not safe to test floating point numbers for equality. If a good programmer wants to know whether x is equal or close enough to y, they would probably code it up as

if  abs(x - y) < 0.001:      # if x is approximately equal to y
...


## 12.16.1. Contributed Exercises¶

Define a function called draw(turtle, shape, length). If shape is “square”, use turtle to draw a square with side equal to length. If shape is “triangle”, draw an equilateral triangle with side equal to length. Otherwise, draw nothing. The turtle should face in the same position after draw is done. The function may return whatever you like. Example usage: draw(myturtle, "triangle", 20).
Define a function square_list(list) which takes in a list of numbers, and returns a list of the squares of those numbers. Example: square_list([1,5,3]) should return [1,25,9].
Use the functions square_list and graph to draw the graph of a parabola: that is, [1,2,3,4] on the x axis, and [1,4,9,16] on the y axis.
Define a function first_letters(sentence) which takes in a string, and counts the number of words that begin with each letter of the alphabet. The function should return a dictionary. Example: first_letters(“she sold six buns today”) should return {‘s’: 3, ‘b’: 1, ‘t’: 1}. Bonus if your program returns the same result for first_letters("She sold six buns today.")
Define a function graph(x_list,y_list) which takes two lists and uses Altair to make a point graph of the x_list versus the y_list.
Define a function graph(x_list,y_list) which takes two lists and uses Altair to make a point graph of the x_list versus the y_list.

Q-1: After completing the reading, what concepts are still unclear to you? If nothing is unclear, what did you find most interesting?

Implement a function called pow_answer that has 2 parameters, base and exponent. The function computes the value of the base to the power of the exponent. It then returns a friendly answer For example, calling pow_answer(2, 3) returns: Value of 2 to the power of 3 is 8

Write a function named generate_odd_numbers that will generate a list containing every odd number between 0 and a number specified by the user, excluding the user-specified number. The function must return the generated list.

Write a function named average_odd_list that will return the average of the odd numbers between 0 and a number specified by the user, excluding the user-specified number. The function must return the average.

The average_odd_list function must make use of the generate_odd_numbers function from the wvu_functions_createlist question. You may copy-and-paste the source code for that function here.

Variance can be calculated as (∑(x−x̄)²)/n, where is the average of all x and n is the count of how many x there are.

Standard deviation is the square root of variance.

Write a function named variance that will return the variance of a list. Write a second function named stdev that will return the standard deviation of a list.

Write a function findHypot. The function will be given the length of two sides of a right-angled triangle and it should return the length of the hypotenuse. (Hint: x ** 0.5 will return the square root, or use sqrt from the math module)

Write a Python function called largest that will take a the list of integers between 0 and 1000 and return the maximum value. (Note: there is a builtin function named max but pretend you cannot use it. In fact, don’t use the name max anywhere in you code.)

Write a function named num_test that takes a number as input. If the number is greater than 10, the function should return “Greater than 10.” If the number is less than 10, the function should return “Less than 10.” If the number is equal to 10, the function should return “Equal to 10.”

Write a function to implement the trapezoidal method,

$\int_a^b f(x)\, dx \approx \Delta x \left( \frac{f(a) + f(b)}{2} + \sum_{k=1}^{N-1} f(x_k)\right),$

where $$a$$ and $$b$$ are the lower and upper bounds of the integral, $$f(x)$$ is the integrand, $$N$$ is the number of points that the integrand is evaluated at, and $$\Delta x$$ is the interval between evaluation points.

Your function should be called int_trapz and should take as parameters the integrand, lower and upper bounds, and the number of evaluation points. It should return the estimated value of the integral.

Use your function to evaluate the integral

$\int_{-1}^3 x^3\, dx$

using 101 evaluation points and print out the result.

Hint: use your and pow3 functions from a previous problem.

Write a function call pow3 that takes a parameter x and returns float according to

$f(x) = x^3$

Using your function, print out values for $$x=-1.5, 0, 2.1$$.

Write a function call linspace that returns $$N$$ evenly spaced values between two points $$a$$ and $$b$$ inclusive. Your function should take parameters a, b, and N and return a list of length N.

Using your function, print out the sequence

[-5. , -4.5, -4. , -3.5, -3. , -2.5, -2. , -1.5, -1. , -0.5,  0. ,
0.5,  1. ,  1.5,  2. ,  2.5,  3. ,  3.5,  4. ,  4.5,  5. ]


Functions are also objects. This means that we can pass function object as a parameter to another function. For example, we will create a function that applies another function to each element of a list. This function looks like:

def apply_to_each(func, lst_in):
lst_out = []
for elem in lst_in:
lst_out.append(func(elem))
return lst_out


We can then specify a list and a function to apply to it:

nums = [1, 2, 3]

def square(x):
return x**2


Finally, we can apply square to each element of nums.

print( apply_to_each(square, nums) )


Notice that there are no arguments or parentheses for square; we are pass it as an object. The output is then

[1, 4, 9]


Create a function call eval_delta that returns the values from a function evaluated at x - dx, x, x+dx. It should take the function name, x, and dx as parameters and return a tuple of the three values. The function definition is provided for you.

Use this to evaluate square at 0.5, 1, 1.5 and print out the results.

Write a function called transpose that takes any matrix and returns its transpose without changing the input. Use your function to assign the transpose of mat_a and mat_b to mat_at and mat_bt.

Hint: use your solution from a previous exercise to get started.

Write a function called l2_norm that takes a vector (list) of any length as input and returns the $$L^{2}\text{-norm}$$ without modifying the input. Use your function to compute and print out the $$L^{2}\text{-norm}$$ of the vectors defined below.

Hint: use your solution from a previous exercise to get started.

The energy levels of the hydrogen atom are given by the equation

$E_{n}=-\frac{2 e^{4}m_{e}}{\left(4\epsilon_{0}h\right)^{2}}\left(\frac{1}{n^{2}}\right)\quad n=1,2,3,\dots$

where $$m_{e}=9.109381\times10^{-31}\text{ kg}$$ is the electron mass, $$e=1.602176\times10^{-19}\text{ C}$$ is the elementary charge, $$\epsilon_{0}=8.854187817\times10^{-12}\text{ F/m}$$ is the permittivity of free space, $$h=6.626068\times10^{-34}\text{J}\cdot\text{s}$$ is Planck’s constant, and $$n$$ is the quantum number.

Write a function called h_atom_ene that takes the quantum number as a parameter and returns the energy in units of electron volts, where

$1\text{ eV} = 1.602176\times10^{-19}\text{ J}.$

The Lorentzian function is often used to fit frequency spectra. It is given by

$L\left(p\right)=\frac{1}{1+\left(\frac{p^{0}-p}{w/2}\right)^{2}}$

where $$p$$ is the frequency, $$p^0$$ is the frequency of maximum intensity, and $$w$$ is the full width at half maximum.

Write a function called lorzentian that takes parameters freq ($$p$$), freq_max ($$p^0$$), and width ($$w$$) and returns the value of the Lorentzian function as a float.

Print the results of your function for

freq=0.5,  freq_max=0,   width=1
freq=-0.5, freq_max=0,   width=1
freq=0.5,  freq_max=0.5, width=1
freq=0.5,  freq_max=0,   width=2
freq=-0.5, freq_max=0.5, width=2


Write a function called matmul that takes any two matrices and returns their matrix multiplication without changing either one.

To test your code, use the two $$3\times3$$ matrices, mat1 and mat2, defined for you. If your code is correct, your function should return

[[0.86814005, 0.88635532],
[0.6728074 , 1.0937629 ]]


Hint: use your solution from a previous exercise to get started.

Write a function called count_list that reproduces the count method without using the count. That is it takes a list and an object as parameters and returns the number of times the object occurs in the list.

Write a function called in_list that reproduces the in operator without using the in operator. That is it takes a list and an object as parameters and returns True if the object is in the list and False otherwise.

The normalized Gaussian function has the form

$g\left(x\right)=\frac{1}{\sigma\sqrt{2\pi}}\exp\left(-\frac{1}{2}\left(\frac{x-\mu}{\sigma}\right)^{2}\right)$

where $$\sigma$$ is the standard deviation and $$\mu$$ is the mean.

Write a function call gaussian that takes x, mean, and stdev as parameters and returns a float. mean and stdev should be optional parameters with default values of 1.0.

Print the results of your function for

x=0.5,  mean=0,   stdev=1
x=-0.5, mean=0,   stdev=1
x=0.5,  mean=0.5, stdev=1
x=0.5,  mean=0,   stdev=2
x=-0.5, mean=0.5, stdev=2


Write a function called add_2x than takes a list of numbers and adds 2 times the last number to the end. The function should not return anything. Instead, it should modify the list in-place.

E.g., for input list

lst = [4, 5, 6]


the list

[4, 5, 6, 12]


Consider the expression for radioactive decay

$\frac{dN}{dt} = -\lambda N$

where $$N$$ is the number of particles, $$t$$ is time and $$\lambda$$ is a decay constant. If we have a value for the number of particles at the current time, $$N(t)$$, we can calculate the number of particles at $$\Delta t$$ in the future from

$N(t+\Delta t) = N(t) + \frac{dN}{dt}\Delta t = N(t) -\lambda N(t) \Delta t$

Write a function call decay that takes a list of the number of particles a previous times, the decay constant, decay_const, the time step delta_t, and the number of time steps, nsteps. It should update the input list by using the last value in the list as the current number of particles and appending a new value for each time step.

E.g., the function call

decay( [10], 2, .01, 5)


we expect the output

[10, 9.8, 9.604, 9.41192, 9.2236816, 9.039207968]


For

decay( [100, 200, 300], 2, .01, 5)


we expect the output

[100, 200, 300, 294.0, 288.12, 282.3576, 276.710448, 271.17623904]


since 100 and 200 are not used.

Note: the approach we are using here is called the Euler method. There are much better methods for integrating ordinary differential equation initial values problems but they all use the same basic approach of iteratively updating from an initial value.

Write a function to compute the value of a mathematical function midway between two points. E.g., for

$f(x) = (x-1)^2$

and point $$a=1$$ and $$b=3$$, the result is

$f\left(\frac{a+b}{2}\right) = 1$

Your function should be called midpoint and take a function and two floats as input parameters.

A root of a mathematical function is input value (or values) for which the function evaluates to zero. For example,

$f(x) = x^2 -1$

has roots at $$x=1$$ and $$-1$$.

Often, we don’t know the exact values of the root but we might know that it lies is some range of $$x$$ values. In this case, we can find an approximation of the root using the bisection method.

1. Set err to the acceptable error.

2. Set maxstep to a large number, say 1000.

3. Guess a low and a high value for the root where $$f(\mathtt{low})<0$$ and $$f(\mathtt{high})>0$$. These must bracket a single root. For $$f(x) = x^2 -1$$, suitable brackets are 0 and 5 for the $$x=1$$ root and 0.5 and -4 for the $$x=-1$$ root. A bracket of -4 and 5 is not suitable because it brackets two roots and $$f(-4)>0$$ and $$f(5)>0$$. Brackets are just guesses and don’t need to be exact.

4. Check that $$f(\mathtt{low})<f(\mathtt{high})$$. If not, swap low and high.

5. For maxsteps iterations:

1. Set mid to (high+low)/2.

2. If $$|f(\mathtt{mid})|>err$$

1. If $$f(\mathtt{mid})>0$$, then replace high with mid.

2. else replace low with mid.

3. Set mid to (high+low)/2.

4. Continue iterating.

3. else return mid as the approximate root.

6. If you get to this step, your function did not find a good enough approximation of the root. It should return None, which is the same a not having a return statement at all in Python.

Implement the bisection method by completing the function below. Test it by finding both roots of $$f(x)$$ above.

Write a function called order to compute the value of a mathematical function at two points, low and high. If $$f(\mathtt{low}) < f(\mathtt{high})$$, then return the tuple (low, high). If $$f(\mathtt{low}) > f(\mathtt{high})$$, then swap low and high and return the tuple (low, high).

E.g., for the math function

$f(x) = -2x+3$
def line(x):
return -2*x+3


the function could be called as

order(line, 1, 10)


and would return (10, 1). If it was instead called as

order(line, 10, 1)


it would also return (10, 1) as $$f(10)< f(1)$$.

Write a function lettercount that accepts a list and a letter. The function should return a new list with all the words in the original list that have the letter in them with a dash and the number of times that letter is in the word. For example lettercount([‘cat’,’dog’,’parakeet’,’turtle’],’t’) should return [‘cat-1’,’parakeet-1’,’turtle-2’]. Use append to add to your list.

Create a function cleanup that accepts a string makes it all lower case and breaks the string into a list at the commas, it should then strip any leading/trailing white space out of each list element, and convert any string in the list with only numbers (and periods) into a float.

Write a function sortandseperate that takes a list with mixed type and divides it into sub lists by type. A list with sorted strings and a list with sorted numbers, and a list of lists (don’t need to sort…). For example [‘rat’,8,’dog’,10,11,[5],3,[‘cat’]] would become [[‘dog’,’rat’],[3,8,10,11],[[5],[‘cat’]].

The taylor series expansion for $$e^x$$ is

$1 + \frac{x^1}{1!} + \frac{x^2}{2!} + \frac{x^3}{3!} + ...$

Start by grabbing your factorial code from Classwork 3, and turning it into a function called factorial which returns the value of the factorial. Then create a function taylorterm that accepts an integer $$a$$ and the value of $$x$$ and returns the result of an individual taylor fraction. In other words

$\frac{x^a}{factorial(a)}$

Use a for loop and concatenation to make a list with each term of the taylor series. This should be a function called taylorlist that should take the value of x and max value of a as inputs. So $$x=3$$ and $$a=2$$ would get

$[1 , taylorterm(3,1) , taylorterm(3,2)] = [1 , 3 , 4.5]$

Lastly create a function taylorex that returns the taylor series result this should accept an $$x$$ and an $$a$$ and sum the result from the taylorlist. So $$x=3$$ and $$a=2$$ would get 8.5.

Write a function separate_types that takes a list with mixed type and divides it into sub lists by type. A list with sorted strings and a list with sorted numbers, and a list of lists (don’t need to sort…). For example [‘rat’,8,’dog’,10,11,[5],3,[‘cat’]] would become [[‘dog’,’rat’],[3,8,10,11],[[5],[‘cat’]].