{ "cells": [ { "cell_type": "markdown", "id": "f2e65fb8", "metadata": {}, "source": [ "# Control Flow\n", "\n", "**Prerequisites**\n", "\n", "- Booleans section in [Basics](https://datascience.quantecon.org/basics.html) \n", "- [Collections](https://datascience.quantecon.org/collections.html) \n", "\n", "\n", "**Outcomes**\n", "\n", "- Asset pricing and NPV \n", " - Understand basic principles of pricing assets with deterministic payoffs \n", " - Apply programming with iteration and conditionals to asset pricing examples \n", "- Conditionals \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", "- Iteration \n", " - Understand what an iterable is \n", " - Be able to write for and while loops \n", " - Understand the keywords break and continue \n", "\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "id": "8dae536b", "metadata": {}, "source": [ "## Net Present Values and Asset Pricing\n", "\n", "In this lecture, we’ll introduce two related topics from economics:\n", "\n", "- Net present valuations \n", "- Asset pricing \n", "\n", "\n", "These topics will motivate some of the programming we do in this course.\n", "\n", "In economics and finance, “assets” provide a stream of\n", "payoffs.\n", "\n", "These “assets” can be concrete or abstract: a stock pays dividends over time, a\n", "bond pays interest, an apple tree provides apples, a job pays wages, and an\n", "education provides possible jobs (which, in turn, pay wages).\n", "\n", "When deciding the price to pay for an asset or how to choose between\n", "different alternatives, we need to take into account that most people would\n", "prefer to receive 1 today vs. 1 next year.\n", "\n", "This reflection on consumer preferences leads to the notion of a discount rate.\n", "If you are indifferent between receiving 1.00 today and 1.10 next year, then\n", "the discount rate over the next year is $r = 0.10$.\n", "\n", "If we assume that an individuals preferences are consistent over time, then we\n", "can apply that same discount rate to valuing assets further into the future.\n", "\n", "For example, we would expect that the consumer would be indifferent between\n", "consuming 1.00 today and $(1+r)(1+r) = 1.21$ dollars two years from now\n", "(i.e. discount twice).\n", "\n", "Inverting this formula, 1 delivered two years from now is equivalent to\n", "$\\frac{1}{(1+r)^2}$ today." ] }, { "cell_type": "markdown", "id": "a481f112", "metadata": {}, "source": [ "## Exercise\n", "\n", "See exercise 1 in the [exercise list](#ex2-3).\n", "\n", "\n", "" ] }, { "cell_type": "markdown", "id": "a5cd3631", "metadata": {}, "source": [ "### Net Present Value\n", "\n", "If an asset pays a stream of payoffs over multiple time periods, then we\n", "can use a discount rate to calculate the value to the consumer of a entire\n", "sequence of payoffs.\n", "\n", "Most generally, we enumerate each discrete time period (e.g. year, month, day) by\n", "the index $t$ where today is $t=0$ and the asset lives for $T$\n", "periods.\n", "\n", "List the payoff at each time period as $y_t$, which we will assume, for\n", "now, is known in advance.\n", "\n", "Then if the discount factor is $r \\geq 0$, the consumer “values” the\n", "payoff $y_t$ delivered at time $t$ as $\\frac{1}{(1+r)^t}y_t$\n", "where we note that if $t=0$, the value is just the current payoff\n", "$y_0$.\n", "\n", "Using this logic, we can write an expression for the value of the entire\n", "sequence of payoffs with a sum.\n", "\n", "\n", "\n", "$$\n", "P_0 = \\sum_{t=0}^T \\left(\\frac{1}{1 + r}\\right)^t y_t \\tag{1}\n", "$$\n", "\n", "If $y_t$ is a constant, then we can compute this sum with a simple formula!\n", "\n", "Below, we present some useful formulas that come from infinite series that we\n", "will use to get our net present value formula.\n", "\n", "For any constant $0 < \\beta < 1$ and integer value $\\tau > 0$,\n", "\n", "\n", "\n", "\n", "\\begin{aligned}\n", "\\sum_{t=0}^{\\infty} \\beta^t & = \\frac{1}{1-\\beta}\\\\\n", "\\sum_{t=0}^{\\tau} \\beta^t &= \\frac{1- \\beta^{\\tau+1}}{1-\\beta}\\\\\n", "\\sum_{t=\\tau}^{\\infty} \\beta^t &= \\frac{\\beta^{\\tau}}{1-\\beta}\n", "\\end{aligned} \\tag{2}\n", "\n", "\n", "In the case of an asset which pays one dollar until time $T$, we can use\n", "these formulas, taking $\\beta = \\frac{1}{1+r}$ and $T = \\tau$, to\n", "find\n", "\n", "\n", "\\begin{aligned}\n", "P_0 &= \\sum_{t=0}^T \\left(\\frac{1}{1 + r}\\right)^t = \\frac{1- (\\frac{1}{1+r})^{\\tau+1}}{1-\\frac{1}{1+r}}\\\\\n", "&= \\frac{1 + r}{r} - \\frac{1}{r}\\left(\\frac{1}{1+r} \\right)^\\tau\n", "\\end{aligned}\n", "\n", "\n", "Note that we can also consider an asset that lives and pays forever if\n", "$T= \\infty$, and from [(2)](#equation-eq-infinite-sums), the value of an asset which\n", "pays 1 forever is $\\frac{1+r}{r}$." ] }, { "cell_type": "markdown", "id": "c81e4599", "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](https://datascience.quantecon.org/basics.html) lecture for a refresher.\n", "\n", "The basic syntax for conditionals is" ] }, { "cell_type": "code", "execution_count": null, "id": "5785d83b", "metadata": { "hide-output": false }, "outputs": [], "source": [ "if condition:\n", " # code to run when condition is True\n", "else:\n", " # code to run if no conditions above are True" ] }, { "cell_type": "markdown", "id": "fedf68cb", "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, "id": "f09536ce", "metadata": { "hide-output": false }, "outputs": [], "source": [ "if True:\n", " print(\"This is where True code is run\")" ] }, { "cell_type": "markdown", "id": "9892bd6f", "metadata": {}, "source": [ "Alternatively, you could have a test which returns a booleans" ] }, { "cell_type": "code", "execution_count": null, "id": "cdf7dea9", "metadata": { "hide-output": false }, "outputs": [], "source": [ "if 1 < 2:\n", " print(\"This is where True code is run\")" ] }, { "cell_type": "markdown", "id": "3ce2dd48", "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, "id": "3d0b2b12", "metadata": { "hide-output": false }, "outputs": [], "source": [ "if False:\n", " print(\"This is where True code is run\")" ] }, { "cell_type": "markdown", "id": "54f5dd6f", "metadata": {}, "source": [ "Or" ] }, { "cell_type": "code", "execution_count": null, "id": "d030b7cb", "metadata": { "hide-output": false }, "outputs": [], "source": [ "if 1 > 2:\n", " print(\"This is where True code is run\")" ] }, { "cell_type": "markdown", "id": "5e29bc45", "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, "id": "83e68216", "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", "id": "3a71b582", "metadata": {}, "source": [ "## Exercise\n", "\n", "See exercise 2 in the [exercise list](#ex2-3).\n", "\n", "The next example shows us how else works." ] }, { "cell_type": "code", "execution_count": null, "id": "4a2e6adb", "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", "id": "3d8876cb", "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, "id": "888d322d", "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", "id": "d0a65cb8", "metadata": {}, "source": [ "## Exercise\n", "\n", "See exercise 3 in the [exercise list](#ex2-3)." ] }, { "cell_type": "markdown", "id": "93ccd4f8", "metadata": {}, "source": [ "## Exercise\n", "\n", "See exercise 4 in the [exercise list](#ex2-3)." ] }, { "cell_type": "markdown", "id": "83c987b0", "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": "code", "execution_count": null, "id": "36ffd62a", "metadata": { "hide-output": false }, "outputs": [], "source": [ "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" ] }, { "cell_type": "markdown", "id": "012d29a6", "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, "id": "40e0613f", "metadata": { "hide-output": false }, "outputs": [], "source": [ "import datetime\n", "halloween = datetime.date(2017, 10, 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", "id": "505b61a3", "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", "id": "d90fe535", "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", "id": "28907d55", "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, "id": "b5103c0c", "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", "id": "eb391e75", "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": "code", "execution_count": null, "id": "0eb544e6", "metadata": { "hide-output": false }, "outputs": [], "source": [ "print(f\"{i}**2 = {i**2}\")" ] }, { "cell_type": "markdown", "id": "359fadb3", "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": null, "id": "2ee39746", "metadata": { "hide-output": false }, "outputs": [], "source": [ "for i in range(1, 11):\n", " print(f\"{i}**2 = {i**2}\")" ] }, { "cell_type": "markdown", "id": "8b36f0e5", "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", "id": "e3b80221", "metadata": {}, "source": [ "### for Loops\n", "\n", "The general structure of a standard for loop is as follows." ] }, { "cell_type": "code", "execution_count": null, "id": "9e2b6aa3", "metadata": { "hide-output": false }, "outputs": [], "source": [ "for item in iterable:\n", " # operation 1 with item\n", " # operation 2 with item\n", " # ...\n", " # operation N with item" ] }, { "cell_type": "markdown", "id": "1058c4c6", "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", "" ] }, { "cell_type": "markdown", "id": "15e6f20e", "metadata": {}, "source": [ "### Exercise\n", "\n", "See exercise 5 in the [exercise list](#ex2-3).\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, "id": "007aac52", "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", "id": "5f258248", "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": null, "id": "dca6cf95", "metadata": { "hide-output": false }, "outputs": [], "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} revenue is ${value} million\")" ] }, { "cell_type": "markdown", "id": "91afa6e7", "metadata": {}, "source": [ "Similarly, the index can be used to access another vector." ] }, { "cell_type": "code", "execution_count": null, "id": "a129740f", "metadata": { "hide-output": false }, "outputs": [], "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", "id": "8525df13", "metadata": {}, "source": [ "### Exercise\n", "\n", "See exercise 6 in the [exercise list](#ex2-3)." ] }, { "cell_type": "markdown", "id": "b9408407", "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": "code", "execution_count": null, "id": "256e4643", "metadata": { "hide-output": false }, "outputs": [], "source": [ "while True_condition:\n", " # repeat these steps" ] }, { "cell_type": "markdown", "id": "03c74402", "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": null, "id": "838a68c9", "metadata": { "hide-output": false }, "outputs": [], "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", "id": "d5ee6f3e", "metadata": {}, "source": [ "Let’s check our work." ] }, { "cell_type": "code", "execution_count": null, "id": "f647dc3e", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# Should be just less than 1000 because range(45) goes from 0 to 44\n", "sum(range(45))" ] }, { "cell_type": "code", "execution_count": null, "id": "3bd16711", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# should be between 990 + 45 = 1035\n", "sum(range(46))" ] }, { "cell_type": "markdown", "id": "aeb8540a", "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": null, "id": "a9330676", "metadata": { "hide-output": false }, "outputs": [], "source": [ "i = 0" ] }, { "cell_type": "markdown", "id": "034f8729", "metadata": {}, "source": [ "And then executes a while loop" ] }, { "cell_type": "code", "execution_count": null, "id": "bebc9b9b", "metadata": { "hide-output": false }, "outputs": [], "source": [ "while i < 3:\n", " print(i)\n", " i = i + 1\n", "print(\"done\")" ] }, { "cell_type": "markdown", "id": "b9e24275", "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": null, "id": "7afa5f17", "metadata": { "hide-output": false }, "outputs": [], "source": [ "while i < 3:\n", " print(i)\n", " i = i + 1\n", "print(\"done\")" ] }, { "cell_type": "markdown", "id": "1aa7356c", "metadata": {}, "source": [ "### Exercise\n", "\n", "See exercise 7 in the [exercise list](#ex2-3)." ] }, { "cell_type": "markdown", "id": "7947ad19", "metadata": {}, "source": [ "### break and continue" ] }, { "cell_type": "markdown", "id": "1752ebf1", "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": null, "id": "5d085dda", "metadata": { "hide-output": false }, "outputs": [], "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", "id": "e19f7409", "metadata": {}, "source": [ "#### Exercise\n", "\n", "See exercise 8 in the [exercise list](#ex2-3)." ] }, { "cell_type": "markdown", "id": "5d7ccc20", "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": "code", "execution_count": null, "id": "97b5e9e1", "metadata": { "hide-output": false }, "outputs": [], "source": [ "for item in iterable:\n", " # always do these operations\n", " if condition:\n", " continue\n", "\n", " # only do these operations if condition is False" ] }, { "cell_type": "markdown", "id": "262a5100", "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, "id": "1108dec9", "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", "id": "80ab55d9", "metadata": {}, "source": [ "#### Exercise\n", "\n", "See exercise 9 in the [exercise list](#ex2-3)." ] }, { "cell_type": "markdown", "id": "cb415e32", "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": null, "id": "c798d400", "metadata": { "hide-output": false }, "outputs": [], "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", "id": "c712ca5d", "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, "id": "915cb6a7", "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, "id": "48b8803c", "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, "id": "422d5667", "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", "id": "b1a73636", "metadata": {}, "source": [ "## Exercise\n", "\n", "See exercise 10 in the [exercise list](#ex2-3).\n", "\n", "Finally, we can use this approach to build complicated nested dictionaries." ] }, { "cell_type": "code", "execution_count": null, "id": "669cc226", "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", "id": "61b834a7", "metadata": {}, "source": [ "\n", "" ] }, { "cell_type": "markdown", "id": "5ae60060", "metadata": {}, "source": [ "## Exercises" ] }, { "cell_type": "markdown", "id": "0db3548b", "metadata": {}, "source": [ "### 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%?" ] }, { "cell_type": "code", "execution_count": null, "id": "49091728", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# your code here" ] }, { "cell_type": "markdown", "id": "ee31db0a", "metadata": {}, "source": [ "([back to text](#dir2-3-1))" ] }, { "cell_type": "markdown", "id": "cfc81185", "metadata": {}, "source": [ "### 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": null, "id": "8c21a980", "metadata": { "hide-output": false }, "outputs": [], "source": [ "x = 1\n", "\n", "if x > 0:\n", " print(\"1\")\n", " print(\"2\")\n", "print(\"3\")" ] }, { "cell_type": "code", "execution_count": null, "id": "e72982d0", "metadata": { "hide-output": false }, "outputs": [], "source": [ "x = 1\n", "\n", "if x > 0:\n", " print(\"1\")\n", "print(\"2\") # changed the indentation\n", "print(\"3\")" ] }, { "cell_type": "markdown", "id": "11ee33b7", "metadata": {}, "source": [ "([back to text](#dir2-3-2))" ] }, { "cell_type": "markdown", "id": "85242529", "metadata": {}, "source": [ "### 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", "Write some conditional based on current_time.hour." ] }, { "cell_type": "code", "execution_count": null, "id": "526c3ddd", "metadata": { "hide-output": false }, "outputs": [], "source": [ "import datetime\n", "current_time = datetime.datetime.now()\n", "\n", "## your code here" ] }, { "cell_type": "markdown", "id": "7c6649ee", "metadata": {}, "source": [ "more text after\n", "\n", "([back to text](#dir2-3-3))" ] }, { "cell_type": "markdown", "id": "658e0e8b", "metadata": {}, "source": [ "### 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](https://datascience.quantecon.org/../scientific/randomness.html) lecture)." ] }, { "cell_type": "code", "execution_count": null, "id": "d590e0b2", "metadata": { "hide-output": false }, "outputs": [], "source": [ "import numpy as np\n", "x = np.random.random()\n", "print(f\"x = {x}\")\n", "\n", "## your code here" ] }, { "cell_type": "markdown", "id": "beffe7ef", "metadata": {}, "source": [ "([back to text](#dir2-3-4))" ] }, { "cell_type": "markdown", "id": "64000705", "metadata": {}, "source": [ "### 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", "1. 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", "\n", "Should the student enroll in school if the discount rate is r = 0.05?" ] }, { "cell_type": "code", "execution_count": null, "id": "35b8df07", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# 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", "\n", "# Compute npv of attending college\n", "\n", "# Compute npv of being a college worker\n", "\n", "# Is npv_collegeworker - npv_collegecost > npv_hsworker" ] }, { "cell_type": "markdown", "id": "d37f6cd5", "metadata": {}, "source": [ "([back to text](#dir2-3-5))" ] }, { "cell_type": "markdown", "id": "9bee0da9", "metadata": {}, "source": [ "### 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", "Try using zip" ] }, { "cell_type": "code", "execution_count": null, "id": "9dc59fa7", "metadata": { "hide-output": false }, "outputs": [], "source": [ "cities = [\"Phoenix\", \"Austin\", \"San Diego\", \"New York\"]\n", "states = [\"Arizona\", \"Texas\", \"California\", \"New York\"]\n", "\n", "# Your code here" ] }, { "cell_type": "markdown", "id": "f38fe380", "metadata": {}, "source": [ "([back to text](#dir2-3-6))" ] }, { "cell_type": "markdown", "id": "2fc4aa30", "metadata": {}, "source": [ "### 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": null, "id": "a1c10758", "metadata": { "hide-output": false }, "outputs": [], "source": [ "# Define cost of teaching python\n", "cost = 25_000\n", "r = 0.01\n", "\n", "# Per month value\n", "added_value = 2500\n", "\n", "n_months = 0\n", "total_npv = 0.0\n", "\n", "# Put condition below here\n", "while False: # (replace False with your condition here)\n", " n_months = n_months + 1 # Increment how many months they've worked\n", "\n", " # Increase total_npv" ] }, { "cell_type": "markdown", "id": "dfac1ed0", "metadata": {}, "source": [ "([back to text](#dir2-3-7))" ] }, { "cell_type": "markdown", "id": "5a954c37", "metadata": {}, "source": [ "### 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", "try iterating over range(len(x))." ] }, { "cell_type": "code", "execution_count": null, "id": "85297426", "metadata": { "hide-output": false }, "outputs": [], "source": [ "x = np.random.rand(10_000)\n", "# Your code here" ] }, { "cell_type": "markdown", "id": "caa2a557", "metadata": {}, "source": [ "([back to text](#dir2-3-8))" ] }, { "cell_type": "markdown", "id": "7665b63f", "metadata": {}, "source": [ "### 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", "Try starting your loop with for value in x: instead of\n", "iterating over the indices of x." ] }, { "cell_type": "code", "execution_count": null, "id": "15dc129c", "metadata": { "hide-output": false }, "outputs": [], "source": [ "x = np.random.rand(10_000)\n", "# Your code here" ] }, { "cell_type": "markdown", "id": "8b0053ae", "metadata": {}, "source": [ "([back to text](#dir2-3-9))" ] }, { "cell_type": "markdown", "id": "e21aec8c", "metadata": {}, "source": [ "### 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", "Try using zip" ] }, { "cell_type": "code", "execution_count": null, "id": "34854a57", "metadata": { "hide-output": false }, "outputs": [], "source": [ "cities = [\"Phoenix\", \"Austin\", \"San Diego\", \"New York\"]\n", "states = [\"Arizona\", \"Texas\", \"California\", \"New York\"]\n", "\n", "# your code here" ] }, { "cell_type": "markdown", "id": "79f2b820", "metadata": {}, "source": [ "([back to text](#dir2-3-10))" ] } ], "metadata": { "date": 1662089821.4258816, "filename": "control_flow.md", "kernelspec": { "display_name": "Python", "language": "python3", "name": "python3" }, "title": "Control Flow" }, "nbformat": 4, "nbformat_minor": 5 }