Chapter 2

Chapter 2

Table of Contents

Data

Download Data for Chapter 2

Alternatively, individual files can be found in the Data section.

Code from chapter

'''
A program to plot one uv-vis spectrum from a .csv file
    Requires: a .csv file with col 1 as wavelength and col 2 as intensity    
    Written by: Ben Lear and Chris Johnson (authors@codechembook.com)
    v1.0.0 - 250131 - initial version
'''
import numpy as np # needed for genfromtxt()
from plotly.subplots import make_subplots # needed to plot
from codechembook.quickTools import quickOpenFilename

# Specify the name and place for data
data_file = quickOpenFilename()

# Import wavelength (nm) and absorbance to plot as a numpy array
x_data, y_data = np.genfromtxt(data_file,
    delimiter = ',',
    skip_header = 1,
    unpack = True)

# Construct the plot - here UVvis holds the figure object
UVvis = make_subplots() # make a figure object
UVvis.add_scatter(x = x_data, y = y_data, # make a scatter trace object
    mode = 'lines', # this ensures that we will only get lines and not markers
    showlegend = False) # this prevents a legend from being automatically created

# Format the figure
UVvis.update_yaxes(title = 'absorbance')
UVvis.update_xaxes(title = 'wavelength /nm', range = [270, 1100])
UVvis.update_layout(template = 'simple_white') # set the details for the appearance 

# Display the figure
UVvis.show('browser+png') # show an interactive plot and in the spyder Plots window

# Save the spectra using the input file name but replacing .csv with the image file form
UVvis.write_image(data_file.with_suffix('.svg')) # save in the same location as the data file
UVvis.write_image(data_file.with_suffix('.png')) # save in the same location as the data file

Solutions to Exercises

Targeted exercises

Exploiting_built-in_methods_to_manipulate_data_stored_in_objects

  1. Make a Numpy array that has all integers from 1 to 14, including both 1 and 14. Assign this to the variable pH. Make a new Numpy array, assigned to the \cite{variable} conc_H, that is the concentration of protons that corresponds to each p$H$ value. For both array objects, use \cite{methods} of Numpy arrays to accomplish the following (you may need to read the online Numpy documentation):

    • Calculate the mean.
    • Calculate the median.
    • Get the size of the arrays.
    • Get the shape of the arrays.
    • Get the dimension of the arrays.
    • Calculate the variance of the arrays.
    • Get the standard deviation of the arrays?
    • Sort the arrays so that they increase monotonically.
    • Sort the arrays so that they decrease monotonically.
    • Round the value of the conc_H array to 10 decimal places.
    • Get the mode of the conc_H arrays when the values have been rounded to 10 decimal places.
  2. Using the final code from Chapter 1 and only using methods for Numpy arrays, compute the total volume of each stock solution needed for the 24 well plate and how long it will take to prepare the plate, assuming it takes you 4 seconds each time you use the pipet.

Importing_subsets_of_libraries_using_from

  1. Working with from numpy.random import randn
    • using randn(), generate 100 random numbers with a mean of 10 and a standard deviation of 2
    • Using the methods of the Numpy array, get the mean, median, mode, and standard deviation of the array.
  2. Working with from numpy.random import rand:
    • Using rand() generate 100 random numbers between 7 and 13.
    • Using the methods of the Numpy array, get the mean, median, mode, and standard deviation of the array.
  3. Generate two ‘random’ arrays, using rand() twice. Follow these directions:
    • import numpy
    • rng1 = np.random.default_rng(42) # sets a 'seed' for random number generation
    • rand1 = rng1.random(10) # get 10 random numbers from the generator
    • rng2 = np.random.default_rng(42) # set up random number generation with the same seed as above
    • rand2 = rng2.random(10) # get another 10 random numbers, using the second generator
    • rand1 - rand2
    • What does it mean that rand1 - rand2 gave an array of all zeros?
    • Now, repeat the above, but change the value given to default_rng(), the \textit{second} time you use it.
    • What does it mean that rand1 - rand2 did not give an array of all zeros?
    • Repeat the calculation, but with the same numbers you just used. Do you get the same difference as before?
    • Now repeat this twice, but do not give any value to the \textit{second} default_rng()
    • What does all of this tell you about random number generation in Numpy?

Performing_multiple_assignment_operations_in_one_line_by_unpacking

  1. Pick three people you know. Using a single assignment operation assign their favorite food to a variable that is their first name.
  2. A function that is native to Python that we have not yet seen is divmod(). Using the information returned by Python help() function, learn how to write a single line of code that will use divmod() to solve the following problem: You have a solvent bottle with 287 mL of solvent. You have a series of experiments to run that each require 7 mL of solvent. How many experiments can you run, and how much solvent will be left over (these should be assigned to separate variables)? Again, use only a single line of code.
  3. In the prior chapter, you learned to calculate concentrations for a 24 well plate. Using unpacking, get 4 arrays representing the volume of water needed for the 4 rows of the well plate. Use only a single line for this assignment.

Representing_answers_to_yes/no_questions_using_booleans

  1. Which of the following are valid values of booleans?
    • True
    • true
    • TRUE
    • Yes
    • yes
    • YES
    • 1
    • 0
    • Maybe

Describing_the_location_of_files_or_folders_on_your_computer_using_Pathlib

  1. Write down a \cite{statement} to create a variable folder name that contains a Path object object pointing to the following folders on your computer. Use the print(<path objet>) to print the absolute path for each:
    • Your Downloads folder.
    • Your Documents folder.
    • The folder where you are storing files for this book. This \textit{must} be different from both the Downloads and Documents folder.

Making_paths_convenient_and_portable_by_specifying_relative_paths

  1. For the following combinations of folders, print out the relative paths that point from the first folder to the second folder. Use the relative_to() \cite{method} of the Path class to find the relative path between them:
    • From Downloads to Documents
    • From Documents to Downloads
    • From the folder you are using for this book to your Downloads folder
    • From the folder you are using for this book to your Documents folder

Adding_codechembook_to_your_Python_installation

  1. Verify that import codechembook will run. Then use help(codechembook). How many functions are there in this library?

Locating_files_and_folders_graphically_with_codechembook.quickTools.quickOpenFilename

  1. In this exercise, you will learn how to use quickOpenFilename() to generate a relative path from one file or folder to another file or folder.
    • Use quickOpenFilename() to select a file in your Documents folder. This will return an absolute path to the file. Assign this absolute path to a variable called path1.
    • Do the same for a file in your Downloads folder, but assign it to the variable path2.
    • Use the .relative_to() method of the Path class to get the relative path from path2 to path1 and vice-versa. Note you will want to use the \cite{keyword_argument} walk_up to allow full flexibility for relative paths.
  2. Using quickOpenFilename select a file in your downloads folder. Then select a file in your documents folder. Verify these give the same absolute paths as you found in Exercise 10.
  3. Modern file dialogs have search features that make it so that you don’t have to click through your whole file structure to find a file or folder and get its path. Use the search feature of the file dialog in quickOpenFilename() to search for the file ‘0.999.csv’ used in this chapter and select it to get the absolute path to it. Confirm that this path exists.

Accessing_data_in_structured_text_files_using_Numpy

  1. Use the following files supplied on \website for this exercise. Read them into Python using genfromtxt().
    • Exercise-2.16.csv
    • Exercise-2.16.tsv
    • Exercise-2.16.ssv
  2. Repeat Exercise 16, but assign the results to a single variable. Then using this variable, unpack the values into variables that correspond to the columns in the original data file.
  3. Use genfromtxt() to read the file Exercise-2.19.csv. This file contains data with both text and numbers. This can be found at \website
  4. Use genfromtxt() read the same file you used in Exercise 18, but extract only the first and third data columns.
  5. It turns out that the first three rows of the data file you used in Exercise 18 has useful data. Setting unpack = False in genfromtxt(), extract the row data.

Making_appealing_and_interactive_plots_using_Plotly

  1. Go to the Plotly website and find an example plot. Explain how you might use that type of plot in your own research.
  2. Run plotlyTest() from codechembook. You can always use help(codechembook) to find this function.
  3. The plotlyTest() function you ran in Exercise 21 above should have opened a figure in your computer’s browser. One nice thing about Plotly is that these figures are interactive. Using your mouse, move your mouse cursor over the data shown. What happens? Then, click and drag your mouse to try select a region of data. What happens? Play around with this interactivity, and describe what else you find you can do.

Outlining_your_solution_before_coding_using_comments

  1. Consider the comprehensive exercises for this chapter (see below).
    • Create a text outline for the solution, formatted as Python comments.
    • Create a flow diagram for the solutions.
    • Write a list of instructions, like you would to a human being, for how to solve them.

Comprehensive exercises

  1. Generate Plotly plots of the following relationships:
    • $e^{-x}$
    • $1/x$
    • $\nu_{rms}$ vs $T$
    • $K_{EQ}$ as a function of T, for a given $\Delta{H}$ and $\Delta{S}$
  2. Consider the decay of fluorescence intensity (I) over time (t). This typically follows the functional form $I(t) = Ae^{-kt}$. Using Plotly:
    • Plot I vs t.
    • Plot log(I) vs t.
    • Plot I vs log(t).
    • Plot log(I) versus log(t).
    • Which of the above is the most useful, and why do you think that?
  3. Find some other spectroscopic data, either in the data provided with this book or your own data, and adapt the final code from this chapter to plot it.
  4. The data file ‘CO2-IR.txt’ found on the \website contains an absorption-mode FTIR spectrum of gaseous $\ce{CO2}$ with the $x$-axis in wavenumbers. Write a script to that outputs a plot of %transmission vs wavenumber. Remember that absorbance = $-\log_{10}$(transmission). Make sure you use correct axis labels! Bonus: Make the $x$-axis run from the largest to smallest numbers, which is the convention for plotting wavenumbers.
  5. Using the same file from Exercise 27 change the $x$-axis from wavenumber to wavelength (nm). When converting between energy and wavelength on the x-axis, you will need apply a Jacobian correction to the intensities. You can do this by $I(\lambda) = I(\nu) 1 \times 10^7 / \nu^2$ . Make sure you use correct axis labels! Bonus for figuring out how to reverse the direction of the $x$-axis to follow the convention for wavelength.
  6. One nice feature of Plotly over Matplotlib is the fact that you can change a plot after you show it and get an updated version. In Matplotlib, once you show a plot, you usually can no longer make changes and you have to start over. In the case of the final code presented in this chapter, the Plotly figure object, fig, is still in your computer’s memory and you can update it. To prove that you can do this, run the code and adjust the $x$-axis range to 550-750 nm using the range keyword of the update_xaxes() \cite{method} of the figure object. Then show the plot again. Then, do the same for the $y$-axis, choosing values for range so that the resulting spectrum fills the plot area.
  7. In this chapter, we introduced a function that makes it easy to identify files on your computer: quickOpenFilename(). This will be nice to use when you don’t know where the file is located, or when you are choosing different files each time you run your script. However, there will be times when you simply want to use the same file over and over—for instance when you are developing and testing a code. In these cases, it can be much faster to provide the path to the file in the script. Modify the final code in this chapter, replacing the quickOpenFilename() function with a line that creates a Path object with the absolute path to the data. Verify this works, and also comment on when you might prefer this approach over the use of quickOpenFilename().