{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Iterations: While statement\n", "\n", "We've spent some time going into detail about some of the data types and structures available in python. It's now time to talk about how to navigate through some of this data, and use data to make decisions. \n", "\n", "Traversing over data and making decisions based upon data are a common aspect of every programming language. To understand how to do this, we will study the concept of _iteration_. Iterations allow us to execute the same task multiple times, and is a key programming concept.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# This is just to use the time.sleep function\n", "# We will use the time.sleep function to slow\n", "# down the execution of loops, only for\n", "# instructional purposes. In reality, we add\n", "# such delays only in special cases.\n", "import time" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Introduction\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The `while` statement provides a general way for creating iterative code execution. \n", "\n", "As in the case of the `if` statement, the `while` statement uses a boolean expression that controls the flow of execution. \n", "\n", "The difference is that, when we use the `if` statement, the nested code in executed only once; when we use the `while` statement, the nested code keeps executing, as long as the boolean expression is `True`.\n", "\n", "For example, the following example counts until `i` becomes larger than 5" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "i = 0\n", "while i <= 5: # check if i<=5. If yes, execute the nested block of code\n", " print(i) # print the current value of i\n", " time.sleep(1.0) # Wait for 1 sec\n", " i = i + 1 # increase i\n", " # Now go to the beginning of the loop" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Formal description of a while statement" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "More formally, here is the flow of execution for a `while` statement:\n", "\n", "![Flowchart for a while loop (from \"How to Think Like a Computer Scientist\")](http://interactivepython.org/runestone/static/thinkcspy/_images/while_flow.png)\n", "\n", "1. Evaluate the condition, yielding `False` or `True`.\n", "2. If the condition is `False`, exit the `while` statement and continue execution at the next statement that is after the body of the while.\n", "3. If the condition is `True`, execute each of the statements in the body and then go back to step 1.\n", "\n", "The body consists of all of the statements below the header with the same indentation.\n", "\n", "\n", "\n", "This type of flow is called a **loop** because the third step loops back around to the top. Notice that if the condition is `False` the first time through the loop, the statements inside the loop are never executed." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Example: Tea Cooling" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Or consider the following example: The tea starts at 115 degrees Fahrenheit. You want it at 110 degrees. A chip of ice turns out to lower the temperature one degree every second. You test the temperature each time, and also print out the temperature before reducing the temperature. In Python you could write and run the code below:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "temperature = 115\n", "while temperature > 110: # Execute the loop code if temperature > 110\n", " print(temperature)\n", " time.sleep(1.0) # Wait for 1 sec\n", " temperature = temperature - 1 # Decrease the value of temperature by one\n", " # Now go back to the beginning of the loop\n", "\n", "print(\"The tea is cool enough.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Finite and Infinite Loops" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Notice that the body of the loop should change the value of one or more variables so that eventually the condition becomes `False` and the loop terminates. If the condition never becomes False, the loop will repeat forever. Such type of a loop is called an **infinite loop**. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And here is a simplified simulator that starts with an amount of money in the bank, and then examines the effect of withdrawing a specific amount of money per year, until you run out of money. Notice that the loop will keep running for ever, if you never withdraw more money than what you have. (We will deal with this issue next.)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "money_in_bank = 1000\n", "interest = 6\n", "year = 2017\n", "widthdrawal_per_period = 200\n", "\n", "while money_in_bank > 0:\n", " print(f\"At the beginning of {year} you have ${money_in_bank:.2f} in the bank.\")\n", " money_in_bank = money_in_bank - widthdrawal_per_period\n", " money_in_bank = money_in_bank * (1 + interest / 100)\n", " year = year + 1\n", " print(f\"At the end of {year} you have ${money_in_bank:.2f} in the bank.\")\n", " print(\"-----------------\")\n", "\n", "print(\"You have no money left!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "The following code contains an infinite loop. \n", "\n", "```python \n", "n = 10\n", "answer = 1\n", "while n > 0:\n", " answer = answer + n\n", " n = n + 1\n", "print(answer)\n", "```\n", "\n", "Which is the best explanation for why the loop does not terminate?\n", "\n", "1. `n` starts at 10 and is incremented by 1 each time through the loop, so it will always be positive\n", "2. `answer` starts at 1 and is incremented by `n` each time, so it will always be positive\n", "3. You cannot compare `n` to 0 in `while` loop. You must compare it to another variable.\n", "4. In the `while` loop body, we must set `n` to `False`, and this code does not do that." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Warning\n", "\n", "_You may have seen that Python’s `while` is very close to the English “while”. There is an important difference, though: In English “while X holds, do Y”, we usually assume that immediately after X becomes false, we stop with Y. In Python there is not an immediate stop: Even if the condition becomes false in the middle of the loop body, the rest of the loop body will still be executed, and the loop will stop only before the next iteration._\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `Break` and `Continue`\n", "\n", "\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's discuss now two commands, `break` and `continue`, that allow us to control better the execution of code within a loop.\n", "\n", "These two statements are used to modify iteration of loops. `break` is used to *exit immediately* the *inner most _loop_* in which it appears. In contrast, `continue` stops the code executing within the loop and goes on to the *next iteration of the same loop*.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Bank Account Example\n", "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For example, consider our example with the bank account. The loop will keep running for ever, if you never withdraw more money than what you have. \n", "\n", "To avoid this infinite loop, we can add an extra check in the code, checking if the year is above a certain limit, and stop execution of the loop at that point." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "money_in_bank = 1000\n", "interest = 6\n", "year = 2017\n", "\n", "# Try also the values 56.6 and 56.7 and see its behavior\n", "widthdrawal_per_period = 50\n", "\n", "while money_in_bank > 0:\n", " print(f\"At the beginning of {year} you have ${money_in_bank:.2f} in the bank\")\n", " money_in_bank = money_in_bank - widthdrawal_per_period\n", " money_in_bank = money_in_bank * (1 + interest / 100)\n", " year = year + 1\n", " if year > 2117:\n", " print(\"I am pretty sure you will not be alive by then\")\n", " break\n", " print(f\"At the end of {year} you have ${money_in_bank:.2f} in the bank\")\n", " print(\"-----------------\")\n", "\n", "print(\"You have no money left (or you are dead)!\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Tea Cooling Example\n", "\n", "Here is another example, this time with the `continue` command. In the example below, we modify our \"tea cooling\" example to print the temperature only when temperature is exactly divisible by 5. If not, we use the `continue` command to skip executing the rest of the loop." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import time\n", "\n", "temperature = 133\n", "while temperature > 110: # first while loop code\n", " temperature = temperature - 1\n", " if temperature % 5 != 0: # If the temperature is not divisible by 5\n", " continue # We keep running the loop, but will not print\n", " # the temperature and have a delay\n", " time.sleep(0.5)\n", " print(temperature)\n", "\n", "print(\"The tea is cool enough.\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exercise" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write a program that receives user for three pieces of information as variables: \n", "* a starting balance, \n", "* a target balance, \n", "* and an interest rate (entered as 0.05 for 5%, for example)\n", "\n", "The program then outputs the number of years required for the starting balance to have grown larger than the target balance. While this can be computed directly mathematically, we want for this exercise to use a while loop to figure out the answer. The answer should just be a line stating something like: \"_To grow an initial investment of \\\\$1000 to \\\\$2000 at 5.0% will require `XX` years_\".\n", "\n", "Hint: You will need a variable to store the number of years that passed. You will also need a variable to hold the current balance in the account, as it grows over the years." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "starting = 1000\n", "target = 2000\n", "interest = 0.05\n", "\n", "# your code here" ] }, { "cell_type": "markdown", "metadata": { "solution2": "hidden", "solution2_first": true }, "source": [ "### Solution" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "solution2": "hidden" }, "outputs": [], "source": [ "starting = 1000\n", "target = 2000\n", "interest = 0.045\n", "\n", "# We introduce a variable to store the current amount of money we have\n", "current = starting\n", "# We also introduce a variable year to count the number of years that passed\n", "year = 0\n", "\n", "# We will keep increasing the current balance, year after year, until\n", "# the value of current surpases the target\n", "while current < target:\n", " # We increase the value of current, by adding interest\n", " current = current * (1 + interest)\n", " # Alternatively, you can write the above as\n", " # current += current * interest\n", " # current = current + current * interest\n", " # current *= 1+interest\n", "\n", " # We increase the year value, as a year has passed\n", " year = year + 1\n", "\n", " # We also print a message with the current balance\n", " # as this can be useful for debugging\n", " print(f\"After {year} years, you have ${current:.2f}\")\n", "\n", "# We are out of the loop, let's print how long it took:\n", "print(\n", " f\"To grow an initial investment of ${starting} to ${target} at {100*interest:.1f}% will require {year} years\"\n", ")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.2" } }, "nbformat": 4, "nbformat_minor": 1 }