{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "# Introduction to Loops"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Problem 1\n",
    "\n",
    "**Write code to print the numbers 0 to 4 on each line below.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "source": [
    "### Solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "print(0)\n",
    "print(1)\n",
    "print(2)\n",
    "print(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Discussion\n",
    "* Okay, let's keep going to 10000...(!?)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Loops\n",
    "\n",
    "* Loops in programing are used to simplify repetative work.\n",
    "* Above, each line is a print statement.\n",
    "    * The only thing different on each line is the number we are printing.\n",
    "* We can write a loop statment to do the above problem as follows"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "for i in range(4):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Discussion\n",
    "* What are the parts of this: list them?\n",
    "* ```i``` can be any variable, not just \"i\"\n",
    "* Is there anything weird or unexpected here?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Problem 2\n",
    "* We can put **any** code in the for loop\n",
    "    * Variables, functions, expressions, math, etc.\n",
    "* We can put variables outside of the loop that are available inside of the loop\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "For the ideal gas law, pressure is given by\n",
    "$$P = nRT/V$$\n",
    "* n = 1 kmol\n",
    "* R = 8314 J/kmol*K\n",
    "* T = 300 K\n",
    "\n",
    "**For V = 2, 3, 4, 5, ... 20, use a loop to find and print the values of P for each V.**\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "### Solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2 1247100.0\n",
      "3 831400.0\n",
      "4 623550.0\n",
      "5 498840.0\n",
      "6 415700.0\n",
      "7 356314.28571428574\n",
      "8 311775.0\n",
      "9 277133.3333333333\n",
      "10 249420.0\n",
      "11 226745.45454545456\n",
      "12 207850.0\n",
      "13 191861.53846153847\n",
      "14 178157.14285714287\n",
      "15 166280.0\n",
      "16 155887.5\n",
      "17 146717.64705882352\n",
      "18 138566.66666666666\n",
      "19 131273.68421052632\n",
      "20 124710.0\n"
     ]
    }
   ],
   "source": [
    "n = 1     # kmol\n",
    "R = 8314  # J/kmol*K\n",
    "T = 300   # K\n",
    "\n",
    "for V in range(2,21):\n",
    "    P = n*R*T/V\n",
    "    print(V, P)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Discussion\n",
    "* What if you wanted V to not step by integers?\n",
    "    * Step by 2? Step by 5?\n",
    "    * Step by 0.2?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Problem 3 \n",
    "\n",
    "**Add all the numbers from 0 to 100**\n",
    "* Before you start the code, think about what you would do if solving this in your head?\n",
    "    * How do you start?\n",
    "    * What things do you keep track of?\n",
    "    * What variables to use?\n",
    "    * What is the loop syntax?\n",
    "    * How do variables interact with the loop?\n",
    "* Think through the process of <font color='red'>the problem</font> to <font color='blue'> the solution</font>\n",
    "* Talk to your neighbor\n",
    "* If you've solved it, help your neighbor."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5050\n"
     ]
    }
   ],
   "source": [
    "s = 0\n",
    "for i in range(101):\n",
    "    s += i\n",
    "print(s)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Nested loops\n",
    "\n",
    "* We can put **any** code in a ```for``` loop. Even another loop.\n",
    "* Look at the code below. \n",
    "* **Before running it, think of what you expect to see.**\n",
    "    * Now run it and compare. Did you get what you thought you would?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [],
   "source": [
    "for i in range(3):\n",
    "    print(\"i =\", i)\n",
    "    for j in range(4):\n",
    "        print(\"   j =\", j)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "* Note, each time through the top (outer) loop, **everything** inside is done.\n",
    "* This means the **whole** inner loop is computed for each outer loop.\n",
    "* **Think of an actual application for a nested loop.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Problem 4a\n",
    "\n",
    "* Given the following function\n",
    "$$f(x) = x^2 - 3,$$\n",
    "we can use Newton's method to find $x$ for $f(x)=0$. \n",
    "\n",
    "* Recall, Newton recurrence formula:\n",
    "$$x_{new} = x_{old} - \\frac{f(x_{old})}{f^\\prime(x_{old})}$$\n",
    "\n",
    "### We solved this previously in Excel\n",
    "* **Open Excel and solve this problem.**\n",
    "* Think about the steps involved, how we set it up.\n",
    "* **Use the simplest method possible.**\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Solution-Excel\n",
    "\n",
    "<img src='https://ignite.byu.edu/cbe263/lectures/loops_fig_1.png' width=300>\n",
    "\n",
    "\n",
    "| Excel | Python|\n",
    "|:-----:|:-----:|\n",
    "|cell for guess |  ?? |\n",
    "|Newton equation in terms of x cell <br> A2 - (A2^2-3)/(2*A2)| ?? |\n",
    "| repeat: fill down | ?? |\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Problem 4b\n",
    "### Now solve in Python using loops\n",
    "\n",
    "* **Try to write the simplest solution you can think of with as few lines of code as possible.**\n",
    "* **We want 3 decimal places of accuracy.**\n",
    "* Consider: \n",
    "    * What variables are needed?\n",
    "    * How to setup and use the loop.\n",
    "    * What to print and where?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Solution-Python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0\n",
      "1.75\n",
      "1.7321428571428572\n",
      "1.7320508100147276\n",
      "1.7320508075688772\n"
     ]
    }
   ],
   "source": [
    "x = 1\n",
    "for i in range(5):\n",
    "    x = x - (x**2-3)/(2*x)\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Discussion\n",
    "- Note that `i` isn't used, it's just convenient for making the loop\n",
    "- x is reassigned in place (x is replaced with the updated value on each loop)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "###  Explicitly write out the four steps\n",
    "* We don't have to code it from top to bottom...\n",
    "* Compare to Excel\n",
    "\n",
    "| Excel | Python|\n",
    "|:-----:|:-----:|\n",
    "|cell for guess |  variable for x |\n",
    "|Newton equation in terms of x cell <br> A2 - (A2^2-3)/(2*A2)| Newton equation in terms of x <br> x = x - (x\\*\\*2-3)/(2*x)|\n",
    "| repeat: fill down | repeat: wrap in loop |"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0\n",
      "1.75\n",
      "1.7321428571428572\n",
      "1.7320508100147276\n",
      "1.7320508075688772\n",
      "1.7320508075688774\n"
     ]
    }
   ],
   "source": [
    "# step 1: initial guess\n",
    "x = 1\n",
    "\n",
    "# step 2: add Newton equation\n",
    "x=1\n",
    "x = x - (x**2 - 3)/(2*x)\n",
    "\n",
    "# step 3: wrap in loop\n",
    "x=1\n",
    "for i in range(6):\n",
    "    x = x - (x**2 - 3)/(2*x)\n",
    "\n",
    "# step 4: add a print\n",
    "x=1\n",
    "for i in range(6):\n",
    "    x = x - (x**2 - 3)/(2*x)\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Problem 4c\n",
    "\n",
    "**Redo Solution 1 using functions for $f(x)$ and $f^\\prime(x)$.**\n",
    "* Recall: we discussed functions two classes back."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "slideshow": {
     "slide_type": "fragment"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0\n",
      "1.75\n",
      "1.7321428571428572\n",
      "1.7320508100147276\n",
      "1.7320508075688772\n"
     ]
    }
   ],
   "source": [
    "def f(x):\n",
    "    return x**2-3\n",
    "def fp(x):\n",
    "    return 2*x\n",
    "\n",
    "x = 1\n",
    "for i in range(5):\n",
    "    x = x - f(x)/fp(x)\n",
    "    print(x)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "## Problem 4d\n",
    "\n",
    "* Now, to get to three decimal places we only needed 3 iterations.\n",
    "* But we didn't know this at the beginning, so we guessed the number of iterations.\n",
    "    * If 6 wasn't enough, we would do more.\n",
    "* This guess and check is not very efficient.\n",
    "\n",
    "**Modify the code above to do just the right number of iterations.**\n",
    "* What Python features do you need to use?\n",
    "* How do you decide when you are done?\n",
    "* **Talk with your neighbor.**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "skip"
    }
   },
   "source": [
    "### Solution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.0\n",
      "1.75\n",
      "1.7321428571428572\n",
      "1.7320508100147276\n"
     ]
    }
   ],
   "source": [
    "def f(x):\n",
    "    return x**2-3\n",
    "def fp(x):\n",
    "    return 2*x\n",
    "\n",
    "eps = 0.001\n",
    "xold = 1\n",
    "for i in range(5):\n",
    "    xnew = xold - f(xold)/fp(xold)\n",
    "    print(xnew)\n",
    "    rerr = np.abs((xold - xnew)/xnew)\n",
    "    if rerr < eps: \n",
    "        break\n",
    "    xold = xnew"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "slideshow": {
     "slide_type": "slide"
    }
   },
   "source": [
    "### Discussion\n",
    "- Keep track of old and new x: `xold` and `xnew`.\n",
    "    - Need to reset `xold=xnew` at the end to get set for next interation.\n",
    "- New keyword `break`\n",
    "- Define the error and compare it to the desired accuracy.\n",
    "    - Use absolute value: `np.abs()`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "celltoolbar": "Slideshow",
  "kernelspec": {
   "display_name": "base",
   "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.14.6"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
