import numpy as npModuleNotFoundError: No module named 'numpy'
Module 3: NumPy
When light moves from one medium to another, its path bends. This phenomenon is called refraction. Snell’s law relates the angle of incidence \(\theta_1\) to the angle of refraction \(\theta_2\):
\[ n_1 \sin(\theta_1) = n_2 \sin(\theta_2), \]
where \(n_1\) and \(n_2\) are the refractive indices of the two media. Air has a refractive index close to 1, while water has a refractive index close to 1.33.
In this application, you will use vectorized trigonometric functions and descriptive statistics to estimate the refractive index of an unknown material.
import numpy as npModuleNotFoundError: No module named 'numpy'
Each row contains an incidence angle followed by its corresponding refraction angle. Both are measured in degrees.
# Columns: theta_1, theta_2
angles = np.array([
[30, 18],
[32, 19],
[34, 21],
[36, 22],
[38, 23],
[40, 24],
[42, 25],
[44, 26],
[46, 27],
[48, 28],
[50, 29],
[52, 30],
[54, 31],
[56, 32],
[58, 33],
[60, 33]
], dtype=float)
print(angles.shape)NameError: name 'np' is not defined
Write a function named index_of_refraction(theta_1, theta_2) that accepts two arrays of angles in degrees and returns
\[ \frac{\sin(\theta_1)}{\sin(\theta_2)}. \]
Remember that NumPy’s trigonometric functions expect radians.
Write a function named mean_and_std(values) that returns the mean and population standard deviation in the format mean +/- standard deviation. Display both numbers with two decimal places.
For [1, 1.41, 1.22], the result should be 1.21 +/- 0.17.
Write a function named estimate_index(angles_2d, n_1=1.0) that:
index_of_refraction();mean_and_std(); andEstimate the unknown material first with air as the initial medium and then with water, using n_1=1.33.
def index_of_refraction(
theta_1: np.ndarray,
theta_2: np.ndarray
) -> np.ndarray:
"""Return sin(theta_1) / sin(theta_2) for angles in degrees."""
theta_1_rad = np.radians(theta_1)
theta_2_rad = np.radians(theta_2)
return np.sin(theta_1_rad) / np.sin(theta_2_rad)
def mean_and_std(values: np.ndarray) -> str:
"""Format the mean and population standard deviation."""
mean = np.mean(values)
standard_deviation = np.std(values)
return f"{mean:.2f} +/- {standard_deviation:.2f}"
def estimate_index(angles_2d: np.ndarray, n_1: float = 1.0) -> str:
"""Estimate the refractive index of the second medium."""
incidence_angles = angles_2d[:, 0]
refracted_angles = angles_2d[:, 1]
relative_indices = index_of_refraction(
incidence_angles,
refracted_angles
)
n_2_values = n_1 * relative_indices
return mean_and_std(n_2_values)
print("From air:", estimate_index(angles))
print("From water:", estimate_index(angles, n_1=1.33))NameError: name 'np' is not defined
This application combines two-dimensional slicing, degree-to-radian conversion, vectorized trigonometric functions, and statistical aggregation.
Explain why the angles must be converted to radians before calling np.sin(). Then describe how measurement variability appears in the reported result.