{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h1>4. Loops</h1>\n",
    "<h2>10/06/23</h2>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>4.0 Last Time...</h2>\n",
    "\n",
    "<ul>\n",
    "    <li>A <b>function</b> is a block of code that can be called.</li>\n",
    "    <li>Functions can be called using either positional or keyword arguments.</li>\n",
    "    <li>Positional arguments can be described via lists and keyword arguments can be described via dictionaries.</li>\n",
    "    <li>Python uses if statements for logical constructs.</li>\n",
    "    <li>The code within an <b>if</b> statement is run if the current statement is true.</li>\n",
    "    <li>The code within an <b>elif</b> statement applies if prior statements are not true <b>and</b> the current statement is true.</li>\n",
    "    <li>The code within an <b>else</b> statement applies if all prior statements are not true.</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>4.1 For Loops</h2>\n",
    "\n",
    "A <b>for loop</b> is used when you're going to be repeating a block of code a predetermined number of times. The format is simple enough: <b>for</b> an index <b>in</b> a list:. The block of code that you'll then be running <b>must be indented</b>: either use Tab or press Spacebar four times at the start of each line. (This is the price we pay for not having to end statements with a semicolon or something similar.)\n",
    "\n",
    "The index we refer to here is just a counter that's going to keep track of how many times the loop has been run. Often we just call this index 'i', but you can name it whatever you like. This index will be assigned to each individual item in the list until we run out of list items."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Let's try an example. First let's define a list!\n",
    "\n",
    "\n",
    "# Now let's print each value within that list using a for loop.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that the index variable changes variable type as it goes down the list, from integer to float to string to integer. Technically, this index should be called an <b>iterator</b>, and iterators are one example of an <b>object</b>, which we'll see in more detail when we get into object-oriented programming later in this course.\n",
    "\n",
    "Sometimes you'll want the iterator to just count the elements in a list, rather than actually taking on their values. For this, the range() function comes in handy: you specify the size of the list you want, and it will create a new list counting the number of elements. That is, range(n) returns [0,1,2,...,n-1]."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# You can use the range function in a for loop. In this case, i is an integer for every step of the loop.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's try a meteorological example of a for loop. Let's say you have 10 temperature measurements in Celsius and want them to be converted to Fahrenheit. A for loop is a great way to do this!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# First, let's define our initial 10 temperature measurements.\n",
    "\n",
    "\n",
    "# Next, we'll want to loop over all values in this list.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "    \n",
    "# Did it work? Let's check.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that, for this example, we had to use the range() function, because we needed to know the index of each temperature measurement we were in the process of converting. If we didn't know how many elements were in temp, we could have used range(len(temp)) instead of range(10). "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The range() function is also useful for counting based on a particular pattern, using the format <b>range(first value,final value,increment)</b>. Remember that the first value is always <b>inclusive</b> and the final value is always <b>exclusive</b>!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "\n",
    "# Let's convert the same dataset from Celsius to Fahrenheit, but this time we'll only convert\n",
    "# every second temperature, going backwards.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As a side note, using an integer in a function in a way that makes that function less versatile (for instance, range(10) above means the loop will only work for lists with 10 elements) is often called <b>hardcoding</b> and is good to avoid when you can. If instead we used range(len(temp)), it wouldn't matter how many elements there were in the list: our loop would still work.\n",
    "\n",
    "It's also very possible to combine the logical constructs from yesterday's class with a loop."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Let's use our new Fahrenheit temperatures to make some statements!\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>4.2 While Loops</h2>\n",
    "\n",
    "A <b>while</b> loop lets you loop an indefinite number of times. This comes in handy if we don't yet know how many times we want to repeat a process (for instance, adding a random number to a running total until we hit a particular target value). The syntax is simple: <b>while \\<condition\\>:</b>. The indented code following the while line will be executed repeatedly while \\<condition\\> evaluates as True."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Let's do a simple example of a while loop that will print the integers one through nine.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "That first line (a = 1) is known as an <b>initialization</b> and is a key part of a while loop: if we didn't have a value of a to start with, we couldn't evaluate whether the while statement was True or False. The last line (a = a + 1) is known as an <b>incrementation</b> and ensures that we're not just doing the same check over and over again."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Here's an example of a while loop that will not run because the while condition is always False.\n",
    "\n",
    "# There won't be an error message, but the loop will never run.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What if the while statement is always True? Then the while statement will go on forever. This... is a problem. If you suspect you may be caught in an infinite loop, you can often hit CTRL-C to stop the process, or hit the stop button in a Jupyter notebook.\n",
    "\n",
    "Often this problem emerges because the incrementation step (in the example above, a = a + 1) gets forgotten."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# We're not going to run an infinite-loop example here because it may crash your web browser. But it happens!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<b>An Example!</b>\n",
    "\n",
    "Using 1) a <b>for</b> loop, and 2) a <b>while</b> loop, write code that will count integers backwards from 10 to 1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# For loop!\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "tags": []
   },
   "outputs": [],
   "source": [
    "# While Loop!\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<h2>TAKE-HOME POINTS</h2>\n",
    "\n",
    "<ul>\n",
    "    <li>A <b>for loop</b> lets you repeat an operation a specified  number of times.</li>\n",
    "    <li>Indentation is critical for lists in Python.</li>\n",
    "    <li>The range() function will create a list of all values up to the specified integer.</li>\n",
    "    <li>Hardcoding is the act of (often unnecessarily) restricting a piece of code so it only works under specific circumstances.</li>\n",
    "    <li>A <b>while loop</b> lets you repeat an operation until a particular condition is met.</li>\n",
    "    <li>The index in a while loop must be initialized and care should be taken to avoid infinite loops.</li>\n",
    "</ul>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
