{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Introduction to Python: Loops and Input Functions\n",
    "Here, we will explore other looping construct under Python, for example, <br>\n",
    "we have **while**, and we also illustrate how to allow user to input arguments into our program.\n",
    "\n",
    "**Created and updated by:** John C.S. Lui on August 9th, 2020.\n",
    "\n",
    "**<span style=\"color:red\"> Important note</span>:** *If you want to use and modify this notebook file, please acknowledge the author.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## While syntax\n",
    "\n",
    "## Initialize the condition\n",
    "flag == True\n",
    "\n",
    "## The while loop\n",
    "**while** flag:  &nbsp;    # execute the following statements until the flag becomes False<br>\n",
    "    &nbsp; &nbsp; &nbsp;&nbsp; # statement 1 <br>\n",
    "    &nbsp; &nbsp; &nbsp;&nbsp; # statement 2 <br>\n",
    "    &nbsp; &nbsp; &nbsp;&nbsp; # ........... <br>\n",
    "    &nbsp; &nbsp; &nbsp;&nbsp; # statement n <br>\n",
    "<p><p>\n",
    "* All **while** loop has an initial condition as true.\n",
    "* The **while** statement includes a condition to test.\n",
    "* All statements in the loop will be executed as long as the condition is true.\n",
    "* When the condition changes to False (within the statement loop), the loop stops\n",
    "* Codes that are defined after the **while** loop will be executed\n",
    "    \n",
    "<p><p>\n",
    "Let's illustrate it with some examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Computing the sum from 1 to upper_limit\n",
    "\n",
    "upper_limit = 10   # Define the upper limit\n",
    "\n",
    "sum = 0\n",
    "num = 1\n",
    "\n",
    "while num <= upper_limit :\n",
    "    sum = sum + num\n",
    "    print(\"The sum from 1 to\", num, \"is\", sum)\n",
    "    num = num + 1\n",
    "\n",
    "print(\"\\n**** The sum from 1 to\", upper_limit, \"is\", sum)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example\n",
    "A Fibonacci series is a series of numbers in which each number is the sum of the two preceding numbers. <br>\n",
    "For example, we have the following series 1, 1, 2, 3, 5, 8, etc.<br>\n",
    "Use the **while** loop to generate a series for up to *upper_limit* numbers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "upper_limit = 30   # set upper limit for the Fibonacci series\n",
    "previous_num = 0\n",
    "current_num = 1\n",
    "next_num  = 0\n",
    "index = 1\n",
    "\n",
    "print(\"The Fibonacci series: \" + str(1) +\",\", end=\" \")  # instead of newline, use \" \" !!!!!\n",
    "while index <= upper_limit:\n",
    "    next_num = previous_num + current_num          # generate next number to print\n",
    "    if index < upper_limit:                        # if not last number, generate \",\" and \" \"\n",
    "        print (str(next_num) +\",\", end=\" \")\n",
    "    else:                                          # if last number, generate \".\" and a newline\n",
    "        print (str(next_num) + \".\")\n",
    "    previous_num = current_num                     # change previous and current number\n",
    "    current_num = next_num\n",
    "    index = index + 1                              # modifying the condition of while loop\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercise\n",
    "Use the **while** loop to generate the first 10 numbers of 2^n, where n is an integer with an upper bound."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Allowing user input\n",
    "We have learnt how to generate output, but how do we accept input by the users of the program?  \n",
    "It is by the *input()* function. Let's illustrate."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## General syntax for input\n",
    "\n",
    "variable = input ('Message you want to show: \") <br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create a list of teachers in the first floor\n",
    "teachers = ['john c. s. lui', 'patrick p. c. lee', 'james cheng', 'wei meng']\n",
    "\n",
    "# Ask the user to input a name\n",
    "name = input('Enter a name of the teacher:')\n",
    "\n",
    "# Now check whether the name is in the list\n",
    "\n",
    "if name in teachers:\n",
    "    print(\"Yes, \", name.title(), \"is in the list\")\n",
    "else:\n",
    "    print(\"Sorry, \", name.title(), \"is NOT in the list\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Note on *input()* and *raw_input()* in Python 2.7\n",
    "\n",
    "In Python 3, you use *input()* to get a **string** back.  In Python 2.7,\n",
    "the counter-part is *raw_input()*\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercise\n",
    "\n",
    "Write a program with the following:\n",
    "- Create a list of your favorite sports\n",
    "- Print out your favorite sports \n",
    "- Prompt user to enter another sport\n",
    "- If the sport is not in the list, append it to the list, else print out an error message\n",
    "- display the content of the current list"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Keep adding new names into the list\n",
    "teachers = []   # create an empty list\n",
    "\n",
    "name = ''       # initialize the name\n",
    "\n",
    "while name.upper() != 'QUIT':\n",
    "    name = input ('Input the name of a professor whose office is on the 1st floor: ')\n",
    "    if name.upper() != 'QUIT':\n",
    "        teachers.append(name)\n",
    "        print(\"Right now the list is:\", teachers)\n",
    "\n",
    "print(\"Done!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Give the user some context for \"menu input\".\n",
    "print(\"\\nWelcome to the nature center. What would you like to do?\")\n",
    "\n",
    "# Set an initial value for choice other than the value for 'quit'.\n",
    "choice = ''\n",
    "\n",
    "# Start a loop that runs until the user enters the value for 'quit'.\n",
    "while choice != 'q':\n",
    "    # Give all the choices in a series of print statements.\n",
    "    print(\"\\n[1] Enter 1 to take a course in Python.\")\n",
    "    print(\"[2] Enter 2 to take a course in C++.\")\n",
    "    print(\"[3] Enter 3 to take a course in Java.\")\n",
    "    print(\"[q] Enter q to quit.\")\n",
    "    \n",
    "    # Ask for the user's choice.\n",
    "    choice = input(\"\\nWhich course you like to take ? \")\n",
    "    \n",
    "    # Respond to the user's choice.\n",
    "    if choice == '1':\n",
    "        print(\"\\nPython is great. Have fun!\\n\")\n",
    "    elif choice == '2':\n",
    "        print(\"\\nC++ is also a good language. It has good performance!\\n\")\n",
    "    elif choice == '3':\n",
    "        print(\"\\nYou want to take Java? Are you sure?\\n\")\n",
    "    elif choice == 'q':\n",
    "        print(\"\\nOK, I know you have enough programming languages\\n\")\n",
    "    else:\n",
    "        print(\"\\nI don't understand your choice, please try again.\\n\")\n",
    "        \n",
    "# Print a message that we are all finished.\n",
    "print(\"Thanks again, Chiao.\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Example of using while loop to go through a list\n",
    "\n",
    "# Start with a list of teachers, and an empty list of smart teachers.\n",
    "teachers = ['john c. s. lui', 'patrick p. c. lee', 'james cheng', 'wei meng']\n",
    "smart_teachers = []\n",
    "\n",
    "# Let's go through the teachers\n",
    "while len(teachers) != 1:  # process all but the first item in the teacher list\n",
    "    \n",
    "    # Get the last teachers from the list, put he/she in the smart_teaher list\n",
    "    current_teacher = teachers.pop()\n",
    "    print(\"We have %s from the list!\" % current_teacher.title())\n",
    "    \n",
    "    # Move it to the smart_teachers list\n",
    "    smart_teachers.append(current_teacher)\n",
    "    \n",
    "# Prove that we have finished confirming all users.\n",
    "print(\"\\nSmart teachers are: \")\n",
    "for people in smart_teachers:\n",
    "    print('- ' + people.title())\n",
    "    \n",
    "print(\"\\nDumb teachers are:\")\n",
    "for people in teachers:\n",
    "    print('- ' + people.title())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Final examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# A program with while \n",
    "a, b = 0, 1         # parallel assignment\n",
    "while b < 10:\n",
    "    print('a = ', a, '; b = ', b)\n",
    "    a, b = b, a+b\n",
    "print ('end')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Nested while"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = 0\n",
    "while x < 3:   # outer loop\n",
    "    y = 0\n",
    "    while y < 3:   # inner loop\n",
    "        print(\"x =\", x, \";\", \"y =\", y)\n",
    "        y = y+1\n",
    "    x = x+1"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Else Clause with Python While Loop\n",
    "In Python, we can add an optional `else` clause after the end of `while` loop.\n",
    "\n",
    "The code inside the `else` clause would **always** run but after the while loop finishes execution. The **one situation** when it won�脌 run is if the loop exits after a `break` statement.\n",
    "\n",
    "Using the else clause would make sense when you wish to execute a set of instructions after the while loop ends, i.e., without using a break statement.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def while_else_demo():\n",
    "\n",
    "    count = 0\n",
    "    while count < 5 :\n",
    "        num = int(input(\"Enter number between 0-100?\"))\n",
    "        if (num < 0) or (num > 100):\n",
    "            print(\"Aborted while: You've entered an invalid number.\")\n",
    "            break\n",
    "        count += 1\n",
    "    else:\n",
    "        print(\"While loop ended gracefully.\")\n",
    "\n",
    "while_else_demo()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercise\n",
    "\n",
    "Let's see whether you really understand the *while* structure in Python"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# What is the output for the following snippet?\n",
    "\n",
    "x = 0\n",
    "\n",
    "while False :\n",
    "    x = x + 1\n",
    "    print('So good to see John C.S. Lui.')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# What is the output for the following snippet?\n",
    "\n",
    "x=2\n",
    "while x<=10 :\n",
    "    print(x)\n",
    "    x = x + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# What is the output for the following snippet?\n",
    "\n",
    "#custom debug print function\n",
    "def dbgprint(x):\n",
    "    if debug == True:\n",
    "        print(x)\n",
    "\n",
    "#ask user to enter the range values\n",
    "debug = False\n",
    "r1 = int(input(\"Enter the starting range value?\"))\n",
    "r2 = int(input(\"Enter the ending range value?\"))\n",
    "         \n",
    "dbgprint(\"Range: %d - %d\" % (r1, r2))\n",
    "\n",
    "num = r1 + 1\n",
    "count = 0\n",
    "\n",
    "while num < r2:\n",
    "    dbgprint(\"num: %d\" % (num))\n",
    "    res = num % 2\n",
    "    dbgprint(\"res: %d\" % (res))\n",
    "    if (num % 2) > 0:\n",
    "        count += 1\n",
    "    num += 1\n",
    "\n",
    "print(\"Odd count: %d\" % (count))"
   ]
  },
  {
   "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.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}