πŸ““ About This Tutorial

This webpage is a static view of an interactive Jupyter Notebook tutorial. To get the full interactive experience where you can run Python code, modify examples and complete exercises, click the "Open in Colab" button. This will access the Google Colab notebook from a GitHub repository github.com/dchappell2/Computational-Physics and open it in Google Colab. You will need a Google account if you want to open it in Colab.

Note: You can download a pdf of the lecture slides for this chapter here: Chapter 0-3 slides

Chapter 9 - Functions

Goals:

9.0 Break programs down into functions to make them easier to understand.

For example, you might design a program that does data analysis into functional parts:

Each of these could be their own function (or multiple functions)

9.1 - Define a function using def

Here's an example:

def print_greeting():
    print('Hello!')

9.2 Defining a function does not run it.

print_greeting()

9.3 Arguments in the calling function are matched to the parameters in the definition.

πŸ”† print_date() function

In this example, we define a function to print a date in MM/DD/YYYY format

Run the code to see the output:

def print_date(year, month, day):
    print(f'{month}/{day}/{year}')

print_date(1871, 3, 19)
print_date(month=3, day=19, year=1871)

βœ… Skill Check 1

Write a function that prints an ASCII cat face: =^.^=

# your code here

9.4 Arguments can have default values

πŸ”† Example: weight() function

This example calculates the weight of an object (in Newtons) given the object's mass.

def weight(m,g=9.8):
    return m*g

# weight of a 100 kg mass on Earth
# value of g is not specified (default is used)
# only the mass is passed to the weight() function
W = weight(100)
print(f"weight on Earth = {W:.0f} Newtons")

# weight of a 100 kg mass on the Moon (where g = 1.62 m/s^2)
# both the mass and the value of g are passed to the function
# you could also call the function like this:  weight(100,1.62) without specifying "g="
W = weight(100,g=1.62)
print(f"weight on Moon = {W:.0f} Newtons")

9.5 Functions may return a result using the return command.

πŸ”† Example: Kinetic Energy

# define a function to calculate the kinetic energy
# given the mass m and velocity v
#
def KE(m,v):
    return 1.5 * m * v**2

m = 100           # mass in kg
v = 10            # velocity in m/s
my_KE = KE(m,v)   # calculate kinetic energy

print(f'Kinetic energy = {my_KE}')

βœ… Skill Check 2

Once a function is defined, it can be used as many times as you want.

# your code here

βœ… Skill Check 3

Write a function the calculates and returns the equivalent resistance of two resistors wired in parallel: $\frac{1}{R_{eq}}=\frac{1}{R_1} + \frac{1}{R_1}$.

# your code here

9.6 Write functions robustly, so they can handle all the ways a user might use them

πŸ”† Average() function

def average(values):
    if len(values) == 0:              # check to see if passed array is empty
        return None
    return sum(values) / len(values)

print('average of empty list:', average([]))

9.7 Use functions to modularize your code

It is tempting to just start writing the final version of your code that does everything you want. However experience suggests that (for all except the simplest programs) it is better to break your code into pieces and test each piece before combining them together into your final program.

Here's an example that shows how a function can help simplify code:

πŸ”† Example: Spring Force

The function spring_force() calculates the force in 3D space applied by a spring with spring constant k. In vector form, the spring force is given by

$\vec{F}=-k(\vec{r}-\vec{r}_0)$.

Passed parameters:

Returned array:

import numpy as np

def spring_force(r,r0,k):
    d = r-r0                 # vector displacement of spring (r0 to r)
    F = -k*d                 # vector force acting on point r
    return F

r  = np.array([1,1,0])       # 3D position of end of spring
r0 = np.array([0,0,0])       # 3D position where spring is anchored
k  = 2                       # spring force

F0 = spring_force(r,r0,k)    # calculate and print the spring force
print("force = ",F0)

Running this code shows that the spring pulls the free end, down and to the left (both x and y are negative).

We can now use our spring function to add a second spring at (2,0,0) and calculate the net force.


# Calculate force from a second spring
F1 = spring_force(r,[2,0,0],k)

# add the two spring forces to get net force
Fnet = F0 + F1

print("first force  = ",F1)
print("second force = ",F1)
print("net force    = ",Fnet)

βœ… Skill Check 4

βœ… Skill Check 5

Write a function to calculate and return the electric field at position r given a point charge q at position r0. Assume r and r0 are NumPy arrays, each with length 3 whose elements are the x, y, z components. Hint: a convient way of writing the electric field from a point charge is

$\vec{E} = \frac{1}{4 \pi \epsilon_0} \frac{\vec{r}-\vec{r}_0}{|\vec{r}-\vec{r}_0|^3}$.

Passed parameters:

Returned values:

Test your function with the following passed parameters:

print the electric field vector.

#  Your code here

βœ… SKill Check 6

Use the electric field function defined is Skill Check 5 to calculate the electric field from a dipole, made of the following two charges:

Calculate the field at the following locations and print the results:

a) $\vec{r} = (10m,0,0)$

b) $\vec{r} = (10m,0,10m)$

c) $\vec{r} = (0,0,10m)$

d) $\vec{r} = (0,0,-10m)$

Do your results make sense?

βœ… Skill Check 7

Write a function that generates a noisy sine wave. Here are the specs:

Passed parameters:

Returned values:

The noisy sine wave can be written as $y = B z_{norm} + A\sin(2\pi t/ P)$, where

The signal-to-noise ratio (SNR) is given by $SNR = A/B$. Since both $A$ and $SNR$ are specified as passed parameters, you will need to calculate $B$ using this formula.

Comments have been created describing how to use the noisy_sin() function.

Run your code (with the verbose flag = True) for the following parameter combinations:

import numpy as np

# noisy_sin() function returns a noisy sine wave
#
# passed parameters:
#    SNR     = signal-to-noise ratio
#    N       = number of data points
#    tmax    = maximum time
#    P       = period of sine wave
#    A       = amplitude of sine wave
#    verbose = flag to print statistics about the generated wave
#
# returned parameters:
#    data    = 2D array where: column 1 = time values,
#                              column 2 = noise sine wave values
#


# your code here

Key Points

This tutorial is an adaptation of "Python for Physicists"

Β© Software Carpentry