<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Chapter 5 :: Coding For Chemists</title>
    <link>https://codingforchemistsbook.com/book_material/chapter-5/index.html</link>
    <description>Data Chapter 5 usesDownload the data for Chapter 5&#xA;Alternatively, individual files can be found in the Data section.&#xA;Code from chapter &#39;&#39;&#39; A script to fit a calibration experiment to a line, starting wtih the UV/vis spectra Requires: .csv files with col 1 as wavelength and col 2 as intensity filenames should contain the concentration after an &#39;_&#39; Written by: Ben Lear and Chris Johnson (authors@codechembook.com) v1.0.0 - 250204 - initial version &#39;&#39;&#39; import numpy as np from lmfit.models import LinearModel from plotly.subplots import make_subplots from codechembook.quickTools import quickSelectFolder, quickHTMLFormula import codechembook.symbols as cs # identify the files you wish to plot and the place you want to save them at print(&#39;Select the folder with the calibration UVvis files.&#39;) filenames = sorted(quickSelectFolder().glob(&#39;*csv&#39;)) # Ask the user what wavelength to use for calibration l_max = float(input(&#39;What is the position of the feature of interest? &#39;)) # Loop through the file names, read the files, and extract the data into lists conc, absorb = [], [] # empty lists that will hold concentrations and absorbances for f in filenames: conc.append(float(f.stem.split(&#39;_&#39;)[1])) # get concentration from file name and add to list temp_x, temp_y = np.genfromtxt(f, unpack = True, delimiter=&#39;,&#39;, skip_header = 1) # read file l_max_index = np.argmin(abs(temp_x - l_max)) # Find index of x data point closest to l_max absorb.append(temp_y[l_max_index]) # get the closest absorbance value and add to list # Set up and perform a linear fit to the calibration data lin_mod = LinearModel() # create an instance of the linear model object pars = lin_mod.guess(absorb, x=conc) # have lmfit guess at initial values result = lin_mod.fit(absorb, pars, x=conc) # fit using these initial values print(result.fit_report()) # print out the results of the fit # Print out the molar absorptivity print(f&#39;The molar absorptivity is {result.params[&#34;slope&#34;].value / 1:5.2f} {cs.math.plusminus} {result.params[&#34;slope&#34;].stderr:4.2f} M{cs.typography.sup_minus}{cs.typography.sup_1}cm{cs.typography.sup_minus}{cs.typography.sup_1}&#39;) # Construct a plot with two subplots. Pane 1 contains the best fit and data, pane 2 the residual fig = make_subplots(rows = 2, cols = 1) # make a blank figure object that has two subplots # Add trace objects for the best fit, the data, and the residualto the plot fig.add_scatter(x = result.userkws[&#39;x&#39;], y = result.best_fit, mode = &#39;lines&#39;, showlegend=False, row = 1, col = 1) fig.add_scatter(x = result.userkws[&#39;x&#39;], y = result.data, mode = &#39;markers&#39;, showlegend=False, row =1, col = 1) fig.add_scatter(x = result.userkws[&#39;x&#39;], y = -1*result.residual, showlegend=False, row = 2, col = 1) # Create annotation for the slope and intercept values and uncertainties as a string annotation_string = f&#39;&#39;&#39; slope = {result.params[&#34;slope&#34;].value:.2e} {cs.math.plusminus} {result.params[&#34;slope&#34;].stderr:.2e}&lt;br&gt; intercept = {result.params[&#34;intercept&#34;].value:.2e} {cs.math.plusminus} {result.params[&#34;intercept&#34;].stderr:.2e}&lt;br&gt; R{cs.typography.sup_2} = {result.rsquared:.3f}&#39;&#39;&#39; fig.add_annotation(text = annotation_string, x = np.min(result.userkws[&#39;x&#39;]), y = result.data[-1], xanchor = &#39;left&#39;, yanchor = &#39;top&#39;, align = &#39;left&#39;, showarrow = False, ) # Create annotation for the extinction coefficient and uncertainty fig.add_annotation(text = f&#39;{cs.greek.epsilon} = {result.params[&#34;slope&#34;].value:5.2f} {cs.math.plusminus} {result.params[&#34;slope&#34;].stderr:4.2f} M&lt;sup&gt;-1&lt;/sup&gt;cm&lt;sup&gt;-1&lt;/sup&gt;&#39;, x = np.max(result.userkws[&#39;x&#39;]), y = result.data[0], xanchor = &#39;right&#39;, yanchor = &#39;top&#39;, align = &#39;right&#39;, showarrow = False, ) # Format the axes and the plot, then show it fig.update_xaxes(title = &#39;concentration /M&#39;) fig.update_yaxes(title = f&#39;absorbance @ {l_max} nm&#39;, row = 1, col = 1) fig.update_yaxes(title = &#39;residual absorbance&#39;, row = 2, col = 1) fig.update_layout(template = &#39;simple_white&#39;, title = f&#39;calibration for {quickHTMLFormula(&#34;(C4H2N2S2)2Ni&#34;)}&#39;) fig.show(&#39;png&#39;) # -*- coding: utf-8 -*- &#34;&#34;&#34; Created on Tue Dec 17 13:51:22 2024 @author: benle &#34;&#34;&#34; import numpy as np from pathlib import Path from lmfit.models import LinearModel from plotly.subplots import make_subplots from codechembook.quickTools import quickSelectFolder import codechembook.symbols as cs # identify the files you wish to plot and the place you want to save them at filenames = quickSelectFolder().glob(&#34;*csv&#34;) filenames = list(filenames) # at this point, we have a sorted list of filenames # now, extract the information we want from the files. conc, absorb = [], [] # empty lists that will hold concentrations and absorbances for f in filenames: # go through the file names print(f) x, y = np.genfromtxt(f, delimiter = &#34;,&#34;, unpack=True) fig = make_subplots() fig.add_scatter(x = x, y = y, line = dict(color = &#34;red&#34;)) fig.update_yaxes(title = &#34;absorbance&#34;) fig.update_xaxes(title = &#34;wavelength /nm&#34;) fig.update_layout(template = &#34;none&#34;) fig.show(&#34;png&#34;) fig.write_image(Path(f).with_suffix(&#34;.png&#34;)) Solutions to Exercises Targeted exercises Prompting the user for information using input Exercise 0 Using the dictionary of solvent properties that you made in Exercise 0 from Chapter 4, write a code that asks the user for a solvent, then asks the user for a property, and then prints a sentence that tells the user the value of that property for the solvent they chose.</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <managingEditor>authors@codingforchemistsbook.com (Benjamin Lear and Christopher Johnson)</managingEditor>
    <webMaster>authors@codingforchemistsbook.com (Benjamin Lear and Christopher Johnson)</webMaster>
    <atom:link href="https://codingforchemistsbook.com/book_material/chapter-5/index.xml" rel="self" type="application/rss+xml" />
  </channel>
</rss>