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
Goals:
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)
defdef.def comes the name of the function. Function names follow the same rules as variable names (only letters, numbers and underscores; no spaces)Here's an example:
def print_greeting():
print('Hello!')
print_greeting function is made by simmply typing the function name followed by a pair of parentheses:print_greeting()
In this example, we define a function to print a date in MM/DD/YYYY format
(year, month, day) in the function definition.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)
Write a function that prints an ASCII cat face: =^.^=
cat() or print_cat(), etc.# your code here
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")
return command.return to give a value back to the caller.return command can occur anywhere in the function, but..# 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}')
Once a function is defined, it can be used as many times as you want.
KE() function to calculate the kinetic energy of a particle with mass 2 kg and a velocity 5 m/s.# your code here
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
average() function threw an error if we passed it an empty array.None if it is.None instead of a numeric valuedef 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([]))
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:
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:
r0 = NumPy array containing x, y, z components of position where the spring is anchoredr = NumPy array containing x, y, z components of the other end of the spring (where the force is calculated)k = spring constantReturned array:
F = NumPy array containing x, y, z components of the force exerted by the springimport 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)
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:
r = NumPy array (length 3) containing x, y, z componentsr0 = NumPy array (length 3) containing x, y, z components of the point chargeq0 = charge of the point chargeReturned values:
E = electrostatic force vectorTest your function with the following passed parameters:
r = (10,0,2)r0 = (0,0,0)q0 = 1e-6print the electric field vector.
# Your code here
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?
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:
noisy_sin(1)``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
def statement, and the body is indentedreturn statementThis tutorial is an adaptation of "Python for Physicists"