Synoptic exercises

Synoptic exercises#

\(\require{mhchem}\)

Let’s see if your functions function.

1. There are several infinite series that converge to something proportional to \(\pi\). For example, the Basel series is defined as an infinite sum of reciprocal square numbers:

\[\frac{1}{1^{2}} + \frac{1}{2^{2}} + \frac{1}{3^{2}} + \cdots = \sum_{k=1}^{\infty} \frac{1}{k^{2}} = \frac{\pi^{2}}{6}.\]

a) Write a function to approximate \(\pi\) by evaluating the Basel series up to a given term \(n\). Test your function for \(n = 1000\).

b) Another infinite series that converges to something proportional to \(\pi\) is the Leibniz formula:

\[1 - \frac{1}{3} + \frac{1}{5} - \frac{1}{7} + \frac{1}{9} - \cdots = \sum_{k=0}^{\infty} \frac{(-1)^{k}}{2k + 1} = \frac{\pi}{4}.\]

Write a function to approximate \(\pi\) by evaluating the Leibniz formula up to a given term \(n\). Test your function for \(n = 1000\).

c) The accuracy of an approximate value of \(\pi\) is simply measured by calculating the absolute difference from the exact value:

\[|\pi - \pi_{\mathrm{approx}}|.\]

Write a function to evaluate the above expression and use this to determine which of your previous functions is more accurate when evaluated up to the \(50\)th term.

Reminder

You can access the exact value of \(\pi\) (up to a finite number of decimal places) via math.pi.

2. The distance between two points \(i\) and \(j\) in two-dimensional space can be calculated with the following equation:

\[d(i, j) = \sqrt{(x_{i} - x_{j})^{2} + (y_{i} - y_{j})^{2}},\]

where \(x_{i}\) is the \(x\)-coordinate of point \(i\), \(x_{j}\) is the \(x\)-coordinate of point \(j\) etc.

a) Write a function to calculate the distance between two points, where each point is a list of \(x\), \(y\) and \(z\) coordinates:

example_point_i = [0.1, 0.2]
example_point_j = [0.7, 0.5]

Test your function by calculating the distance between the example points above.

b) The atoms in a molecule of \(\ce{BF3}\) are located at the following coordinates:

bf3_coordinates = [[0.00, 0.00], 
                   [0.00, 1.30], 
                   [1.13, -0.65], 
                   [-1.13, -0.65]]

This is a nested list (a list of lists), where each sublist contains the coordinates associated with one atom.

Using loops, calculate and print the distances between all pairs of atoms in \(\ce{BF3}\). Use the function you wrote in a) to calculate each distance.

Hint

You will need a nested loop to generate all possible pairs of atoms.

c) Rather than using the print function to display all of your calculated distances, modify the code you wrote for b) so that the distances are instead used to build a distance matrix:

\[\begin{split}D = \begin{bmatrix} d_{11} & d_{12} & d_{13} & d_{14} \\ d_{21} & d_{22} & d_{23} & d_{24} \\ d_{31} & d_{32} & d_{33} & d_{34} \\ d_{41} & d_{42} & d_{43} & d_{44} \end{bmatrix},\end{split}\]

where \(d_{12}\) is the distance between atom \(1\) and atom \(2\), \(d_{14}\) is the distance between atoms \(1\) and \(4\) etc.

In Python, your final distance matrix should be a nested list:

[[d_11, d_12, d_13, d_14],
 [d_21, d_22, d_23, d_24],
 [d_31, d_32, d_33, d_34],
 [d_41, d_42, d_43, d_44]]

You can build up the matrix one row at a time using the loops you wrote in b).

3. Consider the following blocks of code. Each one of them will cause an error when run. Taking each block one-by-one:

  • Predict which line of code will cause the error and why this line is problematic.

  • Run the block of code in a Jupyter notebook and see whether or not your were correct.

  • Modify the code to solve the problem and thus remove the error.

Block 1:

def calculate_product(sequence):
    """
    Calculate the product of a sequence of numbers (n_1 * n_2 * n_3 * ...).

    Args:
        sequence (iterable): The sequence used to calculate the product.

    Returns:
        (float): The product.
    """

    product = sequence[0]

    for number in sequence[1:]:
        product *= number

    return product

product_of_sequence = calculate_product(5.12, 6.79, 2.22, 0.19, 13.6)

print(f'The cumulative product = {product_of_sequence}')

Block 2:

Note

This block also contains a problem which, whilst it will not cause an error, will lead to the wrong result. See if you can spot and fix this problem in addition to removing the error.

def check_palindrome(convert_to_smalls=False, word):
    """
    Check if a word is a palindrome.

    Args:
        word (str): The word to be checked.

    Returns:
        (bool): Whether or not the word is a palindrome.
    """

    if convert_to_smalls:
        word = word.lower() # Convert to small-case.

    if word == word[::-1]:
        check = True

    else:
        check = False

example_word = 'Civic'

if check_palindrome(example_word, convert_to_smalls=True):
    print(f'{example_word} is a palindrome.')

else:
    print(f'{example_word} is not a palindrome.')

Block 3:

import scipy

def harmonic_energy(v, nu):
    """
    Calculate the energy of a quantum harmonic oscillator.

    Args:
        v (int): Quantum number labelling each energy eigenstate.
        nu (float): Vibrational frequency of the oscillator.

    Returns:
        (float): The energy of the oscillator.
    """

    energy = (v + 0.5) * scipy.constants.hbar * nu

    return energy

frequency_HCl = 5.40e14

harmonic_energy(0, frequency_HCl)

print(f'The zero-point energy of HCl = {energy} J')