#!/usr/bin/env python # coding: utf-8 # # Loops # # This notebook follows on in many ways from the [functions](https://hub.mybinder.org/user/bjmorgan-python_in_chemistry-ty1bfjno/notebooks/General/Functions.ipynb) notebook. The aim here is to show the utility of **loops** in Python programming. I will again endevour to use examples from *chemistry* related problems, but occasionally examples from physics or mathematics will come through. # # As is the case with many aspects of programming the propose of a loop is to allow the programmer to write less code. This leads to the idiom that *computers are really good at doing the same thing over and over*, much better than humans. # # A loop really is just that, a way to tell the computer to perform a task multiple times over. # # The Pythonic way to have a loop is: # # for i in array: # operation # # # There are a few things here that need described. # - for This tells the computer that you are wanting something to be looped through # - i This is the iterator, it will become more clear the utility of this in later examples # - array This is some array of objects that is to be itereated through. # For each iteration the operation is performed. # # Lets have a look at some examples. # In[ ]: for i in range(0, 10): print('Hello World!') # This example says for i in the range 0 to 10 (including zero but not ten) print the string Hello World!. # # The result is that the string is printed 10 times, once for each of the numbers 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. Essentially, i is counting from 0 to 9 and printing the string each time. # # This is more clear if we include i in the string. # In[ ]: for i in range(0, 10): print('Hello World {}!'.format(i)) # Of course, the array doesn't just have to be a series of continuous integers. We can have really any type of array. # In[ ]: array1 = [2.4, 6.7, 3.0, 8.2, 2.7, 7.4] for i in array1: print(i) # And the iterator need not always be called i. This is just a *convention* in programming. # In[ ]: array2 = ['dog', 'horse', 'bear', 'lion', 'camel'] for animal in array2: print(animal) # The examples above are all quite trival, lets have a look at something a bit more applicable. If you have looked at the [functions](https://hub.mybinder.org/user/bjmorgan-python_in_chemistry-ty1bfjno/notebooks/General/Functions.ipynb) notebook this example will be familiar. # # It is the calculation of the equilibrium constant for the following reaction at a series of temperatures, from 300 K to 350 K in 10 K increaments. # # $$\text{CH}_4\text{(g)} + 2\text{O}_2\text{(g)} \rightarrow \text{CO}_2\text{(g)} + 2\text{H}_2\text{O(l)} $$ # # | Component | $\Delta_fH$/kJmol$^{-1}$ | $_rS$/kJmol$^{-1}$ | # |------|------| # | CH$_4$ | -74.8 | 0.1862 | # | O$_2$ | 0 | 0.2050 | # | CO$_2$ | -393.5 | 0.2136 | # | H$_2$O | -285.8 | 0.0699 | # # The first thing we need it the function to calculate the equilibrium constant. # In[ ]: import numpy as np from scipy.constants import R def equilibrium_constant(deltaH_products, deltaH_reactants, S_products, S_reactants, T): deltarH = np.sum(deltaH_products) - np.sum(deltaH_reactants) deltarS = np.sum(S_products) - np.sum(S_reactants) Gibbs_free_energy = deltarH - T * deltarS K = np.exp(-1 * Gibbs_free_energy/(R * 1e-3 *T)) return K # And the range of temperatures. # In[ ]: temperatures = [300., 310., 320., 330., 340., 350.] # Then we can make use of the loop as follows. # In[ ]: deltaH_products = [-393.5, -285.8 * 2] deltaH_reactants = [-74.8, 0 * 2] S_products = [0.2136, 0.0699, 0.0699] S_reactants = [0.1862, 0.2050, 0.2050] for T in temperatures: K = equilibrium_constant(deltaH_products, deltaH_reactants, S_products, S_reactants, T) print('K @ {:.0f} K = {:.3e}'.format(T, K)) # This procedure can be achieved for any range of temperatures, using the np.arange function. The below example also shows how the enumerate function can be utilised to count through the loops. # In[ ]: temperatures = np.arange(300, 400, 20) deltaH_products = [-393.5, -285.8 * 2] deltaH_reactants = [-74.8, 0 * 2] S_products = [0.2136, 0.0699, 0.0699] S_reactants = [0.1862, 0.2050, 0.2050] for i, T in enumerate(temperatures): K = equilibrium_constant(deltaH_products, deltaH_reactants, S_products, S_reactants, T) print('{}. K @ {:.0f} K = {:.3e}'.format(i+1, T, K)) # In[ ]: