{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Functions\n", "\n", "The Pythonic way to define a function is:" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def f(x):\n", " y = x ** 2\n", " return y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "What this says is that you want to: \n", "- define a function\n", "- That function should be called f\n", "- It will have one argument, x\n", "- The operation to be performed on x is to square x; x ** 2\n", "- The result of the operation should be stored in the variable y\n", "- The data stored in variable y should be returned\n", "\n", "Defining a function is only half the battle, now we need to *call* it.\n", "\n", "This is achieved using the following *syntax*:\n", "\n", "result = name_of_function(argument)\n", "\n", "\n", "Which tells the computer to *execute* the function called name_of_function, with the argument argument, and store the result in the variable result. \n", "\n", "So if we would like to run the function that we have defined above." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "x = 2\n", "y = f(x)\n", "y" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It should be noted that the names of the variables **do not** need to be the same as in the function definition (however the function name does), so the following is equally valid." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "horsey = 3\n", "doggy = f(horsey)\n", "doggy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is not necessary for a function to have only one argument, just as in mathematics. For example we can write a function that calculates the equilibrium constant of some reaction." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import numpy as np\n", "\n", "def equilibrium_constant(deltaG, R, T):\n", " K = np.exp(-deltaG / (R * T))\n", " return K\n", "\n", "deltaG = -20.5 #kJ/mol\n", "R = 8.314 #J/Kmol\n", "R = 8.314 * 0.001 #kJ/Kmol\n", "T = 300 #K\n", "\n", "K = equilibrium_constant(deltaG, R, T)\n", "print('The equilibrium constant is {:.3f}'.format(K))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Further, the function can return multiple results. See the example below for finding the roots of a quadratic equation. \n", "\n", "$$ y = ax^2 + bx + c $$\n", "\n", "where, $a = 1$, $b = 4$, and $c = 2$. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def getRoots(a, b, c):\n", " x_plus = (-b + np.sqrt(b ** 2 - 4 * a * c)) / (2 * a)\n", " x_minus = (-b - np.sqrt(b ** 2 - 4 * a * c)) / (2 * a)\n", " return x_plus, x_minus\n", "\n", "x_plus, x_minus = getRoots(1, 4, 2)\n", "print(x_plus, x_minus)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A function doesn't need to be a single operation -- it can include many operations (this is when the power of functions becomes particularly useful). For example calculating the equilibrium constant from the standard enthalpies of formation and standard entropies of the products and reactants of a reaction. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "from scipy.constants import R\n", "\n", "def equilibrium_constant_long(deltaH_products, deltaH_reactants, S_products, S_reactants, T):\n", " deltarH = np.sum(deltaH_products) - np.sum(deltaH_reactants)\n", " deltarS = np.sum(S_products) - np.sum(S_reactants)\n", " Gibbs_free_energy = deltarH - T * deltarS\n", " K = np.exp(-1 * Gibbs_free_energy/(R * 1e-3 * T))\n", " return K" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hopefully you can see how using this function could be useful -- for example if you would like to calculate the equilibrium constant for the following reaction at a series of temperatures, say between 300 K and 350 K in 10 K increaments. \n", "\n", "$$\\text{CH}_4\\text{(g)} + 2\\text{O}_2\\text{(g)} \\rightarrow \\text{CO}_2\\text{(g)} + 2\\text{H}_2\\text{O(l)} $$\n", "\n", "| Component | $\\Delta_fH$/kJmol$^{-1}$ | $_rS$/kJmol$^{-1}$ |\n", "|------|------|\n", "| CH$_4$ | -74.8 | 0.1862 |\n", "| O$_2$ | 0 | 0.2050 |\n", "| CO$_2$ | -393.5 | 0.2136 |\n", "| H$_2$O | -285.8 | 0.0699 |\n", "\n", "All that needs to be written is," ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "deltaH_products = [-393.5, -285.8 * 2]\n", "deltaH_reactants = [-74.8, 0 * 2]\n", "S_products = [0.2136, 0.0699, 0.0699]\n", "S_reactants = [0.1862, 0.2050, 0.2050]\n", "\n", "K_300 = equilibrium_constant_long(deltaH_products, deltaH_reactants, S_products, S_reactants, 300)\n", "print('K @ 300 K = {:.3e}'.format(K_300))\n", "K_310 = equilibrium_constant_long(deltaH_products, deltaH_reactants, S_products, S_reactants, 310)\n", "print('K @ 310 K = {:.3e}'.format(K_310))\n", "K_320 = equilibrium_constant_long(deltaH_products, deltaH_reactants, S_products, S_reactants, 320)\n", "print('K @ 320 K = {:.3e}'.format(K_320))\n", "K_330 = equilibrium_constant_long(deltaH_products, deltaH_reactants, S_products, S_reactants, 330)\n", "print('K @ 330 K = {:.3e}'.format(K_330))\n", "K_340 = equilibrium_constant_long(deltaH_products, deltaH_reactants, S_products, S_reactants, 340)\n", "print('K @ 340 K = {:.3e}'.format(K_340))\n", "K_350 = equilibrium_constant_long(deltaH_products, deltaH_reactants, S_products, S_reactants, 350)\n", "print('K @ 350 K = {:.3e}'.format(K_350))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It would take a lot longer to write out the contents of the equilibrium_constant_long function for each temperature. \n", "\n", "Of course the amount of code required to calcuated K at these temperatures could be reduced further by using a **loop**, but that is for another day." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" } }, "nbformat": 4, "nbformat_minor": 2 }