scipy.constants
¶A lot of the expressions that describe chemical phenomena involve physical constants, such as the speed of light, $c$, Avogadro's constant, $N_\mathrm{A}$, Planck's constant, $h$, and the Boltzmann constant, $k$. When working with algebraic expressions, it is also important to keep track of the relevant units. Different experiments may conventionally report data in non-S.I. units, and these units must be converted for comparing data or calculating chemical properties.
While manipulating units manually (for example, when working through a problem by hand) is an important skill, if you are solving numerical problems using code you ideally want to avoid typing in unit conversions and values for constants. Any numbers that are typed in, are possible places where you could mistype. Mistakes in your code can hopefully be spotted when they produce errors, or from testing that your code produces a known result. Mistakes in numbers typed in are harder to spot, and can propogate through to your results.
To reduce the chance of introducing errors, there are two easy techniques you can follow:
Q. The equations for the circumference and area of a circle are: \begin{equation} c =2\pi r, \end{equation} \begin{equation} A=\pi r^2. \end{equation} Calculate the circumference and area of a circle with radius 5.0 cm. Give your results to 3 decimal places.
circumference = 2.0 * 3.1415 * 5.0
area = 3.1415 * 5.0**2
print( "circumference = {:.3f} cm".format( circumference ) )
print( "area = {:.3f} cm^2".format( area ) )
circumference = 31.415 cm area = 78.538 cm^2
r = 5.0 # radius in cm.
pi = 3.1415 # pi to 4 d.p.
circumference = 2.0 * pi * r
area = pi * r**2
print( "circumference = {:.3f} cm".format( circumference ) )
print( "area = {:.3f} cm^2".format( area ) )
circumference = 31.415 cm area = 78.538 cm^2
This approach has two advantages over the first. The variables r
and pi
are clearly defined at the top of the code, and are then referred to by their variable names in the actual calculations. We can be sure that the same values of r
and pi
are used in both calculations, and it is a lot clearer where these numbers come from. By dividing up the code like this, it is also easier to understand. The actual calculations now look like the expressions in the question, and it is clearer to someone reading the code what is happening.
Instead of typing in the value of $\pi$, you can import
it from the math
module.
from math import pi
print( 'pi = {}'.format(pi) )
pi = 3.141592653589793
This means you never have to worry about mistyping the numerical value. You also get a more accurate value. Notice that in the previous examples, the last decimal place was incorrectly rounded to give 3.1415
and not 3.1416
, and this rounding error propagates through to the calculated answers.
from math import pi
# question inputs
r = 5.0 # radius in cm
circumference = 2.0 * pi * r
area = pi * r**2
print( "circumference = {:.3f} cm".format( circumference ) )
print( "area = {:.3f} cm^2".format( area ) )
circumference = 31.416 cm area = 78.540 cm^2
scipy.constants
¶The math
module contains various mathematical constants, such as $\pi$ and $\mathrm{e}$ (the natural logarithm). For physical constants you can use the scipy.constants
module: https://docs.scipy.org/doc/scipy/reference/constants.html
Common physical constants can be imported directly, e.g.
from scipy.constants import c # speed of light
from scipy.constants import h # Planck's constant
from scipy.constants import k # Boltzmann constant
print( 'c = {} m s^-1'.format( c ) )
print( 'h = {} J s'.format( h ) )
print( 'k = {} J K^-1'.format( k ) )
c = 299792458.0 m s^-1 h = 6.62607004e-34 J s k = 1.38064852e-23 J K^-1
scipy.constants
also contains a physical_constants
database (as a Python dictionary) that contains an even larger number of constants, and also gives their units.
from scipy.constants import physical_constants
print( physical_constants['speed of light in vacuum'] )
print( physical_constants['Planck constant'] )
print( physical_constants['Boltzmann constant'] )
(299792458.0, 'm s^-1', 0.0) (6.62607004e-34, 'J s', 8.1e-42) (1.38064852e-23, 'J K^-1', 7.9e-30)
Each entry in the dictionary returns three components: the value, the units (as a string), and the experimental uncertainty.
The following are example tutorial questions (that will probably be familiar) that involve working with different units, that illustrate using the approaches described above.
Q The pressure at the top of a mountain is one-third of an atmosphere. Calculate the pressure in S.I. units and in bar.
from scipy.constants import atm, bar # 1 atm and 1 bar in SI units (Pascals).
print( "standard atmosphere in Pa: {}".format( atm ) )
print( "one bar in Pa: {}".format( bar ) )
standard atmosphere in Pa: 101325.0 one bar in Pa: 100000.0
pressure_in_atm = 1/3
pressure_in_Pa = pressure_in_atm * atm
pressure_in_bar = pressure_in_Pa / bar
print( "pressure in S.I. units (Pa) = {}".format( pressure_in_Pa ) )
print( "pressure in bar = {}".format( pressure_in_bar ) )
pressure in S.I. units (Pa) = 33775.0 pressure in bar = 0.33775
Q A sample of Neon of mass 255 mg occupies 3.0 L at 122 K. What pressure does it exert if it acts ideally?
A. Answering this question relies on using the ideal gas equation:
\begin{equation} pV = nRT \end{equation}which can be rearranged to give \begin{equation} p = \frac{nRT}{V} \end{equation}
The question gives us the volume and temperature. The number of moles of gas can be calculated from the total mass, and from knowing what the sample is made of.
NOTE The mendeleev
module is not a standard part of Anaconda, and is not necessarily available to you without instalation. If the import mendeleev
line gives an error, you can comment this out, and manually store the mass of Ne in a variable.
from scipy.constants import R # molar gas constant
import mendeleev
molar_mass_of_Ne = mendeleev.element('Ne').mass
# If these lines give an error, you probably do not have the mendeleev module installed.
# If this is the case, comment out the two lines above, and uncomment the line below
# molar_mass_of_Ne = 20.1797
total_mass = 255e-3 # mass in g
volume = 3.0e-3 # volume in m^3
temperature = 122.0 # temperature in K
n_moles_of_Ne = total_mass / molar_mass_of_Ne
pressure = n_moles_of_Ne * R * temperature / volume
print( 'pressure =', pressure )
pressure = 4272.657577962012
Q The atomic radius of a helium atom has been reported as 140 pm. Convert this to Angstroms and into SI units. What, in SI units, is the volume occupied by the atom?
A scipy.constants
also contains conversion factors for SI prefixes (such as “pico”), which can be used to give clearer code
from scipy.constants import pico, angstrom
r = 140 # atomic radius in pm
atomic_radius_in_m = 140 * pico # SI units
atomic_radius_in_angstroms = r / angstrom # Angstroms
print( "atomic radius in Angstroms: {:.2e}".format( atomic_radius_in_angstroms ) )
print( "atomic radius in SI units (m): {:.2e}".format( atomic_radius_in_m ) )
atomic radius in Angstroms: 1.40e+12 atomic radius in SI units (m): 1.40e-10
Approximate the atomic volume as a sphere with radius $r$.
\begin{equation} V_\mathrm{sphere}(r) = \frac{4}{3}\pi r^3. \end{equation}from math import pi
volume = 4.0/3.0 * pi * atomic_radius_in_m**3 # calculate the volume in SI units (m^3)
print( "volume = {:.2e} m^3".format( volume ) )
volume = 1.15e-29 m^3