{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Iteration"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
},
"tags": [
"remove-cell"
]
},
"source": [
"**CS1302 Introduction to Computer Programming**\n",
"___"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2020-11-27T11:20:04.656873Z",
"start_time": "2020-11-27T11:20:04.651575Z"
},
"slideshow": {
"slide_type": "fragment"
},
"tags": [
"remove-cell"
]
},
"outputs": [],
"source": [
"%reload_ext mytutor\n",
"from ipywidgets import interact"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Motivation"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Many tasks are repetitive:\n",
"- To print from 1 up to a user-specified number *arbitrarily large*.\n",
"- To compute the maximum of a sequence of numbers *arbitrarily long*.\n",
"- To get user input *repeatedly until* it is within a certain range."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**How to write code to perform repetitive tasks?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"E.g., can you complete the following code to print from 1 up to a user-specified number?"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:15:26.295495Z",
"start_time": "2020-09-12T02:15:25.202198Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 400\n",
"num = int(input(\">\"))\n",
"if 1 <= num:\n",
" print(1)\n",
"if 2 <= num:\n",
" print(2)\n",
"if 3 <= num:\n",
" print(3)\n",
"# YOUR CODE HERE"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"*Code duplication* is not good because: \n",
"- Duplicate code is hard to read/write/maintain. \n",
" (Imagine what you need to do to change some code.)\n",
"- The number of repetitions may not be known before runtime."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Instead, programmers write a *loop* which specifies a piece of code to be executed iteratively."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## For Loop"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Iterate over a sequence"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**How to print from 1 up to 4?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"We can use a [`for` statement](https://docs.python.org/3.3/tutorial/controlflow.html#for-statements) as follows:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-21T14:40:09.733612Z",
"start_time": "2020-09-21T14:40:09.713133Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 300\n",
"for i in 1, 2, 3, 4:\n",
" print(i)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- `i` is automatically assigned to each element in the sequence `1, 2, 3, 4` one-by-one from left to right.\n",
"- After each assignment, the body `print(i)` is executed. \n",
"\n",
"N.b., if `i` is defined before the for loop, its value will be overwritten. "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The assignment is not restricted to integers and can also be a tuple assignment. The expression list can also be an [iterable object](https://docs.python.org/3.3/glossary.html#term-iterable) instead."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-21T14:41:01.344433Z",
"start_time": "2020-09-21T14:41:01.333522Z"
},
"scrolled": true,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 l\n",
"1 o\n",
"2 o\n",
"3 p\n"
]
}
],
"source": [
"tuples = (0, \"l\"), (1, \"o\"), (2, \"o\"), (3, \"p\")\n",
"for i, c in tuples:\n",
" print(i, c)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"An even shorter code..."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-21T14:41:08.799668Z",
"start_time": "2020-09-21T14:41:08.790110Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 l\n",
"1 o\n",
"2 o\n",
"3 p\n"
]
}
],
"source": [
"for i, c in enumerate(\"loop\"):\n",
" print(i, c)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Iterate over a range"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**How to print up to a user-specified number?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"We can use [`range`](https://docs.python.org/3/library/stdtypes.html#range):"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:15:06.124643Z",
"start_time": "2020-09-12T02:15:03.879119Z"
},
"slideshow": {
"slide_type": "-"
},
"tags": [
"remove-output"
]
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 300\n",
"stop = int(input(\">\")) + 1\n",
"for i in range(stop):\n",
" print(i)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Why add 1 to the user input number?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"`range(stop)` generates a sequence of integers from `0` up to *but excluding* `stop`."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**How to start from a number different from `0`?**"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:16:04.698262Z",
"start_time": "2020-09-12T02:16:04.691449Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"2\n",
"3\n",
"4\n"
]
}
],
"source": [
"for i in range(1, 5):\n",
" print(i)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**What about a step size different from `1`?**"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:16:11.858443Z",
"start_time": "2020-09-12T02:16:11.852378Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"2\n",
"4\n"
]
}
],
"source": [
"for i in range(0, 5, 2): print(i) # starting number must also be specified. Why?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** How to count down from 4 to 0? Try doing it without addition or subtraction."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:16:21.291051Z",
"start_time": "2020-09-12T02:16:21.284902Z"
},
"nbgrader": {
"grade": false,
"grade_id": "count-down",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"4\n",
"3\n",
"2\n",
"1\n",
"0\n"
]
}
],
"source": [
"### BEGIN SOLUTION\n",
"for i in range(4, -1, -1):\n",
" print(i)\n",
"### END SOLUTION"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** Print from `0` to a user-specified number but in steps of `0.5`. \n",
"E.g., if the user inputs `2`, the program should print:\n",
"```\n",
"0.0\n",
"0.5\n",
"1.0\n",
"1.5\n",
"2.0\n",
"```\n",
"\n",
"*Note:* `range` only accepts integer arguments."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:16:56.696693Z",
"start_time": "2020-09-12T02:16:53.508468Z"
},
"nbgrader": {
"grade": false,
"grade_id": "fractional-step",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
},
"scrolled": true,
"slideshow": {
"slide_type": "-"
},
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 300\n",
"num = int(input(\">\"))\n",
"### BEGIN SOLUTION\n",
"for i in range(0, 2 * num + 1, 1):\n",
" print(i / 2)\n",
"### END SOLUTION"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
},
"tags": []
},
"source": [
"**Exercise** How to print the character `'*'` repeatedly for `m` rows and `n` columns? \n",
"Try using a *nested for loop*: Write a for loop (*inner loop*) inside the body of another for loop (*outer loop*)."
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:17:26.930731Z",
"start_time": "2020-09-12T02:17:26.882085Z"
},
"nbgrader": {
"grade": false,
"grade_id": "nested-loop",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "1de9ee5aa05d4684903224749dd4bab3",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(IntSlider(value=5, description='m', max=10), IntSlider(value=5, description='n', max=10)…"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"@interact(m=(0, 10), n=(0, 10))\n",
"def draw_rectangle(m=5, n=5):\n",
" ### BEGIN SOLUTION\n",
" for i in range(m):\n",
" for j in range(n):\n",
" print(\"*\", end=\"\")\n",
" print()\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Iterate over a string"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**What does the following do?**"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-21T14:44:52.568078Z",
"start_time": "2020-09-21T14:44:52.560424Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 300\n",
"for character in \"loop\":\n",
" print(character)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"`str` is a [sequence type](https://docs.python.org/3/library/stdtypes.html#textseq) because a string is regarded as a sequence of characters.\n",
"- The function [`len`](https://docs.python.org/3/library/functions.html#len) can return the length of a string.\n",
"- The indexing operator `[]` can return the character of a string at a specified location."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:19:37.057820Z",
"start_time": "2020-09-12T02:19:37.050524Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"length: 4\n",
"characters: l o o p\n"
]
}
],
"source": [
"message = \"loop\"\n",
"print(\"length:\", len(message))\n",
"print(\"characters:\", message[0], message[1], message[2], message[3])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"We can also iterate over a string as follows although it is less elegant:"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:20:05.326619Z",
"start_time": "2020-09-12T02:20:05.320063Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"l\n",
"o\n",
"o\n",
"p\n"
]
}
],
"source": [
"for i in range(len(\"loop\")):\n",
" print(\"loop\"[i])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** Print a string assigned to `message` in reverse. \n",
"E.g., `'loop'` should be printed as `'pool'`. Try using the for loop and indexing operator."
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:20:21.886787Z",
"start_time": "2020-09-12T02:20:21.855189Z"
},
"nbgrader": {
"grade": false,
"grade_id": "reverse-string",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "3e1ef37940a5449b8d0efe0548e1221e",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Text(value='loop', description='message'), Output()), _dom_classes=('widget-interact',))"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"@interact(message=\"loop\")\n",
"def reverse_print(message):\n",
" ### BEGIN SOLUTION\n",
" for i in range(len(message)):\n",
" print(message[-i - 1], end=\"\")\n",
" print('') # in case message is empty\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## While Loop"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**How to ensure user input is non-empty?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Python provides the [`while` statement](https://docs.python.org/3/reference/compound_stmts.html#while) to loop until a specified condition is false."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:21:16.272650Z",
"start_time": "2020-09-12T02:21:10.921514Z"
},
"slideshow": {
"slide_type": "-"
},
"tags": [
"remove-output"
]
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 300\n",
"while not input(\"Input something please:\"):\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"As long as the condition after `while` is true, the body gets executed repeatedly. In the above example,\n",
"- if user inputs nothing, \n",
"- `input` returns an empty string `''`, which is [regarded as `False`](https://docs.python.org/3/reference/expressions.html#booleans), and so\n",
"- the looping condition `not input('...')` is `True`."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Is it possible to use a for loop instead of a while loop?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- Not without hacks because the for loop is a *definite loop* which has a definite number of iterations before the execution of the loop.\n",
"- `while` statement is useful for an *indefinite loop* where the number of iterations is unknown before the execution of the loop."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"It is possible, however, to replace a for loop by a while loop. \n",
"E.g., the following code prints from `0` to `4` using a while loop instead of a for loop."
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:23:02.642597Z",
"start_time": "2020-09-12T02:23:02.636660Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0\n",
"1\n",
"2\n",
"3\n",
"4\n"
]
}
],
"source": [
"i = 0\n",
"while i <= 4:\n",
" print(i)\n",
" i += 1"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- A while loop may not be as elegant, c.f., \n",
" ```Python\n",
" for i in range(5): print(i)\n",
" ```\n",
"- but it can be as efficient."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Should we just use while loop?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Consider using the following while loop to print from `0` to a user-specified value."
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:28:59.075109Z",
"start_time": "2020-09-12T02:28:51.272451Z"
},
"scrolled": true,
"slideshow": {
"slide_type": "-"
},
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 310\n",
"num = int(input(\">\"))\n",
"i = 0\n",
"while i != num + 1:\n",
" print(i)\n",
" i += 1"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Exercise** Is the above while loop doing the same thing as the for loop below?"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:24:58.735012Z",
"start_time": "2020-09-12T02:24:55.351536Z"
},
"slideshow": {
"slide_type": "-"
},
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 300\n",
"for i in range(int(input(\">\")) + 1):\n",
" print(i)"
]
},
{
"cell_type": "markdown",
"metadata": {
"nbgrader": {
"grade": true,
"grade_id": "infinite-loop",
"locked": false,
"points": 0,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"source": [
"When the input corresponds to an integer $\\leq -2$,\n",
"- the while loop becomes an infinite loop, but\n",
"- the for loop terminates without printing any number."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"We have to be careful not to create unintended *infinite loops*. \n",
"The computer can't always detect whether there is an infinite loop. ([Why not?](https://en.wikipedia.org/wiki/Halting_problem))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Break/Continue/Else Constructs of a Loop"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Breaking out of a loop"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Is the following an infinite loop?**"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:31:40.571589Z",
"start_time": "2020-09-12T02:31:34.464485Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 310\n",
"while True:\n",
" message = input(\"Input something please:\")\n",
" if message:\n",
" break\n",
"print(\"You entered:\", message)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"The loop is terminated by the [`break` statement](https://docs.python.org/3/tutorial/controlflow.html#break-and-continue-statements-and-else-clauses-on-loops) when user input is non-empty."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Why is the `break` statement useful?**"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
" Recall the earlier `while` loop:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:32:29.802277Z",
"start_time": "2020-09-12T02:32:24.259120Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 300\n",
"while not input(\"Input something please:\"):\n",
" pass"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"This while loop is not useful because it does not store the user input."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Is the `break` statement strictly necessary?** "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- We can use the assignment expression but it is not supported by Python version <3.8."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- We can avoid `break` statement by using *flags*, which are boolean variables for flow control:"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:33:25.270345Z",
"start_time": "2020-09-12T02:33:20.380440Z"
},
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 350\n",
"has_no_input = True\n",
"while has_no_input:\n",
" message = input(\"Input something please:\")\n",
" if message:\n",
" has_no_input = False\n",
"print(\"You entered:\", message)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Using flags makes the program more readable, and we can use multiple flags for more complicated behavior. \n",
"The variable names for flags are often `is_...`, `has_...`, etc."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Continue to Next Iteration"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**What does the following program do? \n",
"Is it an infinite loop?**"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:37:31.562800Z",
"start_time": "2020-09-12T02:35:51.649703Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 310\n",
"while True:\n",
" message = input(\"Input something please:\")\n",
" if not message:\n",
" continue\n",
" print(\"You entered:\", message)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- The program repeatedly asks the user for input.\n",
"- If the input is empty, the `continue` statement will skip to the next iteration.\n",
"- The loop can only be terminated by interrupting the kernel.\n",
"- Such an infinite loop can be useful. E.g., your computer clock continuously updates the current time."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Exercise** Is the `continue` statement strictly necessary? Can you rewrite the above program without the `continue` statement? "
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-12T02:37:39.345421Z",
"start_time": "2020-09-12T02:37:32.939865Z"
},
"nbgrader": {
"grade": false,
"grade_id": "avoid-continue",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 350\n",
"while True:\n",
" message = input(\"Input something please:\")\n",
" ### BEGIN SOLUTION\n",
" if message:\n",
" print(\"You entered:\", message)\n",
" ### END SOLUTION"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Else construct for a loop"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"The following program checks whether a number is composite, namely, \n",
"- a positive integer that is\n",
"- a product of two strictly smaller positive integers."
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-21T14:53:16.423937Z",
"start_time": "2020-09-21T14:53:16.388975Z"
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "81f8ceaaf51d4066ac48235c5f654406",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Text(value='1', description='num'), Output()), _dom_classes=('widget-interact',))"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"@interact(num=\"1\")\n",
"def check_composite(num):\n",
" if num.isdigit():\n",
" num = int(num)\n",
" for divisor in range(2, num): # why starts from 2 instead of 1\n",
" if num % divisor:\n",
" continue # where will this go?\n",
" else:\n",
" print(\"It is composite.\")\n",
" break # where will this go?\n",
" else:\n",
" print(\"It is not composite.\") # how to get here?\n",
" else:\n",
" print(\"Not a positive integer.\") # how to get here?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Exercise** There are three else claues in the earlier code. Which one is for the loop?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"- The second else clause that `print('It is not composite.')`.\n",
"- The clause is called when there is no divisor found in the range from `2` to `num`."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"If program flow is confusing, try stepping through executation:"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/html": [
"\n",
" \n",
" "
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"%%mytutor -h 520\n",
"def check_composite(num):\n",
" if num.isdigit():\n",
" num = int(num)\n",
" for divisor in range(2, num):\n",
" if num % divisor:\n",
" continue\n",
" else:\n",
" print(\"It is composite.\")\n",
" break\n",
" else:\n",
" print(\"It is not composite.\")\n",
" else:\n",
" print(\"Not a positive integer.\")\n",
"\n",
"\n",
"check_composite(\"1\")\n",
"check_composite(\"2\")\n",
"check_composite(\"3\")\n",
"check_composite(\"4\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- In addition to using `continue` and `break` in an elegant way, \n",
"- the code also uses an else clause that is executed only when the loop terminates *normally* not by `break`."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"**Exercise** Convert the for loop to a while loop. Try to make the code as efficient as possible with less computation and storage."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"ExecuteTime": {
"end_time": "2020-09-27T08:55:33.231171Z",
"start_time": "2020-09-27T08:55:33.193049Z"
},
"nbgrader": {
"grade": false,
"grade_id": "for-to-while",
"locked": false,
"schema_version": 3,
"solution": true,
"task": false
},
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "e01bb8e34c784f38a32115455b1c883e",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"interactive(children=(Text(value='1', description='num'), Output()), _dom_classes=('widget-interact',))"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"@interact(num=\"1\")\n",
"def check_composite(num):\n",
" if num.isdigit():\n",
" num = int(num)\n",
" ### BEGIN SOLUTION\n",
" # for divisor in range(2,num):\n",
" divisor = int(num ** 0.5) # biggest possible divisor\n",
" while divisor > 1:\n",
" if num % divisor:\n",
" divisor -= 1 # why not go from 2 to int(num ** 0.5)?\n",
" else:\n",
" print(\"It is composite.\")\n",
" break\n",
" else:\n",
" print(\"It is not composite.\")\n",
" ### END SOLUTION\n",
" else:\n",
" print(\"Not a positive integer.\")"
]
}
],
"metadata": {
"celltoolbar": "Slideshow",
"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.8.8"
},
"latex_envs": {
"LaTeX_envs_menu_present": true,
"autoclose": false,
"autocomplete": true,
"bibliofile": "biblio.bib",
"cite_by": "apalike",
"current_citInitial": 1,
"eqLabelWithNumbers": true,
"eqNumInitial": 1,
"hotkeys": {
"equation": "Ctrl-E",
"itemize": "Ctrl-I"
},
"labels_anchors": false,
"latex_user_defs": false,
"report_style_numbering": false,
"user_envs_cfg": false
},
"rise": {
"enable_chalkboard": true,
"scroll": true,
"theme": "white"
},
"toc": {
"base_numbering": 1,
"nav_menu": {
"height": "195px",
"width": "330px"
},
"number_sections": true,
"sideBar": true,
"skip_h1_title": true,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {
"height": "454.418px",
"left": "1533px",
"top": "110.284px",
"width": "435.327px"
},
"toc_section_display": true,
"toc_window_display": false
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"state": {},
"version_major": 2,
"version_minor": 0
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}