{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Control Flow\n",
    "\n",
    "**Prerequisites**\n",
    "\n",
    "- Booleans section \n",
    "- [Collections]\n",
    "\n",
    "\n",
    "**Outcomes**\n",
    "\n",
    "- Conditionals  \n",
    "  \n",
    "  - Understand what a conditional is  \n",
    "  - Be able to construct `if`/`elif`/`else` conditional blocks  \n",
    "  - Understand how conditionals can be used to selectively execute blocks of code  \n",
    "  \n",
    "- Iteration  \n",
    "  \n",
    "  - Understand what an iterable is  \n",
    "  - Be able to write `for` and `while` loops  \n",
    "  - Understand the keywords `break` and `continue`  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Outline\n",
    "\n",
    "- [Control Flow](#Control-Flow)  \n",
    "  - [Net Present Values and Asset Pricing](#Net-Present-Values-and-Asset-Pricing)  \n",
    "  - [Conditional Statements and Blocks](#Conditional-Statements-and-Blocks)  \n",
    "  - [Iteration](#Iteration)  \n",
    "  - [Comprehension](#Comprehension)  \n",
    "  - [Exercises](#Exercises)  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='deterministic-asset-pricing'></a>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conditional Statements and Blocks\n",
    "\n",
    "Sometimes, we will only want to execute some piece of code if a certain condition\n",
    "is met.\n",
    "\n",
    "These conditions can be anything.\n",
    "\n",
    "For example, we might add to total sales if the transaction value is positive,\n",
    "but add to total returns if the value is negative.\n",
    "\n",
    "Or, we might want to add up all incurred costs, only if the transaction happened\n",
    "before a certain date.\n",
    "\n",
    "We use *conditionals* to run particular pieces of code when certain criterion\n",
    "are met.\n",
    "\n",
    "Conditionals are closely tied to booleans, so if you don’t remember what those\n",
    "are, go back to the [basics] lecture for a refresher.\n",
    "\n",
    "The basic syntax for conditionals is"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "if condition:\n",
    "    # code to run when condition is True\n",
    "else:\n",
    "    # code to run if no conditions above are True\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that immediately following the condition, there is a colon *and*\n",
    "that the next line begins with blank spaces.\n",
    "\n",
    "Using 4 spaces is a *very strong* convention, so that is what\n",
    "we do — we recommend that you do the same.\n",
    "\n",
    "Also note that the `else` clause is optional.\n",
    "\n",
    "Let’s see some simple examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "if True:\n",
    "    print(\"This is where `True` code is run\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively, you could have a test which returns a booleans"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "if 1 < 2:\n",
    "     print(\"This is where `True` code is run\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This example is equivalent to just typing the print statement, but the\n",
    "example below isn’t…"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "if False:\n",
    "    print(\"This is where `True` code is run\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "if 1 > 2:\n",
    "     print(\"This is where `True` code is run\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that when you run the cells above nothing is printed.\n",
    "\n",
    "That is because the condition for the `if` statement was not true, so the code\n",
    "inside the indented block was never run.\n",
    "\n",
    "This also allows us to demonstrate the role of indentation\n",
    "in determining the “block” of code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "val = False\n",
    "\n",
    "if val is True: # check an expression\n",
    "    print(\"This is where `True` code is run\")\n",
    "    print(\"More code in the if block\")\n",
    "print(\"Code runs after 'if' block, regardless of val\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-1'></a>\n",
    "> See exercise 2 in the [*exercise list*](https://datascience.quantecon.org/#exerciselist-0)\n",
    "\n",
    "\n",
    "The next example shows us how `else` works."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "val = (2 == 4)  # returns False\n",
    "if val is True:\n",
    "    print(\"This is where `True` code is run\")\n",
    "else:\n",
    "    print(\"This is where `False` code is run\")\n",
    "    print(\"More else code\")\n",
    "print(\"Code runs after 'if' block, regardless of val\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `if False: ...` part of this example is the same as the example\n",
    "before, but now, we added an `else:` clause.\n",
    "\n",
    "In this case, because the conditional for the `if` statement was not\n",
    "`True`, the if code block was not executed, but the `else` block was.\n",
    "\n",
    "Finally, the `Condition is True` is assumed in the `if` statement, and is often left out.  For example, the following are identical"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "if (1 < 2) is True:\n",
    "    print(\"1 < 2\")\n",
    "\n",
    "if 1 < 2:\n",
    "    print(\"1 < 2\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-2'></a>\n",
    "> See exercise 3 in the [*exercise list*]\n",
    "\n",
    "\n",
    "\n",
    "<a id='exercise-3'></a>\n",
    "> See exercise 4 in the [*exercise list*]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `elif` clauses\n",
    "\n",
    "Sometimes, you have more than one condition you want to check.\n",
    "\n",
    "For example, you might want to run a different set of code based on which\n",
    "quarter a particular transaction took place in.\n",
    "\n",
    "In this case you could check whether the date is in Q1, or in Q2, or in Q3, or if not\n",
    "any of these it must be in Q4.\n",
    "\n",
    "The way to express this type of conditional is to use one or more `elif`\n",
    "clause in addition to the `if` and the `else`.\n",
    "\n",
    "The syntax is"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "if condition1:\n",
    "    # code to run when condition1 is True\n",
    "elif condition2:\n",
    "    # code to run when condition2 is True\n",
    "elif condition3:\n",
    "    # code to run when condition3 is True\n",
    "else:\n",
    "    # code to run when none of the above are true\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can include as many `elif` clauses as you want.\n",
    "\n",
    "As before, the `else` part is optional.\n",
    "\n",
    "Here’s how we might express the quarter example referred to above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "import datetime\n",
    "halloween = datetime.date(2017, 1, 31)\n",
    "\n",
    "if halloween.month > 9:\n",
    "    print(\"Halloween is in Q4\")\n",
    "elif halloween.month > 6:\n",
    "    print(\"Halloween is in Q3\")\n",
    "elif halloween.month > 3:\n",
    "    print(\"Halloween is in Q2\")\n",
    "else:\n",
    "    print(\"Halloween is in Q1\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that when there are multiple `if` or `elif` conditions, only the code\n",
    "corresponding to the **first** true clause is run.\n",
    "\n",
    "We saw this in action above.\n",
    "\n",
    "We know that when `halloween.month > 9` is true, then `halloween.month > 6`\n",
    "and `halloween.month > 3` must also be true, but only the code block\n",
    "associated with `halloween.month > 9` was printed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Iteration\n",
    "\n",
    "When doing computations or analyzing data, we often need to repeat certain\n",
    "operations a finite number of times or until some condition is met.\n",
    "\n",
    "Examples include processing all data files in a directory (folder), aggregating\n",
    "revenues and costs for every period in a year, or computing the net present\n",
    "value of certain assets. (In fact, later in this section, we will verify the equations\n",
    "that we wrote down above.)\n",
    "\n",
    "These are all examples of a programming concept called iteration.\n",
    "\n",
    "We feel the concept is best understood through example, so we will present a\n",
    "contrived example and then discuss the details behind doing iteration in Python."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### A Contrived Example\n",
    "\n",
    "Suppose we wanted to print out the first 10 integers and their squares.\n",
    "\n",
    "We *could* do something like this."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "print(f\"1**2 = {1**2}\")\n",
    "print(f\"2**2 = {2**2}\")\n",
    "print(f\"3**2 = {3**2}\")\n",
    "print(f\"4**2 = {4**2}\")\n",
    "# .. and so on until 10"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you can see, the code above is repetitive.\n",
    "\n",
    "For each integer, the code is exactly the same except for the two places where\n",
    "the “current” integer appears.\n",
    "\n",
    "Suppose that I asked you to write the same print statement for an int stored in\n",
    "a variable named `i`.\n",
    "\n",
    "You might write the following code:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "print(f\"{i}**2 = {i**2}\")\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This more general version of the operation suggests a strategy for achieving our\n",
    "goal with less repetition: have a variable `i` take on the values 1 through 10\n",
    "(Quiz: How can we use `range` to create the numbers 1 to 10?) and run the line\n",
    "of code above for each new value of `i`.\n",
    "\n",
    "This can be accomplished with a `for` loop!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1**2 = 1\n",
      "2**2 = 4\n",
      "3**2 = 9\n",
      "4**2 = 16\n",
      "5**2 = 25\n",
      "6**2 = 36\n",
      "7**2 = 49\n",
      "8**2 = 64\n",
      "9**2 = 81\n",
      "10**2 = 100\n"
     ]
    }
   ],
   "source": [
    "for i in range(1, 11):\n",
    "     print(f\"{i}**2 = {i**2}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "china_data = [(2015, 11.06, 1.371), (2014, 10.48, 1.364), (2013, 9.607, 1.357)\\\n",
    "             ,(2012, 8.04, 1.334), (2011, 8.56, 1.3445), (2010, 9.607, 1.628)\\\n",
    "             ] "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "In the year 2015, the GDP is equal to 11.06.\n",
      "In the year 2014, the GDP is equal to 10.48.\n",
      "In the year 2013, the GDP is equal to 9.607.\n",
      "In the year 2012, the GDP is equal to 8.04.\n",
      "In the year 2011, the GDP is equal to 8.56.\n",
      "In the year 2010, the GDP is equal to 9.607.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[11.06, 10.48, 9.607, 8.04, 8.56, 9.607]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "gdp = []\n",
    "for i in range(len(china_data)):\n",
    "    print(f\"In the year {china_data[i][0]}, the GDP is equal to {china_data[i][1]}.\")\n",
    "    gdp.append(china_data[i][1])\n",
    "gdp   "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Whoa, what just happened?\n",
    "\n",
    "The integer `i` took on the values in `range(1, 11)` one by one and\n",
    "for each new value it did the operations in the indented block (here\n",
    "just one line that called the `print` function)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `for` Loops\n",
    "\n",
    "The general structure of a standard `for` loop is as follows."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "for item in iterable:\n",
    "   # operation 1 with item\n",
    "   # operation 2 with item\n",
    "   # ...\n",
    "   # operation N with item\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "where `iterable` is anything capable of producing one item at a time (see\n",
    "[here](https://docs.python.org/3/glossary.html#term-iterable) for official\n",
    "definition from the Python team).\n",
    "\n",
    "We’ve actually already seen some of the most common iterables!\n",
    "\n",
    "Lists, tuples,\n",
    "dicts, and range/zip/enumerate objects are all iterables.\n",
    "\n",
    "Note that we can have as many operations as we want inside the indented block.\n",
    "\n",
    "We will refer to the indented block as the “body” of the loop.\n",
    "\n",
    "When the for loop is executed, `item` will take on one value from `iterable`\n",
    "at a time and execute the loop body for each value.\n",
    "\n",
    "\n",
    "<a id='human-capital-application'></a>\n",
    "\n",
    "<a id='exercise-4'></a>\n",
    "> See exercise 5 in the [*exercise list*]\n",
    "\n",
    "\n",
    "When iterating, each `item` in `iterable` might actually contain more than\n",
    "one value.\n",
    "\n",
    "Recall that tuples (and lists) can be unpacked directly into variables."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "tup = (4, \"test\")\n",
    "i, x = tup\n",
    "print(f\"i = {i}, x = {x}, tup = {tup}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Also, recall that the value of a `enumerate(iterable)` is a tuple of the\n",
    "form `(i, x)` where `iterable[i] == x`.\n",
    "\n",
    "When we use `enumerate` in a for loop, we can “unpack” both values at the same\n",
    "time as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "quarter 1 revenue is $5.12 million\n",
      "quarter 2 revenue is $5.2 million\n",
      "quarter 3 revenue is $5.5 million\n",
      "quarter 4 revenue is $6.5 million\n"
     ]
    }
   ],
   "source": [
    "# revenue by quarter\n",
    "company_revenue = [5.12, 5.20, 5.50, 6.50]\n",
    "\n",
    "for index, value in enumerate(company_revenue):\n",
    "    print(f\"quarter {index + 1} revenue is ${value} million\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "quarter 1 revenue is $5.12 million\n",
      "quarter 2 revenue is $5.2 million\n",
      "quarter 3 revenue is $5.5 million\n",
      "quarter 4 revenue is $6.5 million\n"
     ]
    }
   ],
   "source": [
    "for j in range(len(company_revenue)):\n",
    "     print(f\"quarter {j + 1} revenue is ${company_revenue [j]} million\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Similarly, the index can be used to access another vector."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Phoenix is in Arizona\n",
      "Austin is in Texas\n",
      "San Diego is in California\n",
      "New York is in New York\n"
     ]
    }
   ],
   "source": [
    "cities = [\"Phoenix\", \"Austin\", \"San Diego\", \"New York\"]\n",
    "states = [\"Arizona\", \"Texas\", \"California\", \"New York\"]\n",
    "for index, city in enumerate(cities):\n",
    "    state = states[index]\n",
    "    print(f\"{city} is in {state}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-5'></a>\n",
    "> See exercise 6 in the [*exercise list*]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `while` Loops\n",
    "\n",
    "A related but slightly different form of iteration is to repeat something\n",
    "until some condition is met.\n",
    "\n",
    "This is typically achieved using a `while` loop.\n",
    "\n",
    "The structure of a while loop is"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "while True_condition:\n",
    "    # repeat these steps\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "where `True_condition` is some conditional statement that should evaluate to\n",
    "`True` when iterations should continue and `False` when Python should stop\n",
    "iterating.\n",
    "\n",
    "For example, suppose we wanted to know the smallest `N` such that\n",
    "$ \\sum_{i=0}^N i > 1000 $.\n",
    "\n",
    "We figure this out using a while loop as follows."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The answer is 45\n"
     ]
    }
   ],
   "source": [
    "total = 0\n",
    "i = 0\n",
    "while total <= 1000:\n",
    "    i = i + 1\n",
    "    total = total + i\n",
    "\n",
    "print(\"The answer is\", i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let’s check our work."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "990"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Should be just less than 1000 because range(45) goes from 0 to 44\n",
    "sum(range(45))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1035"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# should be between 990 + 45 = 1035\n",
    "sum(range(46))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A warning: one common programming error with while loops is to forget to\n",
    "set the variable you use in the condition prior to executing.  For example,\n",
    "take the following code which correctly sets a counter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "i = 0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And then executes a while loop"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "2\n",
      "done\n"
     ]
    }
   ],
   "source": [
    "while i < 3:\n",
    "    print(i)\n",
    "    i = i + 1\n",
    "print(\"done\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "No problems.  But if you were to execute the above cell again, or another cell, the `i=3` remains, and code is never executed (since `i < 3` begins as False)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "done\n"
     ]
    }
   ],
   "source": [
    "while i < 3:\n",
    "    print(i)\n",
    "    i = i + 1\n",
    "print(\"done\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-6'></a>\n",
    "> See exercise 7 in the [*exercise list*]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### `break` and `continue`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### `break` Out of a Loop\n",
    "\n",
    "Sometimes we want to stop a loop early if some condition is met.\n",
    "\n",
    "Let’s revisit the example of finding the smallest `N` such that\n",
    "$ \\sum_{i=0}^N i > 1000 $.\n",
    "\n",
    "Clearly `N` must be less than 1000, so we know we will find the answer\n",
    "if we start with a `for` loop over all items in `range(1001)`.\n",
    "\n",
    "Then, we can keep a running total as we proceed and tell Python to stop\n",
    "iterating through our range once total goes above 1000."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The answer is 45\n"
     ]
    }
   ],
   "source": [
    "total = 0\n",
    "for i in range(1001):\n",
    "    total = total + i\n",
    "    if total > 1000:\n",
    "        break\n",
    "\n",
    "print(\"The answer is\", i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-7'></a>\n",
    "> See exercise 8 in the [*exercise list*]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### `continue` to the Next Iteration\n",
    "\n",
    "Sometimes we might want to stop the *body of a loop* early if a condition is met.\n",
    "\n",
    "To do this we can use the `continue` keyword.\n",
    "\n",
    "The basic syntax for doing this is:"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "for item in iterable:\n",
    "    # always do these operations\n",
    "    if condition:\n",
    "        continue\n",
    "\n",
    "    # only do these operations if condition is False\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Inside the loop body, Python will stop that loop iteration of the loop and continue directly to the next iteration when it encounters the `continue` statement.\n",
    "\n",
    "For example, suppose I ask you to loop over the numbers 1 to 10 and print out\n",
    "the message “{i} An odd number!” whenever the number `i` is odd, and do\n",
    "nothing otherwise.\n",
    "\n",
    "You can use continue to do this as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "for i in range(1, 11):\n",
    "    if i % 2 == 0:  # an even number... This is modulus division\n",
    "        continue\n",
    "\n",
    "    print(i, \"is an odd number!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-8'></a>\n",
    "> See exercise 9 in the [*exercise list*]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Comprehension\n",
    "\n",
    "Often, we will want to perform a very simple operation for every element of some iterable and\n",
    "create a new iterable with these values.\n",
    "\n",
    "This could be done by writing a for loop and saving each\n",
    "value, but often using what is called a *comprehension* is more readable.\n",
    "\n",
    "Like many Python concepts, a comprehension is easiest to understand through example.\n",
    "\n",
    "Imagine that we have a list `x` with a list of numbers. We would like to create a list `x2` which has\n",
    "the squared values of x."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 1, 4, 9]\n",
      "[0, 1, 4, 9]\n"
     ]
    }
   ],
   "source": [
    "x = list(range(4))\n",
    "\n",
    "# Create squared values with a loop\n",
    "x2_loop = []\n",
    "for x_val in x:\n",
    "    x2_loop.append(x_val**2)\n",
    "\n",
    "# Create squared values with a comprehension\n",
    "x2_comp = [x_val**2 for x_val in x]\n",
    "\n",
    "print(x2_loop)\n",
    "print(x2_comp)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that much of the same text appears when we do the operation in the loop and when we do the\n",
    "operation with the comprehension.\n",
    "\n",
    "- We need to specify what we are iterating over – in both cases, this is `for x_val in x`.  \n",
    "- We need to square each element `x_val**2`.  \n",
    "- It needs to be stored somewhere – in `x2_loop`, this is done by appending each element to a list,\n",
    "  and in `x2_comp`, this is done automatically because the operation is enclosed in a list.  \n",
    "\n",
    "\n",
    "We can do comprehension with many different types of iterables, so we demonstrate a few more below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "# Create a dictionary from lists\n",
    "tickers = [\"AAPL\", \"GOOGL\", \"TVIX\"]\n",
    "prices = [175.96, 1047.43, 8.38]\n",
    "d = {key: value for key, value in zip(tickers, prices)}\n",
    "d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "# Create a list from a dictionary\n",
    "d = {\"AMZN\": \"Seattle\", \"TVIX\": \"Zurich\", \"AAPL\": \"Cupertino\"}\n",
    "\n",
    "hq_cities = [d[ticker] for ticker in d.keys()]\n",
    "hq_cities"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "import math\n",
    "\n",
    "# List from list\n",
    "x = range(10)\n",
    "\n",
    "sin_x = [math.sin(x_val) for x_val in x]\n",
    "sin_x"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "<a id='exercise-9'></a>\n",
    "> See exercise 10 in the [*exercise list*]\n",
    "\n",
    "Finally, we can use this approach to build complicated nested dictionaries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "hide-output": false
   },
   "outputs": [],
   "source": [
    "gdp_data = [9.607, 10.48, 11.06]\n",
    "years = [2013, 2014, 2015]\n",
    "exports = [ {\"manufacturing\": 2.4, \"agriculture\": 1.5, \"services\": 0.5},\n",
    "            {\"manufacturing\": 2.5, \"agriculture\": 1.4, \"services\": 0.9},\n",
    "            {\"manufacturing\": 2.7, \"agriculture\": 1.4, \"services\": 1.5}]\n",
    "data = zip(years, gdp_data,exports)\n",
    "data_dict = {year : {\"gdp\" : gdp, \"exports\": exports} for year, gdp, exports in data}\n",
    "print(data_dict)\n",
    "\n",
    "# total exports by year\n",
    "[data_dict[year][\"exports\"][\"services\"] for year in data_dict.keys()]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercises\n",
    "\n",
    "Due date: Aug 23, 2022 before Noon.\n",
    "\n",
    "\n",
    "<a id='exerciselist-0'></a>\n",
    "**Exercise 1**\n",
    "\n",
    "Government bonds are often issued as *zero-coupon bonds* meaning that they\n",
    "make no payments throughout the entire time that they are held, but, rather\n",
    "make a single payment at the time of maturity.\n",
    "\n",
    "How much should you be willing to pay for a zero-coupon bond that paid\n",
    "100 in 10 years with an interest rate of 5%?\n",
    "\n",
    "([*back to text*](https://datascience.quantecon.org/#exercise-0))\n",
    "\n",
    "**Exercise 2**\n",
    "\n",
    "Run the following two variations on the code with only a single change in the indentation.\n",
    "\n",
    "After, modify the `x` to print `3` and then `2, 3` instead."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "64.46089162177971\n"
     ]
    }
   ],
   "source": [
    "#Exercise 1:\n",
    "print(npf.npv(0.05,[0,0,0,0,0,0,0,0,0,100]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "#Exercise 2:\n",
    "x = -1\n",
    "\n",
    "if x > 0:\n",
    "    print(\"1\")\n",
    "    print(\"2\")\n",
    "print(\"3\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "x = -1\n",
    "\n",
    "if x > 0:\n",
    "    print(\"1\")\n",
    "print(\"2\") # changed the indentation\n",
    "print(\"3\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*]\n",
    "\n",
    "**Exercise 3**\n",
    "\n",
    "Using the code cell below as a start, print `\"Good afternoon\"` if the\n",
    "`current_time` is past noon.\n",
    "\n",
    "Otherwise, do nothing.\n",
    "\n",
    "(Hint: Write some conditional based on `current_time.hour`.)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "hide-output": false
   },
   "source": [
    "```python\n",
    "import datetime\n",
    "current_time = datetime.datetime.now()\n",
    "\n",
    "## your code here\n",
    "```\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [],
   "source": [
    "import datetime\n",
    "current_time = datetime.datetime.now()\n",
    "current_time = current_time.hour\n",
    "\n",
    "if current_time > 12:\n",
    "    print(\"Good afternoon\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "more text after\n",
    "\n",
    "([*back to text*]\n",
    "\n",
    "**Exercise 4**\n",
    "\n",
    "In this example, you will generate a random number between 0 and 1\n",
    "and then display \"x > 0.5\" or \"x < 0.5\" depending on the value of the\n",
    "number.\n",
    "\n",
    "This also introduces a new package `numpy.random` for\n",
    "drawing random numbers (more in the [randomness](../scientific/randomness) lecture)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "x = 0.5773876947360274\n",
      "x>0.5\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "x = np.random.random()\n",
    "print(f\"x = {x}\")\n",
    "\n",
    "## your code here\n",
    "if x > 0.5:\n",
    "    print(\"x>0.5\")\n",
    "else:\n",
    "    print(\"x<0.5\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*]\n",
    "\n",
    "**Exercise 5**\n",
    "\n",
    "In economics, when an individual has some knowledge, skills, or education\n",
    "which provides them with a source of future income, we call it [human\n",
    "capital](https://en.wikipedia.org/wiki/Human_capital).\n",
    "\n",
    "When a student graduating from high school is considering whether to\n",
    "continue with post-secondary education, they may consider that it gives\n",
    "them higher paying jobs in the future, but requires that they don't begin\n",
    "working until after graduation.\n",
    "\n",
    "Consider the simplified example where a student has perfectly forecastable\n",
    "employment and is given two choices:\n",
    "\n",
    "1. Begin working immediately and make 40,000 a year until they retire 40\n",
    "years later.\n",
    "2. Pay 5,000 a year for the next 4 years to attend university, then\n",
    "get a job paying 50,000 a year until they retire 40 years after making\n",
    "the college attendance decision.\n",
    "\n",
    "Should the student enroll in school if the discount rate is r = 0.05?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Collecting package metadata (current_repodata.json): ...working... done\n",
      "Solving environment: ...working... done\n",
      "\n",
      "## Package Plan ##\n",
      "\n",
      "  environment location: C:\\Users\\marth\\anaconda3\n",
      "\n",
      "  added / updated specs:\n",
      "    - numpy-financial\n",
      "\n",
      "\n",
      "The following packages will be downloaded:\n",
      "\n",
      "    package                    |            build\n",
      "    ---------------------------|-----------------\n",
      "    conda-4.14.0               |   py39hcbf5309_0         1.0 MB  conda-forge\n",
      "    numpy-financial-1.0.0      |     pyhd8ed1ab_0          42 KB  conda-forge\n",
      "    python_abi-3.9             |           2_cp39           4 KB  conda-forge\n",
      "    ------------------------------------------------------------\n",
      "                                           Total:         1.1 MB\n",
      "\n",
      "The following NEW packages will be INSTALLED:\n",
      "\n",
      "  numpy-financial    conda-forge/noarch::numpy-financial-1.0.0-pyhd8ed1ab_0\n",
      "  python_abi         conda-forge/win-64::python_abi-3.9-2_cp39\n",
      "\n",
      "The following packages will be SUPERSEDED by a higher-priority channel:\n",
      "\n",
      "  conda              pkgs/main::conda-4.14.0-py39haa95532_0 --> conda-forge::conda-4.14.0-py39hcbf5309_0\n",
      "\n",
      "\n",
      "\n",
      "Downloading and Extracting Packages\n",
      "\n",
      "numpy-financial-1.0. | 42 KB     |            |   0% \n",
      "numpy-financial-1.0. | 42 KB     | ###7       |  38% \n",
      "numpy-financial-1.0. | 42 KB     | ########## | 100% \n",
      "\n",
      "python_abi-3.9       | 4 KB      |            |   0% \n",
      "python_abi-3.9       | 4 KB      | ########## | 100% \n",
      "\n",
      "conda-4.14.0         | 1.0 MB    |            |   0% \n",
      "conda-4.14.0         | 1.0 MB    | #9         |  20% \n",
      "conda-4.14.0         | 1.0 MB    | ######8    |  69% \n",
      "conda-4.14.0         | 1.0 MB    | ########## | 100% \n",
      "Preparing transaction: ...working... done\n",
      "Verifying transaction: ...working... done\n",
      "Executing transaction: ...working... done\n",
      "Retrieving notices: ...working... done\n",
      "\n",
      "Note: you may need to restart the kernel to use updated packages.\n"
     ]
    }
   ],
   "source": [
    "conda install -c conda-forge numpy-financial "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "hide-output": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000, 40000]\n",
      "40\n",
      "720681.6268677661\n",
      "[5000, 5000, 5000, 5000]\n",
      "4\n",
      "18616.24014685239\n",
      "868709.7146474223\n",
      "Yes, the student should enroll in college, because npv_collegeworker - npv_collegecost > npv_hsworker \n"
     ]
    }
   ],
   "source": [
    "import numpy_financial as npf\n",
    "# Discount rate\n",
    "r = 0.05\n",
    "\n",
    "# High school wage\n",
    "w_hs = 40_000\n",
    "\n",
    "# College wage and cost of college\n",
    "c_college = 5_000\n",
    "w_college = 50_000\n",
    "\n",
    "# Compute npv of being a hs worker\n",
    "hsworker = []\n",
    "for i in range (1,41):\n",
    "    hsworker.append(w_hs)\n",
    "print(hsworker)\n",
    "print(len(hsworker))\n",
    "npv_hsworker= npf.npv(r, hsworker)\n",
    "print(npv_hsworker)\n",
    "\n",
    "# Compute npv of attending college\n",
    "collegecost = []\n",
    "for i in range (1,5):\n",
    "    collegecost.append(c_college)\n",
    "print(collegecost)\n",
    "print(len(collegecost))\n",
    "npv_collegecost = npf.npv(r, collegecost)\n",
    "print(npv_collegecost)\n",
    "\n",
    "# Compute npv of being a college worker\n",
    "collegeworker = []\n",
    "for i in range (1,37):\n",
    "    collegeworker.append(w_college)\n",
    "npv_collegeworker= npf.npv(r, collegeworker)\n",
    "print(npv_collegeworker)\n",
    "# Is npv_collegeworker - npv_collegecost > npv_hsworker\n",
    "\n",
    "if npv_collegeworker - npv_collegecost > npv_hsworker:\n",
    "    print(\"Yes, the student should enroll in college, because npv_collegeworker - npv_collegecost > npv_hsworker \")\n",
    "else: print(\"No, the student should not enroll in college, because npv_collegeworker - npv_collegecost < npv_hsworker\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*]\n",
    "\n",
    "**Exercise 6**\n",
    "\n",
    "Instead of the above, write a for loop that uses the lists of cities\n",
    "and states below to print the same \"{city} is in {state}\" using\n",
    "a `zip` instead of an `enumerate`.\n",
    "\n",
    "*Hint*: try using `zip`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "hide-output": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Phoenix is in Arizona.\n",
      "Austin is in Texas.\n",
      "San Diego is in California.\n",
      "New York is in New York.\n"
     ]
    }
   ],
   "source": [
    "cities = [\"Phoenix\", \"Austin\", \"San Diego\", \"New York\"]\n",
    "states = [\"Arizona\", \"Texas\", \"California\", \"New York\"]\n",
    "x = list(zip(cities, states))\n",
    "#print(tuple(x))\n",
    "# Your code here\n",
    "for i in range (len(x)):\n",
    "    print(f\"{x[i][0]} is in {x[i][1]}.\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*](https://datascience.quantecon.org/#exercise-5))\n",
    "\n",
    "**Exercise 7**\n",
    "\n",
    "Companies often invest in training their employees to raise their\n",
    "productivity. Economists sometimes wonder why companies\n",
    "spend this money when this incentivizes other companies to hire\n",
    "their employees away with higher salaries since employees gain human capital from training?\n",
    "\n",
    "Let's say that it costs a company 25,000 dollars to teach their\n",
    "employees Python, but it raises their output by 2,500 per month. How\n",
    "many months would an employee need to stay for the company to find it\n",
    "profitable to pay for their employees to learn Python if their discount\n",
    "rate is r = 0.01?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "11\n"
     ]
    }
   ],
   "source": [
    "# Define cost of teaching python\n",
    "cost = 25_000\n",
    "r = 0.01\n",
    "\n",
    "# Per month value\n",
    "added_value = 2500\n",
    "value = []\n",
    "n_months = 0\n",
    "total_npv = 0.0\n",
    "\n",
    "# Put condition below here\n",
    "while total_npv < cost: # (replace False with your condition here)\n",
    "    n_months = n_months + 1  # Increment how many months they've worked\n",
    "    value.append(added_value)\n",
    "    total_npv= npf.npv(r, value)\n",
    "    #print(n_months)\n",
    "    #print(value)\n",
    "    #print(total_npv)\n",
    "print(n_months)\n",
    "    # Increase total_npv"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*]\n",
    "\n",
    "**Exercise 8**\n",
    "\n",
    "Try to find the index of the first value in `x`\n",
    "that is greater than 0.999 using a for loop and `break`.\n",
    "\n",
    "*Hint*: try iterating over `range(len(x))`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0.31688883 0.03515574 0.21078914 ... 0.75396292 0.36633748 0.8689677 ]\n",
      "1136\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "x = np.random.rand(10_000)\n",
    "print(x)\n",
    "total = 0\n",
    "for i in x:\n",
    "    total = total + 1\n",
    "    if i > 0.999:\n",
    "        break\n",
    "    \n",
    "    \n",
    "print(total)\n",
    "\n",
    "# Your code here"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*]\n",
    "\n",
    "**Exercise 9**\n",
    "\n",
    "Write a for loop that adds up all values in `x` that are greater than\n",
    "or equal to 0.5.\n",
    "\n",
    "Use the `continue` word to end the body of the loop early for all values\n",
    "of `x` that are less than 0.5.\n",
    "\n",
    "*Hint*: Try starting your loop with `for value in x:` instead of\n",
    "iterating over the indices of `x`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {
    "hide-output": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3709.1589678963783\n"
     ]
    }
   ],
   "source": [
    "x = np.random.rand(10_000)\n",
    "values= []\n",
    "# Your code here\n",
    "for value in x:\n",
    "    if value < 0.5:\n",
    "        continue\n",
    "    values.append(value)\n",
    "    \n",
    "#print(values)\n",
    "print(sum(values))\n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*]\n",
    "\n",
    "**Exercise 10**\n",
    "\n",
    "Returning to our previous example: print \"{city} is in {state}\" for each combination\n",
    "using a `zip` and a comprehension.\n",
    "\n",
    "*Hint*: try using `zip`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {
    "hide-output": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Phoenix is in Arizona.',\n",
       " 'Austin is in Texas.',\n",
       " 'San Diego is in California.',\n",
       " 'New York is in New York.']"
      ]
     },
     "execution_count": 111,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cities = [\"Phoenix\", \"Austin\", \"San Diego\", \"New York\"]\n",
    "states = [\"Arizona\", \"Texas\", \"California\", \"New York\"]\n",
    "\n",
    "# your code here\n",
    "x= list(zip(cities, states))\n",
    "\n",
    "[(f\"{cities} is in {states}.\") for cities, states in x]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "([*back to text*]\n"
   ]
  }
 ],
 "metadata": {
  "date": 1596739281.4357364,
  "filename": "control_flow.rst",
  "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.12"
  },
  "next_doc": {
   "link": "functions",
   "title": "Functions"
  },
  "prev_doc": {
   "link": "collections",
   "title": "Collections"
  },
  "title": "Control Flow"
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
