Commit c2508662 authored by Wichit Sombat's avatar Wichit Sombat

Merge branch 'paul'

parents ec41a6d2 ac6f230a
......@@ -33,21 +33,6 @@
"| Declarative | program logic (fourth-gen) | SQL, regex, CSS, Prolog |\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"### Textbook: PPICS\n",
"![screenshot](http://mcsp.wartburg.edu/zelle/python/ppics3/cover_small.png)\n",
"> [An Introduction to Computer Science 2nd Edition - John M. Zelle, Ph.D.](http://www.leetupload.com/database/Misc/Papers/Python%20programming%20-%20An%20introduction%20to%20computer%20science%202002.pdf)\n",
"\n",
"> [Slides](http://mcsp.wartburg.edu/zelle/python/ppics3/slides/)"
]
},
{
"cell_type": "markdown",
"metadata": {
......@@ -79,8 +64,8 @@
"source": [
"### 1. Computers and Programs [Lecture](./01 Computers and Programs.ipynb) [Lab](./01 Computers and Programs Lab.ipynb)\n",
"\n",
"| Lectures | Laboratory |\n",
"|:----------------------------|:------------------------|\n",
"| Lectures | Laboratory |\n",
"|:---------------------------- |:------------------------|\n",
"| 1. The Universal Machine | 1. Anaconda Installation |\n",
"| 2. Program Power | 2. Python Shell |\n",
"| 3. What is Computer Science? | 3. IPython Shell |\n",
......@@ -364,7 +349,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.1"
"version": "3.5.2"
}
},
"nbformat": 4,
......
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# If Statements"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"By allowing you to respond selectively to different situations and conditions, if statements open up whole new possibilities for your programs. In this section, you will learn how to test for certain conditions, and then respond in appropriate ways to those conditions."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"# <a name=\"top\"></a>Contents\n",
"\n",
"- [What is an *if* statement?](#what)\n",
" - [Example](#example)\n",
"- [Logical tests](#logical_tests)\n",
" - [Equality](#equality)\n",
" - [Inequality](#inequality)\n",
" - [Other inequalities](#other_inequalities)\n",
" - [Checking if an item is in a list](#in_list)\n",
" - [Exercises](#exercises_logical_tests)\n",
"- [The if-elif...else chain](#if-elif-else)\n",
" - [Simple if statements](#simple_if)\n",
" - [if-else statements](#if-else)\n",
" - [if-elif...else chains](#if-elif-else_chains)\n",
" - [Exercises](#exercises_if-elif-else)\n",
"- [More than one passing test](#more_than_one)\n",
"- [True and False values](#true_false)\n",
"- [Overall Challenges](#overall_challenges)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='what'></a>What is an *if* statement?\n",
"===\n",
"An *if* statement tests for a condition, and then responds to that condition. If the condition is true, then whatever action is listed next gets carried out. You can test for multiple conditions at the same time, and respond appropriately to each condition."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='example'></a>Example\n",
"---\n",
"Here is an example that shows a number of the desserts I like. It lists those desserts, but lets you know which one is my favorite."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I like ice cream.\n",
"I like chocolate.\n",
"Apple Crisp is my favorite dessert!\n",
"I like cookies.\n"
]
}
],
"source": [
"# A list of desserts I like.\n",
"desserts = ['ice cream', 'chocolate', 'apple crisp', 'cookies']\n",
"favorite_dessert = 'apple crisp'\n",
"\n",
"# Print the desserts out, but let everyone know my favorite dessert.\n",
"for dessert in desserts:\n",
" if dessert == favorite_dessert:\n",
" # This dessert is my favorite, let's let everyone know!\n",
" print(\"%s is my favorite dessert!\" % dessert.title())\n",
" else:\n",
" # I like these desserts, but they are not my favorite.\n",
" print(\"I like %s.\" % dessert)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"#### What happens in this program?\n",
"\n",
"- The program starts out with a list of desserts, and one dessert is identified as a favorite.\n",
"- The for loop runs through all the desserts.\n",
"- Inside the for loop, each item in the list is tested.\n",
" - If the current value of *dessert* is equal to the value of *favorite_dessert*, a message is printed that this is my favorite.\n",
" - If the current value of *dessert* is not equal to the value of *favorite_dessert*, a message is printed that I just like the dessert.\n",
" \n",
"You can test as many conditions as you want in an if statement, as you will see in a little bit."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='logical_tests'></a>Logical Tests\n",
"===\n",
"Every if statement evaluates to *True* or *False*. *True* and *False* are Python keywords, which have special meanings attached to them. You can test for the following conditions in your if statements:\n",
"\n",
"- [equality](#equality) (==)\n",
"- [inequality](#inequality) (!=)\n",
"- [other inequalities](#other_inequalities)\n",
" - greater than (>)\n",
" - greater than or equal to (>=)\n",
" - less than (<)\n",
" - less than or equal to (<=)\n",
"- [You can test if an item is **in** a list.](#in_list)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Whitespace\n",
"Remember [learning about](04_lists_tuples.html#pep8) PEP 8? There is a [section of PEP 8](http://www.python.org/dev/peps/pep-0008/#other-recommendations) that tells us it's a good idea to put a single space on either side of all of these comparison operators. If you're not sure what this means, just follow the style of the examples you see below."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='equality'></a>Equality\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Two items are *equal* if they have the same value. You can test for equality between numbers, strings, and a number of other objects which you will learn about later. Some of these results may be surprising, so take a careful look at the examples below."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"In Python, as in many programming languages, two equals signs tests for equality."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"**Watch out!** Be careful of accidentally using one equals sign, which can really throw things off because that one equals sign actually sets your item to the value you are testing for!"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"# Examples"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"5 == 5"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 == 5 "
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"5 == 5.0"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"'eric' == 'eric'"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"'Eric' == 'eric'"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"'Eric'.lower() == 'eric'.lower()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"'5' == 5"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"'5' == str(5)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='inequality'></a>Inequality\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Two items are *inequal* if they do not have the same value. In Python, we test for inequality using the exclamation point and one equals sign.\n",
"\n",
"Sometimes you want to test for equality and if that fails, assume inequality. Sometimes it makes more sense to test for inequality directly."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 != 5"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"5 != 5"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"'Eric' != 'eric'"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='other_inequalities'></a>Other Inequalities\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### greater than"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"5 > 3"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### greater than or equal to"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"5 >= 3"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 >= 3"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### less than"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 < 5"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### less than or equal to"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 <= 5"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"3 <= 3"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='in_list'></a>Checking if an item is **in** a list\n",
"---\n",
"You can check if an item is in a list using the **in** keyword."
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"vowels = ['a', 'e', 'i', 'o', 'u']\n",
"'a' in vowels"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"vowels = ['a', 'e', 'i', 'o', 'u']\n",
"'b' in vowels"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_logical_tests'></a>Exercises\n",
"---\n",
"#### True and False\n",
"- Write a program that consists of at least ten lines, each of which has a logical statement on it. The output of your program should be 5 **True**s and 5 **False**s.\n",
"- Note: You will probably need to write `print(5 > 3)`, not just `5 > 3`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 5.1 : True and False\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='if-elif-else'></a>The if-elif...else chain\n",
"===\n",
"You can test whatever series of conditions you want to, and you can test your conditions in any combination you want."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='simple_if'></a>Simple if statements\n",
"---\n",
"The simplest test has a single **if** statement, and a single statement to execute if the condition is **True**."
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wow, we have a lot of dogs here!\n"
]
}
],
"source": [
"dogs = ['willie', 'hootz', 'peso', 'juno']\n",
"\n",
"if len(dogs) > 3:\n",
" print(\"Wow, we have a lot of dogs here!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"In this situation, nothing happens if the test does not pass."
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"dogs = ['willie', 'hootz']\n",
"\n",
"if len(dogs) > 3:\n",
" print(\"Wow, we have a lot of dogs here!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Notice that there are no errors. The condition `len(dogs) > 3` evaluates to False, and the program moves on to any lines after the **if** block."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='if-else'></a>if-else statements\n",
"---\n",
"Many times you will want to respond in two possible ways to a test. If the test evaluates to **True**, you will want to do one thing. If the test evaluates to **False**, you will want to do something else. The **if-else** structure lets you do that easily. Here's what it looks like:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wow, we have a lot of dogs here!\n"
]
}
],
"source": [
"dogs = ['willie', 'hootz', 'peso', 'juno']\n",
"\n",
"if len(dogs) > 3:\n",
" print(\"Wow, we have a lot of dogs here!\")\n",
"else:\n",
" print(\"Okay, this is a reasonable number of dogs.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Our results have not changed in this case, because if the test evaluates to **True** only the statements under the **if** statement are executed. The statements under **else** area only executed if the test fails:"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Okay, this is a reasonable number of dogs.\n"
]
}
],
"source": [
"dogs = ['willie', 'hootz']\n",
"\n",
"if len(dogs) > 3:\n",
" print(\"Wow, we have a lot of dogs here!\")\n",
"else:\n",
" print(\"Okay, this is a reasonable number of dogs.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"The test evaluated to **False**, so only the statement under `else` is run."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='if-elif-else_chains'></a>if-elif...else chains\n",
"---\n",
"Many times, you will want to test a series of conditions, rather than just an either-or situation. You can do this with a series of if-elif-else statements\n",
"\n",
"There is no limit to how many conditions you can test. You always need one if statement to start the chain, and you can never have more than one else statement. But you can have as many elif statements as you want."
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Holy mackerel, we might as well start a dog hostel!\n"
]
}
],
"source": [
"dogs = ['willie', 'hootz', 'peso', 'monty', 'juno', 'turkey']\n",
"\n",
"if len(dogs) >= 5:\n",
" print(\"Holy mackerel, we might as well start a dog hostel!\")\n",
"elif len(dogs) >= 3:\n",
" print(\"Wow, we have a lot of dogs here!\")\n",
"else:\n",
" print(\"Okay, this is a reasonable number of dogs.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"It is important to note that in situations like this, only the first test is evaluated. In an if-elif-else chain, once a test passes the rest of the conditions are ignored."
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Wow, we have a lot of dogs here!\n"
]
}
],
"source": [
"dogs = ['willie', 'hootz', 'peso', 'monty']\n",
"\n",
"if len(dogs) >= 5:\n",
" print(\"Holy mackerel, we might as well start a dog hostel!\")\n",
"elif len(dogs) >= 3:\n",
" print(\"Wow, we have a lot of dogs here!\")\n",
"else:\n",
" print(\"Okay, this is a reasonable number of dogs.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The first test failed, so Python evaluated the second test. That test passed, so the statement corresponding to `len(dogs) >= 3` is executed."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Okay, this is a reasonable number of dogs.\n"
]
}
],
"source": [
"dogs = ['willie', 'hootz']\n",
"\n",
"if len(dogs) >= 5:\n",
" print(\"Holy mackerel, we might as well start a dog hostel!\")\n",
"elif len(dogs) >= 3:\n",
" print(\"Wow, we have a lot of dogs here!\")\n",
"else:\n",
" print(\"Okay, this is a reasonable number of dogs.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"In this situation, the first two tests fail, so the statement in the else clause is executed. Note that this statement would be executed even if there are no dogs at all:"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Okay, this is a reasonable number of dogs.\n"
]
}
],
"source": [
"dogs = []\n",
"\n",
"if len(dogs) >= 5:\n",
" print(\"Holy mackerel, we might as well start a dog hostel!\")\n",
"elif len(dogs) >= 3:\n",
" print(\"Wow, we have a lot of dogs here!\")\n",
"else:\n",
" print(\"Okay, this is a reasonable number of dogs.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Note that you don't have to take any action at all when you start a series of if statements. You could simply do nothing in the situation that there are no dogs by replacing the `else` clause with another `elif` clause:"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"###highlight=[8]\n",
"dogs = []\n",
"\n",
"if len(dogs) >= 5:\n",
" print(\"Holy mackerel, we might as well start a dog hostel!\")\n",
"elif len(dogs) >= 3:\n",
" print(\"Wow, we have a lot of dogs here!\")\n",
"elif len(dogs) >= 1:\n",
" print(\"Okay, this is a reasonable number of dogs.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"In this case, we only print a message if there is at least one dog present. Of course, you could add a new `else` clause to respond to the situation in which there are no dogs at all:"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"I wish we had a dog here.\n"
]
}
],
"source": [
"###highlight=[10,11]\n",
"dogs = []\n",
"\n",
"if len(dogs) >= 5:\n",
" print(\"Holy mackerel, we might as well start a dog hostel!\")\n",
"elif len(dogs) >= 3:\n",
" print(\"Wow, we have a lot of dogs here!\")\n",
"elif len(dogs) >= 1:\n",
" print(\"Okay, this is a reasonable number of dogs.\")\n",
"else:\n",
" print(\"I wish we had a dog here.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"As you can see, the if-elif-else chain lets you respond in very specific ways to any given situation."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_if-elif-else'></a>Exercises\n",
"---\n",
"#### Three is a Crowd\n",
"- Make a list of names that includes at least four people.\n",
"- Write an if test that prints a message about the room being crowded, if there are more than three people in your list.\n",
"- Modify your list so that there are only two people in it. Use one of the methods for removing people from the list, don't just redefine the list.\n",
"- Run your if test again. There should be no output this time, because there are less than three people in the list.\n",
"- **Bonus:** Store your if test in a function called something like `crowd_test`.\n",
"\n",
"#### Three is a Crowd - Part 2\n",
"- Save your program from *Three is a Crowd* under a new name.\n",
"- Add an `else` statement to your if tests. If the `else` statement is run, have it print a message that the room is not very crowded.\n",
"\n",
"#### Six is a Mob\n",
"- Save your program from *Three is a Crowd - Part 2* under a new name.\n",
"- Add some names to your list, so that there are at least six people in the list.\n",
"- Modify your tests so that\n",
" - If there are more than 5 people, a message is printed about there being a mob in the room.\n",
" - If there are 3-5 people, a message is printed about the room being crowded.\n",
" - If there are 1 or 2 people, a message is printed about the room not being crowded.\n",
" - If there are no people in the room, a message is printed abou the room being empty."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 5.2 : Three is a Crowd\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 5.3 : Three is a Crowd - Part 2\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 5.4 : Six is a Mob\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='more_than_one'></a>More than one passing test\n",
"===\n",
"In all of the examples we have seen so far, only one test can pass. As soon as the first test passes, the rest of the tests are ignored. This is really good, because it allows our code to run more efficiently. Many times only one condition can be true, so testing every condition after one passes would be meaningless.\n",
"\n",
"There are situations in which you want to run a series of tests, where every single test runs. These are situations where any or all of the tests could pass, and you want to respond to each passing test. Consider the following example, where we want to greet each dog that is present:"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, Willie!\n",
"Hello, Hootz!\n"
]
}
],
"source": [
"dogs = ['willie', 'hootz']\n",
"\n",
"if 'willie' in dogs:\n",
" print(\"Hello, Willie!\")\n",
"if 'hootz' in dogs:\n",
" print(\"Hello, Hootz!\")\n",
"if 'peso' in dogs:\n",
" print(\"Hello, Peso!\")\n",
"if 'monty' in dogs:\n",
" print(\"Hello, Monty!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"If we had done this using an if-elif-else chain, only the first dog that is present would be greeted:"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, Willie!\n"
]
}
],
"source": [
"###highlight=[6,7,8,9,10,11]\n",
"dogs = ['willie', 'hootz']\n",
"\n",
"if 'willie' in dogs:\n",
" print(\"Hello, Willie!\")\n",
"elif 'hootz' in dogs:\n",
" print(\"Hello, Hootz!\")\n",
"elif 'peso' in dogs:\n",
" print(\"Hello, Peso!\")\n",
"elif 'monty' in dogs:\n",
" print(\"Hello, Monty!\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Of course, this could be written much more cleanly using lists and for loops. See if you can follow this code."
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Hello, Willie!\n",
"Hello, Hootz!\n"
]
}
],
"source": [
"dogs_we_know = ['willie', 'hootz', 'peso', 'monty', 'juno', 'turkey']\n",
"dogs_present = ['willie', 'hootz']\n",
"\n",
"# Go through all the dogs that are present, and greet the dogs we know.\n",
"for dog in dogs_present:\n",
" if dog in dogs_we_know:\n",
" print(\"Hello, %s!\" % dog.title())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"This is the kind of code you should be aiming to write. It is fine to come up with code that is less efficient at first. When you notice yourself writing the same kind of code repeatedly in one program, look to see if you can use a loop or a function to make your code more efficient."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# ADD LOGICAL OPERATORS"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name=\"true_false\"></a>True and False values\n",
"===\n",
"Every value can be evaluated as True or False. The general rule is that any non-zero or non-empty value will evaluate to True. If you are ever unsure, you can open a Python terminal and write two lines to find out if the value you are considering is True or False."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Take a look at the following examples, keep them in mind, and test any value you are curious about."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"I am using a slightly longer test just to make sure something gets printed each time."
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This evaluates to False.\n"
]
}
],
"source": [
"if 0:\n",
" print(\"This evaluates to True.\")\n",
"else:\n",
" print(\"This evaluates to False.\")"
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This evaluates to True.\n"
]
}
],
"source": [
"if 1:\n",
" print(\"This evaluates to True.\")\n",
"else:\n",
" print(\"This evaluates to False.\")"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This evaluates to True.\n"
]
}
],
"source": [
"# Arbitrary non-zero numbers evaluate to True.\n",
"if 1253756:\n",
" print(\"This evaluates to True.\")\n",
"else:\n",
" print(\"This evaluates to False.\")"
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This evaluates to True.\n"
]
}
],
"source": [
"# Negative numbers are not zero, so they evaluate to True.\n",
"if -1:\n",
" print(\"This evaluates to True.\")\n",
"else:\n",
" print(\"This evaluates to False.\")"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This evaluates to False.\n"
]
}
],
"source": [
"# An empty string evaluates to False.\n",
"if '':\n",
" print(\"This evaluates to True.\")\n",
"else:\n",
" print(\"This evaluates to False.\")"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This evaluates to True.\n"
]
}
],
"source": [
"# Any other string, including a space, evaluates to True.\n",
"if ' ':\n",
" print(\"This evaluates to True.\")\n",
"else:\n",
" print(\"This evaluates to False.\")"
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This evaluates to True.\n"
]
}
],
"source": [
"# Any other string, including a space, evaluates to True.\n",
"if 'hello':\n",
" print(\"This evaluates to True.\")\n",
"else:\n",
" print(\"This evaluates to False.\")"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"This evaluates to False.\n"
]
}
],
"source": [
"# None is a special object in Python. It evaluates to False.\n",
"if None:\n",
" print(\"This evaluates to True.\")\n",
"else:\n",
" print(\"This evaluates to False.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='overall_challenges'></a>Overall Challenges\n",
"===\n",
"#### Alien Points\n",
"- Make a list of ten aliens, each of which is one color: 'red', 'green', or 'blue'.\n",
" - You can shorten this to 'r', 'g', and 'b' if you want, but if you choose this option you have to include a comment explaining what r, g, and b stand for.\n",
"- Red aliens are worth 5 points, green aliens are worth 10 points, and blue aliens are worth 20 points.\n",
"- Use a for loop to determine the number of points a player would earn for destroying all of the aliens in your list.\n",
"- [hint](#hint_alien_points)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Overall Challenge: Alien Points\n",
"\n",
"# Put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Hints\n",
"===\n",
"These are placed at the bottom, so you can have a chance to solve exercises without seeing any hints.\n",
"\n",
"####<a name='hint_alien_invaders'></a> Alien Invaders\n",
"- After you define your list of aliens, set a variable called `current_score` or `current_points` equal to 0.\n",
"- Inside your for loop, write a series of if tests to determine how many points to add to the current score.\n",
"- To keep a running total, use the syntax `current_score = current_score + points`, where *points* is the number of points for the current alien."
]
}
],
"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.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Loops, Iteration Schemas and Input\n",
"==="
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"While loops are really useful because they let your program run until a user decides to quit the program. They set up an infinite loop that runs until the user does something to end the loop. This section also introduces the first way to get input from your program's users."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name=\"top\"></a>Contents\n",
"===\n",
"- [What is a `while` loop?](#what)\n",
" - [General syntax](#general_syntax)\n",
" - [Example](#example)\n",
" - [Exercises](#exercises_while)\n",
"- [Accepting user input](#input)\n",
" - [General syntax](#general_user_input)\n",
" - [Example](#example_user_input)\n",
" - [Exercises](#exercises_input)\n",
"- [Using while loops to keep your programs running](#keep_running)\n",
" - [Exercises](#exercises_running_input)\n",
"- [Using while loops to make menus](#menus)\n",
"- [Using while loops to process items in a list](#process_list)\n",
"- [Accidental Infinite loops](#infinite_loops)\n",
" - [Exercises](#exercises_infinite_loops)\n",
"- [Overall Challenges](#overall_challenges)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## The FOR (iteration) loop"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The `for` loop statement is the most widely used iteration mechanisms in Python.\n",
"\n",
"* Almost every structure in Python can be iterated (*element by element*) by a `for` loop\n",
" - a list, a tuple, a dictionary, $\\ldots$ (more details will follows)\n",
"\n",
"* In Python, also `while` loops are permitted, but `for` is the one you would see (and use) most of the time!"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='what'></a>What is a while loop?\n",
"==="
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"A while loop tests an initial condition. If that condition is true, the loop starts executing. Every time the loop finishes, the condition is reevaluated. As long as the condition remains true, the loop keeps executing. As soon as the condition becomes false, the loop stops executing."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='general_syntax'></a>General syntax\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"# Set an initial condition.\n",
"game_active = True\n",
"\n",
"# Set up the while loop.\n",
"while game_active:\n",
" # Run the game.\n",
" # At some point, the game ends and game_active will be set to False.\n",
" # When that happens, the loop will stop executing.\n",
" \n",
"# Do anything else you want done after the loop runs."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"- Every while loop needs an initial condition that starts out true.\n",
"- The `while` statement includes a condition to test.\n",
"- All of the code in the loop will run as long as the condition remains true.\n",
"- As soon as something in the loop changes the condition such that the test no longer passes, the loop stops executing.\n",
"- Any code that is defined after the loop will run at this point."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='example'></a>Example\n",
"---\n",
"Here is a simple example, showing how a game will stay active as long as the player has enough power."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"You are still playing, because your power is 5.\n",
"You are still playing, because your power is 4.\n",
"You are still playing, because your power is 3.\n",
"You are still playing, because your power is 2.\n",
"You are still playing, because your power is 1.\n",
"\n",
"Oh no, your power dropped to 0! Game Over.\n"
]
}
],
"source": [
"# The player's power starts out at 5.\n",
"power = 5\n",
"\n",
"# The player is allowed to keep playing as long as their power is over 0.\n",
"while power > 0:\n",
" print(\"You are still playing, because your power is %d.\" % power)\n",
" # Your game code would go here, which includes challenges that make it\n",
" # possible to lose power.\n",
" # We can represent that by just taking away from the power.\n",
" power = power - 1\n",
" \n",
"print(\"\\nOh no, your power dropped to 0! Game Over.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_while'></a>Exercises\n",
"---\n",
"#### Growing Strength\n",
"- Make a variable called strength, and set its initial value to 5.\n",
"- Print a message reporting the player's strength.\n",
"- Set up a while loop that runs until the player's strength increases to a value such as 10.\n",
"- Inside the while loop, print a message that reports the player's current strength.\n",
"- Inside the while loop, write a statement that increases the player's strength.\n",
"- Outside the while loop, print a message reporting that the player has grown too strong, and that they have moved up to a new level of the game.\n",
"- Bonus: Play around with different cutoff levels for the value of *strength*, and play around with different ways to increase the strength value within the while loop."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 6.1 : Growing Strength\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='input'></a>Accepting user input\n",
"==="
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Almost all interesting programs accept input from the user at some point. You can start accepting user input in your programs by using the `input()` function. The input function displays a messaget to the user describing the kind of input you are looking for, and then it waits for the user to enter a value. When the user presses Enter, the value is passed to your variable."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='general_user_input'></a>General syntax\n",
"---\n",
"The general case for accepting input looks something like this:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"# Get some input from the user.\n",
"variable = input('Please enter a value: ')\n",
"# Do something with the value that was entered."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"You need a variable that will hold whatever value the user enters, and you need a message that will be displayed to the user."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='example_user_input'></a>Example\n",
"---\n",
"In the following example, we have a list of names. We ask the user for a name, and we add it to our list of names."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Please tell me someone I should know: jessica\n",
"['guido', 'tim', 'jesse', 'jessica']\n"
]
}
],
"source": [
"# Start with a list containing several names.\n",
"names = ['guido', 'tim', 'jesse']\n",
"\n",
"# Ask the user for a name.\n",
"new_name = input(\"Please tell me someone I should know: \")\n",
"\n",
"# Add the new name to our list.\n",
"names.append(new_name)\n",
"\n",
"# Show that the name has been added to the list.\n",
"print(names)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_input'></a>Exercises\n",
"---\n",
"#### Game Preferences\n",
"- Make a list that includes 3 or 4 games that you like to play.\n",
"- Print a statement that tells the user what games you like.\n",
"- Ask the user to tell you a game they like, and store the game in a variable such as `new_game`.\n",
"- Add the user's game to your list.\n",
"- Print a new statement that lists all of the games that we like to play (*we* means you and your user)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 6.2 : Game Preferences\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='keep_running'></a>Using while loops to keep your programs running\n",
"==="
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "-"
}
},
"source": [
"Most of the programs we use every day run until we tell them to quit, and in the background this is often done with a while loop."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Here is an example of how to let the user enter an arbitrary number of names."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "-"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Please tell me someone I should know, or enter 'quit': guido\n",
"Please tell me someone I should know, or enter 'quit': jesse\n",
"Please tell me someone I should know, or enter 'quit': jessica\n",
"Please tell me someone I should know, or enter 'quit': tim\n",
"Please tell me someone I should know, or enter 'quit': quit\n",
"['guido', 'jesse', 'jessica', 'tim', 'quit']\n"
]
}
],
"source": [
"# Start with an empty list. You can 'seed' the list with\n",
"# some predefined values if you like.\n",
"names = []\n",
"\n",
"# Set new_name to something other than 'quit'.\n",
"new_name = ''\n",
"\n",
"# Start a loop that will run until the user enters 'quit'.\n",
"while new_name != 'quit':\n",
" # Ask the user for a name.\n",
" new_name = input(\"Please tell me someone I should know, or enter 'quit': \")\n",
"\n",
" # Add the new name to our list.\n",
" names.append(new_name)\n",
"\n",
"# Show that the name has been added to the list.\n",
"print(names)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"That worked, except we ended up with the name 'quit' in our list. We can use a simple `if` test to eliminate this bug:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Please tell me someone I should know, or enter 'quit': guido\n",
"Please tell me someone I should know, or enter 'quit': jesse\n",
"Please tell me someone I should know, or enter 'quit': jessica\n",
"Please tell me someone I should know, or enter 'quit': tim\n",
"Please tell me someone I should know, or enter 'quit': quit\n",
"['guido', 'jesse', 'jessica', 'tim']\n"
]
}
],
"source": [
"# Start with an empty list. You can 'seed' the list with\n",
"# some predefined values if you like.\n",
"names = []\n",
"\n",
"# Set new_name to something other than 'quit'.\n",
"new_name = ''\n",
"\n",
"# Start a loop that will run until the user enters 'quit'.\n",
"while new_name != 'quit':\n",
" # Ask the user for a name.\n",
" new_name = input(\"Please tell me someone I should know, or enter 'quit': \")\n",
"\n",
" # Add the new name to our list.\n",
" if new_name != 'quit':\n",
" names.append(new_name)\n",
"\n",
"# Show that the name has been added to the list.\n",
"print(names)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"This is pretty cool! We now have a way to accept input from users while our programs run, and we have a way to let our programs run until our users are finished working."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_running_input'></a>Exercises\n",
"---\n",
"#### Many Games\n",
"- Modify *[Game Preferences](#exercises_input)* so your user can add as many games as they like."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 6.3 : Many Games\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='menus'></a>Using while loops to make menus\n",
"===\n",
"You now have enough Python under your belt to offer users a set of choices, and then respond to those choices until they choose to quit."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Let's look at a simple example, and then analyze the code:"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Welcome to the nature center. What would you like to do?\n",
"\n",
"[1] Enter 1 to take a bicycle ride.\n",
"[2] Enter 2 to go for a run.\n",
"[3] Enter 3 to climb a mountain.\n",
"[q] Enter q to quit.\n",
"\n",
"What would you like to do? 1\n",
"\n",
"Here's a bicycle. Have fun!\n",
"\n",
"\n",
"[1] Enter 1 to take a bicycle ride.\n",
"[2] Enter 2 to go for a run.\n",
"[3] Enter 3 to climb a mountain.\n",
"[q] Enter q to quit.\n",
"\n",
"What would you like to do? 3\n",
"\n",
"Here's a map. Can you leave a trip plan for us?\n",
"\n",
"\n",
"[1] Enter 1 to take a bicycle ride.\n",
"[2] Enter 2 to go for a run.\n",
"[3] Enter 3 to climb a mountain.\n",
"[q] Enter q to quit.\n",
"\n",
"What would you like to do? q\n",
"\n",
"Thanks for playing. See you later.\n",
"\n",
"Thanks again, bye now.\n"
]
}
],
"source": [
"# Give the user some context.\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 bicycle ride.\")\n",
" print(\"[2] Enter 2 to go for a run.\")\n",
" print(\"[3] Enter 3 to climb a mountain.\")\n",
" print(\"[q] Enter q to quit.\")\n",
" \n",
" # Ask for the user's choice.\n",
" choice = input(\"\\nWhat would you like to do? \")\n",
" \n",
" # Respond to the user's choice.\n",
" if choice == '1':\n",
" print(\"\\nHere's a bicycle. Have fun!\\n\")\n",
" elif choice == '2':\n",
" print(\"\\nHere are some running shoes. Run fast!\\n\")\n",
" elif choice == '3':\n",
" print(\"\\nHere's a map. Can you leave a trip plan for us?\\n\")\n",
" elif choice == 'q':\n",
" print(\"\\nThanks for playing. See you later.\\n\")\n",
" else:\n",
" print(\"\\nI don't understand that choice, please try again.\\n\")\n",
" \n",
"# Print a message that we are all finished.\n",
"print(\"Thanks again, bye now.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Our programs are getting rich enough now, that we could do many different things with them. Let's clean this up in one really useful way. There are three main choices here, so let's define a function for each of those items. This way, our menu code remains really simple even as we add more complicated code to the actions of riding a bicycle, going for a run, or climbing a mountain."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Welcome to the nature center. What would you like to do?\n",
"\n",
"[1] Enter 1 to take a bicycle ride.\n",
"[2] Enter 2 to go for a run.\n",
"[3] Enter 3 to climb a mountain.\n",
"[q] Enter q to quit.\n",
"\n",
"What would you like to do? 1\n",
"\n",
"Here's a bicycle. Have fun!\n",
"\n",
"\n",
"[1] Enter 1 to take a bicycle ride.\n",
"[2] Enter 2 to go for a run.\n",
"[3] Enter 3 to climb a mountain.\n",
"[q] Enter q to quit.\n",
"\n",
"What would you like to do? 3\n",
"\n",
"Here's a map. Can you leave a trip plan for us?\n",
"\n",
"\n",
"[1] Enter 1 to take a bicycle ride.\n",
"[2] Enter 2 to go for a run.\n",
"[3] Enter 3 to climb a mountain.\n",
"[q] Enter q to quit.\n",
"\n",
"What would you like to do? q\n",
"\n",
"Thanks for playing. See you later.\n",
"\n",
"Thanks again, bye now.\n"
]
}
],
"source": [
"# Define the actions for each choice we want to offer.\n",
"def ride_bicycle():\n",
" print(\"\\nHere's a bicycle. Have fun!\\n\")\n",
" \n",
"def go_running():\n",
" print(\"\\nHere are some running shoes. Run fast!\\n\")\n",
" \n",
"def climb_mountain():\n",
" print(\"\\nHere's a map. Can you leave a trip plan for us?\\n\")\n",
"\n",
"# Give the user some context.\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 bicycle ride.\")\n",
" print(\"[2] Enter 2 to go for a run.\")\n",
" print(\"[3] Enter 3 to climb a mountain.\")\n",
" print(\"[q] Enter q to quit.\")\n",
" \n",
" # Ask for the user's choice.\n",
" choice = input(\"\\nWhat would you like to do? \")\n",
" \n",
" # Respond to the user's choice.\n",
" if choice == '1':\n",
" ride_bicycle()\n",
" elif choice == '2':\n",
" go_running()\n",
" elif choice == '3':\n",
" climb_mountain()\n",
" elif choice == 'q':\n",
" print(\"\\nThanks for playing. See you later.\\n\")\n",
" else:\n",
" print(\"\\nI don't understand that choice, please try again.\\n\")\n",
" \n",
"# Print a message that we are all finished.\n",
"print(\"Thanks again, bye now.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This is much cleaner code, and it gives us space to separate the details of taking an action from the act of choosing that action."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='processing_list'></a>Using while loops to process items in a list\n",
"===\n",
"In the section on Lists, you saw that we can `pop()` items from a list. You can use a while list to pop items one at a time from one list, and work with them in whatever way you need. "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Let's look at an example where we process a list of unconfirmed users."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Confirming user Daria...confirmed!\n",
"Confirming user Clarence...confirmed!\n",
"Confirming user Billy...confirmed!\n",
"Confirming user Ada...confirmed!\n",
"\n",
"Unconfirmed users:\n",
"\n",
"Confirmed users:\n",
"- Daria\n",
"- Clarence\n",
"- Billy\n",
"- Ada\n"
]
}
],
"source": [
"# Start with a list of unconfirmed users, and an empty list of confirmed users.\n",
"unconfirmed_users = ['ada', 'billy', 'clarence', 'daria']\n",
"confirmed_users = []\n",
"\n",
"# Work through the list, and confirm each user.\n",
"while len(unconfirmed_users) > 0:\n",
" \n",
" # Get the latest unconfirmed user, and process them.\n",
" current_user = unconfirmed_users.pop()\n",
" print(\"Confirming user %s...confirmed!\" % current_user.title())\n",
" \n",
" # Move the current user to the list of confirmed users.\n",
" confirmed_users.append(current_user)\n",
" \n",
"# Prove that we have finished confirming all users.\n",
"print(\"\\nUnconfirmed users:\")\n",
"for user in unconfirmed_users:\n",
" print('- ' + user.title())\n",
" \n",
"print(\"\\nConfirmed users:\")\n",
"for user in confirmed_users:\n",
" print('- ' + user.title())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This works, but let's make one small improvement. The current program always works with the most recently added user. If users are joining faster than we can confirm them, we will leave some users behind. If we want to work on a 'first come, first served' model, or a 'first in first out' model, we can pop the first item in the list each time."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Confirming user Ada...confirmed!\n",
"Confirming user Billy...confirmed!\n",
"Confirming user Clarence...confirmed!\n",
"Confirming user Daria...confirmed!\n",
"\n",
"Unconfirmed users:\n",
"\n",
"Confirmed users:\n",
"- Ada\n",
"- Billy\n",
"- Clarence\n",
"- Daria\n"
]
}
],
"source": [
"# Start with a list of unconfirmed users, and an empty list of confirmed users.\n",
"unconfirmed_users = ['ada', 'billy', 'clarence', 'daria']\n",
"confirmed_users = []\n",
"\n",
"# Work through the list, and confirm each user.\n",
"while len(unconfirmed_users) > 0:\n",
" \n",
" # Get the latest unconfirmed user, and process them.\n",
" current_user = unconfirmed_users.pop(0)\n",
" print(\"Confirming user %s...confirmed!\" % current_user.title())\n",
" \n",
" # Move the current user to the list of confirmed users.\n",
" confirmed_users.append(current_user)\n",
" \n",
"# Prove that we have finished confirming all users.\n",
"print(\"\\nUnconfirmed users:\")\n",
"for user in unconfirmed_users:\n",
" print('- ' + user.title())\n",
" \n",
"print(\"\\nConfirmed users:\")\n",
"for user in confirmed_users:\n",
" print('- ' + user.title())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This is a little nicer, because we are sure to get to everyone, even when our program is running under a heavy load. We also preserve the order of people as they join our project. Notice that this all came about by adding *one character* to our program!"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='infinite_loops'></a>Accidental Infinite loops\n",
"===\n",
"Sometimes we want a while loop to run until a defined action is completed, such as emptying out a list. Sometimes we want a loop to run for an unknown period of time, for example when we are allowing users to give as much input as they want. What we rarely want, however, is a true 'runaway' infinite loop."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Take a look at the following example. Can you pick out why this loop will never stop?"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"current_number = 1\n",
"\n",
"# Count up to 5, printing the number each time.\n",
"while current_number <= 5:\n",
" print(current_number)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"1\n",
"1\n",
"1\n",
"1\n",
"1\n",
"..."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"I faked that output, because if I ran it the output would fill up the browser. You can try to run it on your computer, as long as you know how to interrupt runaway processes:\n",
"\n",
"- On most systems, Ctrl-C will interrupt the currently running program.\n",
"- If you are using Geany, your output is displayed in a popup terminal window. You can either press Ctrl-C, or you can use your pointer to close the terminal window."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The loop runs forever, because there is no way for the test condition to ever fail. The programmer probably meant to add a line that increments current_number by 1 each time through the loop:"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1\n",
"2\n",
"3\n",
"4\n",
"5\n"
]
}
],
"source": [
"current_number = 1\n",
"\n",
"# Count up to 5, printing the number each time.\n",
"while current_number <= 5:\n",
" print(current_number)\n",
" current_number = current_number + 1"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"You will certainly make some loops run infintely at some point. When you do, just interrupt the loop and figure out the logical error you made.\n",
"\n",
"Infinite loops will not be a real problem until you have users who run your programs on their machines. You won't want infinite loops then, because your users would have to shut down your program, and they would consider it buggy and unreliable. Learn to spot infinite loops, and make sure they don't pop up in your polished programs later on.\n",
"\n",
"Here is one more example of an accidental infinite loop:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"current_number = 1\n",
"\n",
"# Count up to 5, printing the number each time.\n",
"while current_number <= 5:\n",
" print(current_number)\n",
" current_number = current_number - 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [],
"source": [
"1\n",
"0\n",
"-1\n",
"-2\n",
"-3\n",
"..."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"In this example, we accidentally started counting down. The value of `current_number` will always be less than 5, so the loop will run forever."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_infinite_loops'></a>Exercises\n",
"---\n",
"#### Marveling at Infinity\n",
"- Use one of the examples of a failed while loop to create an infinite loop.\n",
"- Interrupt your output.\n",
"- Marvel at the fact that if you had not interrupted your output, your computer would have kept doing what you told it to until it ran out of power, or memory, or until the universe went cold around it."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 6.4 : Marveling at Infinity\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='overall_challenges'></a>Overall Challenges\n",
"===\n",
"#### Gaussian Addition\n",
"This challenge is inspired by a story about the mathematician Carl Frederich Gauss. [As the story goes](http://mathforum.org/library/drmath/view/57919.html), when young Gauss was in grade school his teacher got mad at his class one day.\n",
"\n",
"\"I'll keep the lot of you busy for a while\", the teacher said sternly to the group. \"You are to add the numbers from 1 to 100, and you are not to say a word until you are done.\"\n",
"\n",
"The teacher expected a good period of quiet time, but a moment later our mathematician-to-be raised his hand with the answer. \"It's 5050!\" Gauss had realized that if you list all the numbers from 1 to 100, you can always match the first and last numbers in the list and get a common answer:\n",
"\n",
" 1, 2, 3, ..., 98, 99, 100\n",
" 1 + 100 = 101\n",
" 2 + 99 = 101\n",
" 3 + 98 = 101\n",
"\n",
"Gauss realized there were exactly 50 pairs of numbers in the range 1 to 100, so he did a quick calculation: 50 * 101 = 5050.\n",
"\n",
"- Write a program that passes a list of numbers to a function.\n",
" - The function should use a while loop to keep popping the first and last numbers from the list and calculate the sum of those two numbers.\n",
" - The function should print out the current numbers that are being added, and print their partial sum.\n",
" - The function should keep track of how many partial sums there are.\n",
" - The function should then print out how many partial sums there were.\n",
" - The function should perform Gauss' multiplication, and report the final answer.\n",
"- Prove that your function works, by passing in the range 1-100, and verifying that you get 5050.\n",
" - `gauss_addition(list(range(1,101)))`\n",
"- Your function should work for any set of consecutive numbers, as long as that set has an even length.\n",
" - Bonus: Modify your function so that it works for any set of consecutive numbers, whether that set has an even or odd length."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Overall Challenge: Gaussian Addition\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
}
],
"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.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Dictionaries (Data Structure)\n",
"==="
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Dictionaries allow us to store connected bits of information. For example, you might store a person's name and age together."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name=\"top\"></a>Contents\n",
"===\n",
"- [What are dictionaries?](#what)\n",
" - [General Syntax](#general_syntax)\n",
" - [Example](#example)\n",
" - [Exercises](#exercises_what)\n",
"- [Common operations with dictionaries](#common_operations)\n",
" - [Adding new key-value pairs](#adding_pairs)\n",
" - [Modifying values in a dictionary](#modifying_values)\n",
" - [Removing key-value pairs](#removing_pairs)\n",
" - [Modifying keys in a dictionary](#modifying_keys)\n",
" - [Exercises](#exercises_common_operations)\n",
"- [Looping through a dictionary](#looping)\n",
" - [Looping through all key-value pairs](#loop_all_keys_values)\n",
" - [Looping through all keys in a dictionary](#loop_all_keys)\n",
" - [Looping through all values in a dictionary](#loop_all_values)\n",
" - [Looping through a dictionary in order](#looping_in_order)\n",
" - [Exercises](#exercises_looping)\n",
"- [Nesting](#nesting)\n",
" - [Lists in a dictionary](#lists_in_dictionary)\n",
" - [Dictionaries in a dictionary](#dictionaries_in_dictionary)\n",
" - [An important note about nesting](#important_note)\n",
" - [Exercises](#exercises_nesting)\n",
"- [Overall Challenges](#overall_challenges)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='what'></a>What are dictionaries?\n",
"===\n",
"Dictionaries are a way to store information that is connected in some way. Dictionaries store information in *key-value* pairs, so that any one piece of information in a dictionary is connected to at least one other piece of information.\n",
"\n",
"Dictionaries do not store their information in any particular order, so you may not get your information back in the same order you entered it."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='general_syntax'></a>General Syntax\n",
"---\n",
"A general dictionary in Python looks something like this:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"dictionary_name = {key_1: value_1, key_2: value_2, key_3: value_3}"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Since the keys and values in dictionaries can be long, we often write just one key-value pair on a line. You might see dictionaries that look more like this:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"dictionary_name = {key_1: value_1,\n",
" key_2: value_2,\n",
" key_3: value_3,\n",
" }"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"This is a bit easier to read, especially if the values are long."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='example'></a>Example\n",
"---\n",
"A simple example involves modeling an actual dictionary."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"We can get individual items out of the dictionary, by giving the dictionary's name, and the key in square brackets:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Word: list\n",
"Meaning: A collection of values that are not connected, but have an order.\n",
"\n",
"Word: dictionary\n",
"Meaning: A collection of key-value pairs.\n",
"\n",
"Word: function\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"print(\"\\nWord: %s\" % 'list')\n",
"print(\"Meaning: %s\" % python_words['list'])\n",
" \n",
"print(\"\\nWord: %s\" % 'dictionary')\n",
"print(\"Meaning: %s\" % python_words['dictionary'])\n",
"\n",
"print(\"\\nWord: %s\" % 'function')\n",
"print(\"Meaning: %s\" % python_words['function'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This code looks pretty repetitive, and it is. Dictionaries have their own for-loop syntax, but since there are two kinds of information in dictionaries, the structure is a bit more complicated than it is for lists. Here is how to use a for loop with a dictionary:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Word: function\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"Word: list\n",
"Meaning: A collection of values that are not connected, but have an order.\n",
"\n",
"Word: dictionary\n",
"Meaning: A collection of key-value pairs.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"# Print out the items in the dictionary.\n",
"for word, meaning in python_words.items():\n",
" print(\"\\nWord: %s\" % word)\n",
" print(\"Meaning: %s\" % meaning)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The output is identical, but we did it in 3 lines instead of 6. If we had 100 terms in our dictionary, we would still be able to print them out with just 3 lines.\n",
"\n",
"The only tricky part about using for loops with dictionaries is figuring out what to call those first two variables. The general syntax for this for loop is:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"for key_name, value_name in dictionary_name.items():\n",
" print(key_name) # The key is stored in whatever you called the first variable.\n",
" print(value_name) # The value associated with that key is stored in your second variable."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_what'></a>Exercises\n",
"---\n",
"#### Pet Names\n",
"- Create a dictionary to hold information about pets. Each key is an animal's name, and each value is the kind of animal.\n",
" - For example, 'ziggy': 'canary'\n",
"- Put at least 3 key-value pairs in your dictionary.\n",
"- Use a for loop to print out a series of statements such as \"Willie is a dog.\"\n",
"\n",
"#### Polling Friends\n",
"- Think of a question you could ask your friends. Create a dictionary where each key is a person's name, and each value is that person's response to your question.\n",
"- Store at least three responses in your dictionary.\n",
"- Use a for loop to print out a series of statements listing each person's name, and their response."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 7.1 : Pet Names\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 7.2 : Polling Friends\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='common_operations'></a>Common operations with dictionaries\n",
"===\n",
"There are a few common things you will want to do with dictionaries. These include adding new key-value pairs, modifying information in the dictionary, and removing items from dictionaries."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='adding_pairs'></a>Adding new key-value pairs\n",
"---\n",
"To add a new key-value pair, you give the dictionary name followed by the new key in square brackets, and set that equal to the new value. We will show this by starting with an empty dictionary, and re-creating the dictionary from the example above."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Word: function\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"Word: list\n",
"Meaning: A collection of values that are not connected, but have an order.\n",
"\n",
"Word: dictionary\n",
"Meaning: A collection of key-value pairs.\n"
]
}
],
"source": [
"# Create an empty dictionary.\n",
"python_words = {}\n",
"\n",
"# Fill the dictionary, pair by pair.\n",
"python_words['list'] ='A collection of values that are not connected, but have an order.'\n",
"python_words['dictionary'] = 'A collection of key-value pairs.'\n",
"python_words['function'] = 'A named set of instructions that defines a set of actions in Python.'\n",
"\n",
"# Print out the items in the dictionary.\n",
"for word, meaning in python_words.items():\n",
" print(\"\\nWord: %s\" % word)\n",
" print(\"Meaning: %s\" % meaning)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"list : 507389742764312598\n",
"function : -6418509839493444138\n",
"dictionary : -4501548687734576673\n",
"function : -6418509839493444138\n",
"list : 507389742764312598\n",
"dictionary : -4501548687734576673\n"
]
}
],
"source": [
"# Dealing with Hashing Functions\n",
"hashings = {}\n",
"hashings['function'] = hash('function')\n",
"hashings['list'] = hash('list')\n",
"hashings['dictionary'] = hash('dictionary')\n",
"\n",
"for k, v in hashings.items():\n",
" print(k,': ',v)\n",
"\n",
"\n",
"from collections import OrderedDict\n",
"hashings = OrderedDict()\n",
"hashings['function'] = hash('function')\n",
"hashings['list'] = hash('list')\n",
"hashings['dictionary'] = hash('dictionary')\n",
"\n",
"for k, v in hashings.items():\n",
" print(k,': ',v)\n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='modifying_values'></a>Modifying values in a dictionary\n",
"---\n",
"At some point you may want to modify one of the values in your dictionary. Modifying a value in a dictionary is pretty similar to modifying an element in a list. You give the name of the dictionary and then the key in square brackets, and set that equal to the new value."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"dictionary: A collection of key-value pairs.\n",
"\n",
"dictionary: A collection of key-value pairs. Each key can be used to access its corresponding value.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"print('dictionary: ' + python_words['dictionary'])\n",
" \n",
"# Clarify one of the meanings.\n",
"python_words['dictionary'] = 'A collection of key-value pairs. \\\n",
" Each key can be used to access its corresponding value.'\n",
"\n",
"print('\\ndictionary: ' + python_words['dictionary'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='removing_pairs'></a>Removing key-value pairs\n",
"---\n",
"You may want to remove some key-value pairs from one of your dictionaries at some point. You can do this using the same `del` command you learned to use with lists. To remove a key-value pair, you give the `del` command, followed by the name of the dictionary, with the key that you want to delete. This removes the key and the value as a pair."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"These are the Python words I know:\n",
"\n",
"Word: dictionary\n",
"Meaning: A collection of key-value pairs.\n",
"\n",
"Word: function\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
" \n",
"# Remove the word 'list' and its meaning.\n",
"_ = python_words.pop('list')\n",
"\n",
"# Show the current set of words and meanings.\n",
"print(\"\\n\\nThese are the Python words I know:\")\n",
"for word, meaning in python_words.items():\n",
" print(\"\\nWord: %s\" % word)\n",
" print(\"Meaning: %s\" % meaning)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"If you were going to work with this code, you would certainly want to put the code for displaying the dictionary into a function. Let's see what this looks like:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"These are the Python words I know:\n",
"\n",
"Word: function\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"Word: list\n",
"Meaning: A collection of values that are not connected, but have an order.\n",
"\n",
"Word: dictionary\n",
"Meaning: A collection of key-value pairs.\n",
"\n",
"\n",
"These are the Python words I know:\n",
"\n",
"Word: function\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"Word: dictionary\n",
"Meaning: A collection of key-value pairs.\n"
]
}
],
"source": [
"def show_words_meanings(python_words):\n",
" # This function takes in a dictionary of python words and meanings,\n",
" # and prints out each word with its meaning.\n",
" print(\"\\n\\nThese are the Python words I know:\")\n",
" for word, meaning in python_words.items():\n",
" print(\"\\nWord: %s\" % word)\n",
" print(\"Meaning: %s\" % meaning)\n",
" \n",
"\n",
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"show_words_meanings(python_words)\n",
" \n",
"# Remove the word 'list' and its meaning.\n",
"del python_words['list']\n",
"\n",
"show_words_meanings(python_words)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"As long as we have a nice clean function to work with, let's clean up our output a little:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"\n",
"These are the Python words I know:\n",
"\n",
"function: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"dictionary: A collection of key-value pairs.\n",
"\n",
"list: A collection of values that are not connected, but have an order.\n",
"\n",
"\n",
"These are the Python words I know:\n",
"\n",
"function: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"dictionary: A collection of key-value pairs.\n"
]
}
],
"source": [
"def show_words_meanings(python_words):\n",
" # This function takes in a dictionary of python words and meanings,\n",
" # and prints out each word with its meaning.\n",
" print(\"\\n\\nThese are the Python words I know:\")\n",
" for word, meaning in python_words.items():\n",
" print(\"\\n%s: %s\" % (word, meaning))\n",
" \n",
"\n",
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"show_words_meanings(python_words)\n",
" \n",
"# Remove the word 'list' and its meaning.\n",
"del python_words['list']\n",
"\n",
"show_words_meanings(python_words)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"This is much more realistic code."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='modifying_keys'></a>Modifying keys in a dictionary\n",
"---\n",
"Modifying a value in a dictionary was straightforward, because nothing else depends on the value. Modifying a key is a little harder, because each key is used to unlock a value. We can change a key in two steps:\n",
"\n",
"- Make a new key, and copy the value to the new key.\n",
"- Delete the old key, which also deletes the old value."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Here's what this looks like. We will use a dictionary with just one key-value pair, to keep things simple."
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {
"collapsed": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"{'list': 'A collection of values that are not connected, but have an order.'}\n"
]
}
],
"source": [
"# We have a spelling mistake!\n",
"python_words = {'list': 'A collection of values that are not connected, but have an order.'}\n",
"\n",
"# Create a new, correct key, and connect it to the old value.\n",
"# Then delete the old key.\n",
"python_words['list'] = python_words['lisst']\n",
"del python_words['lisst']\n",
"\n",
"# Print the dictionary, to show that the key has changed.\n",
"print(python_words)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_common_operations'></a>Exercises\n",
"---\n",
"#### Pet Names 2\n",
"- Make a copy of your program from [Pet Names](#exercises_what).\n",
" - Use a for loop to print out a series of statements such as \"Willie is a dog.\"\n",
" - Modify one of the values in your dictionary. You could clarify to name a breed, or you could change an animal from a cat to a dog.\n",
" - Use a for loop to print out a series of statements such as \"Willie is a dog.\"\n",
" - Add a new key-value pair to your dictionary.\n",
" - Use a for loop to print out a series of statements such as \"Willie is a dog.\"\n",
" - Remove one of the key-value pairs from your dictionary.\n",
" - Use a for loop to print out a series of statements such as \"Willie is a dog.\"\n",
"- Bonus: Use a function to do all of the looping and printing in this problem.\n",
"\n",
"#### Weight Lifting\n",
"- Make a dictionary where the keys are the names of weight lifting exercises, and the values are the number of times you did that exercise.\n",
" - Use a for loop to print out a series of statements such as \"I did 10 bench presses\".\n",
" - Modify one of the values in your dictionary, to represent doing more of that exercise.\n",
" - Use a for loop to print out a series of statements such as \"I did 10 bench presses\".\n",
" - Add a new key-value pair to your dictionary.\n",
" - - Use a for loop to print out a series of statements such as \"I did 10 bench presses\".\n",
" - Remove one of the key-value pairs from your dictionary.\n",
" - - Use a for loop to print out a series of statements such as \"I did 10 bench presses\".\n",
"- Bonus: Use a function to do all of the looping and printing in this problem."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 7.3 : Pet Names 2\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 7.4 : Weight Lifting\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='looping'></a>Looping through a dictionary\n",
"==="
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Since dictionaries are really about connecting bits of information, you will often use them in the ways described above, where you add key-value pairs whenever you receive some new information, and then you retrieve the key-value pairs that you care about. Sometimes, however, you will want to loop through the entire dictionary. There are several ways to do this:\n",
"\n",
"- You can loop through all key-value pairs;\n",
"- You can loop through the keys, and pull out the values for any keys that you care about;\n",
"- You can loop through the values."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='loop_all_keys_values'></a>Looping through all key-value pairs\n",
"---\n",
"This is the kind of loop that was shown in the first example. Here's what this loop looks like, in a general format:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Key: key_1\n",
"Value: value_1\n",
"\n",
"Key: key_3\n",
"Value: value_3\n",
"\n",
"Key: key_2\n",
"Value: value_2\n"
]
}
],
"source": [
"my_dict = {'key_1': 'value_1',\n",
" 'key_2': 'value_2',\n",
" 'key_3': 'value_3',\n",
" }\n",
"\n",
"for key, value in my_dict.items():\n",
" print('\\nKey: %s' % key)\n",
" print('Value: %s' % value)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This works because the method `.items()` pulls all key-value pairs from a dictionary into a list of tuples:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[('key_1', 'value_1'), ('key_3', 'value_3'), ('key_2', 'value_2')]\n"
]
}
],
"source": [
"my_dict = {'key_1': 'value_1',\n",
" 'key_2': 'value_2',\n",
" 'key_3': 'value_3',\n",
" }\n",
"\n",
"print(my_dict.items())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The syntax `for key, value in my_dict.items():` does the work of looping through this list of tuples, and pulling the first and second item from each tuple for us.\n",
"\n",
"There is nothing special about any of these variable names, so Python code that uses this syntax becomes really readable. Rather than create a new example of this loop, let's just look at the original example again to see this in a meaningful context:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Word: function\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"Word: list\n",
"Meaning: A collection of values that are not connected, but have an order.\n",
"\n",
"Word: dictionary\n",
"Meaning: A collection of key-value pairs.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"for word, meaning in python_words.items():\n",
" print(\"\\nWord: %s\" % word)\n",
" print(\"Meaning: %s\" % meaning)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='loop_all_keys'></a>Looping through all keys in a dictionary\n",
"---\n",
"Python provides a clear syntax for looping through just the keys in a dictionary:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Key: key_1\n",
"Key: key_3\n",
"Key: key_2\n"
]
}
],
"source": [
"my_dict = {'key_1': 'value_1',\n",
" 'key_2': 'value_2',\n",
" 'key_3': 'value_3',\n",
" }\n",
"\n",
"for key in my_dict.keys():\n",
" print('Key: %s' % key)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This is actually the default behavior of looping through the dictionary itself. So you can leave out the `.keys()` part, and get the exact same behavior:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Key: key_1\n",
"Key: key_3\n",
"Key: key_2\n"
]
}
],
"source": [
"my_dict = {'key_1': 'value_1',\n",
" 'key_2': 'value_2',\n",
" 'key_3': 'value_3',\n",
" }\n",
"\n",
"for key in my_dict:\n",
" print('Key: %s' % key)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The only advantage of using the `.keys()` in the code is a little bit of clarity. But anyone who knows Python reasonably well is going to recognize what the second version does. In the rest of our code, we will leave out the `.keys()` when we want this behavior.\n",
"\n",
"You can pull out the value of any key that you are interested in within your loop, using the standard notation for accessing a dictionary value from a key:"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Key: key_1\n",
"Key: key_3\n",
"Key: key_2\n",
" The value for key_2 is value_2.\n"
]
}
],
"source": [
"my_dict = {'key_1': 'value_1',\n",
" 'key_2': 'value_2',\n",
" 'key_3': 'value_3',\n",
" }\n",
"\n",
"for key in my_dict:\n",
" print('Key: %s' % key)\n",
" if key == 'key_2':\n",
" print(\" The value for key_2 is %s.\" % my_dict[key])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Let's show how we might use this in our Python words program. This kind of loop provides a straightforward way to show only the words in the dictionary:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The following Python words have been defined:\n",
"- function\n",
"- list\n",
"- dictionary\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"# Show the words that are currently in the dictionary.\n",
"print(\"The following Python words have been defined:\")\n",
"for word in python_words:\n",
" print(\"- %s\" % word)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"We can extend this slightly to make a program that lets you look up words. We first let the user choose a word. When the user has chosen a word, we get the meaning for that word, and display it:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": true,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The following Python words have been defined:\n",
"- function\n",
"- list\n",
"- dictionary\n",
"\n",
"What word would you like to learn about? list\n",
"\n",
"list: A collection of values that are not connected, but have an order.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"# Show the words that are currently in the dictionary.\n",
"print(\"The following Python words have been defined:\")\n",
"for word in python_words:\n",
" print(\"- %s\" % word)\n",
" \n",
"# Allow the user to choose a word, and then display the meaning for that word.\n",
"requested_word = raw_input(\"\\nWhat word would you like to learn about? \")\n",
"print(\"\\n%s: %s\" % (requested_word, python_words[requested_word]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This allows the user to select one word that has been defined. If we enclose the input part of the program in a while loop, the user can see as many definitions as they'd like:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The following Python words have been defined:\n",
"- function\n",
"- list\n",
"- dictionary\n",
"\n",
"What word would you like to learn about? (or 'quit') list\n",
"\n",
" list: A collection of values that are not connected, but have an order.\n",
"\n",
"What word would you like to learn about? (or 'quit') dictionary\n",
"\n",
" dictionary: A collection of key-value pairs.\n",
"\n",
"What word would you like to learn about? (or 'quit') quit\n",
"\n",
" Sorry, I don't know that word.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"# Show the words that are currently in the dictionary.\n",
"print(\"The following Python words have been defined:\")\n",
"for word in python_words:\n",
" print(\"- %s\" % word)\n",
"\n",
"requested_word = ''\n",
"while requested_word != 'quit':\n",
" # Allow the user to choose a word, and then display the meaning for that word.\n",
" requested_word = raw_input(\"\\nWhat word would you like to learn about? (or 'quit') \")\n",
" if requested_word in python_words.keys():\n",
" print(\"\\n %s: %s\" % (requested_word, python_words[requested_word]))\n",
" else:\n",
" # Handle misspellings, and words not yet stored.\n",
" print(\"\\n Sorry, I don't know that word.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This allows the user to ask for as many meanings as they want, but it takes the word \"quit\" as a requested word. Let's add an `elif` clause to clean up this behavior:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The following Python words have been defined:\n",
"- function\n",
"- list\n",
"- dictionary\n",
"\n",
"What word would you like to learn about? (or 'quit') function\n",
"\n",
" function: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"What word would you like to learn about? (or 'quit') dictionary\n",
"\n",
" dictionary: A collection of key-value pairs.\n",
"\n",
"What word would you like to learn about? (or 'quit') list\n",
"\n",
" list: A collection of values that are not connected, but have an order.\n",
"\n",
"What word would you like to learn about? (or 'quit') class\n",
"\n",
" Sorry, I don't know that word.\n",
"\n",
"What word would you like to learn about? (or 'quit') quit\n",
"\n",
" Bye!\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"# Show the words that are currently in the dictionary.\n",
"print(\"The following Python words have been defined:\")\n",
"for word in python_words:\n",
" print(\"- %s\" % word)\n",
"\n",
"requested_word = ''\n",
"while requested_word != 'quit':\n",
" # Allow the user to choose a word, and then display the meaning for that word.\n",
" requested_word = raw_input(\"\\nWhat word would you like to learn about? (or 'quit') \")\n",
" if requested_word in python_words.keys():\n",
" # This is a word we know, so show the meaning.\n",
" print(\"\\n %s: %s\" % (requested_word, python_words[requested_word]))\n",
" elif requested_word != 'quit':\n",
" # This is not in python_words, and it's not 'quit'.\n",
" print(\"\\n Sorry, I don't know that word.\")\n",
" else:\n",
" # The word is quit.\n",
" print \"\\n Bye!\""
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='loop_all_values'></a>Looping through all values in a dictionary\n",
"---\n",
"Python provides a straightforward syntax for looping through all the values in a dictionary, as well:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Value: value_1\n",
"Value: value_3\n",
"Value: value_2\n"
]
}
],
"source": [
"my_dict = {'key_1': 'value_1',\n",
" 'key_2': 'value_2',\n",
" 'key_3': 'value_3',\n",
" }\n",
"\n",
"for value in my_dict.values():\n",
" print('Value: %s' % value)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"We can use this loop syntax to have a little fun with the dictionary example, by making a little quiz program. The program will display a meaning, and ask the user to guess the word that matches that meaning. Let's start out by showing all the meanings in the dictionary:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Meaning: A named set of instructions that defines a set of actions in Python.\n",
"Meaning: A collection of values that are not connected, but have an order.\n",
"Meaning: A collection of key-value pairs.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"for meaning in python_words.values():\n",
" print(\"Meaning: %s\" % meaning)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Now we can add a prompt after each meaning, asking the user to guess the word:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n",
"What word do you think this is? function\n",
"You got it!\n",
"\n",
"Meaning: A collection of values that are not connected, but have an order.\n",
"What word do you think this is? function\n",
"Sorry, that's just not the right word.\n",
"\n",
"Meaning: A collection of key-value pairs.\n",
"What word do you think this is? dictionary\n",
"You got it!\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"# Print each meaning, one at a time, and ask the user\n",
"# what word they think it is.\n",
"for meaning in python_words.values():\n",
" print(\"\\nMeaning: %s\" % meaning)\n",
" \n",
" guessed_word = raw_input(\"What word do you think this is? \")\n",
" \n",
" # The guess is correct if the guessed word's meaning matches the current meaning.\n",
" if python_words[guessed_word] == meaning:\n",
" print(\"You got it!\")\n",
" else:\n",
" print(\"Sorry, that's just not the right word.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This is starting to work, but we can see from the output that the user does not get the chance to take a second guess if they guess wrong for any meaning. We can use a while loop around the guessing code, to let the user guess until they get it right:"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Meaning: A named set of instructions that defines a set of actions in Python.\n",
"\n",
"What word do you think this is? function\n",
"You got it!\n",
"\n",
"Meaning: A collection of values that are not connected, but have an order.\n",
"\n",
"What word do you think this is? dictionary\n",
"Sorry, that's just not the right word.\n",
"\n",
"What word do you think this is? list\n",
"You got it!\n",
"\n",
"Meaning: A collection of key-value pairs.\n",
"\n",
"What word do you think this is? dictionary\n",
"You got it!\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"# Print each meaning, one at a time, and ask the user\n",
"# what word they think it is.\n",
"for meaning in python_words.values():\n",
" print(\"\\nMeaning: %s\" % meaning)\n",
" \n",
" # Assume the guess is not correct; keep guessing until correct.\n",
" correct = False\n",
" while not correct:\n",
" guessed_word = input(\"\\nWhat word do you think this is? \")\n",
" \n",
" # The guess is correct if the guessed word's meaning matches the current meaning.\n",
" if python_words[guessed_word] == meaning:\n",
" print(\"You got it!\")\n",
" correct = True\n",
" else:\n",
" print(\"Sorry, that's just not the right word.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This is better. Now, if the guess is incorrect, the user is caught in a loop that they can only exit by guessing correctly. The final revision to this code is to show the user a list of words to choose from when they are asked to guess:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"A named set of instructions that defines a set of actions in Python.\n",
"\n",
"What word do you think this is?\n",
"function list dictionary \n",
"- function\n",
"You got it!\n",
"\n",
"A collection of values that are not connected, but have an order.\n",
"\n",
"What word do you think this is?\n",
"function list dictionary \n",
"- dictionary\n",
"Sorry, that's just not the right word.\n",
"\n",
"What word do you think this is?\n",
"function list dictionary \n",
"- list\n",
"You got it!\n",
"\n",
"A collection of key-value pairs.\n",
"\n",
"What word do you think this is?\n",
"function list dictionary \n",
"- dictionary\n",
"You got it!\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"def show_words(python_words):\n",
" # A simple function to show the words in the dictionary.\n",
" display_message = \"\"\n",
" for word in python_words.keys():\n",
" display_message += word + ' '\n",
" print display_message\n",
"\n",
"# Print each meaning, one at a time, and ask the user\n",
"# what word they think it is.\n",
"for meaning in python_words.values():\n",
" print(\"\\n%s\" % meaning)\n",
"\n",
" # Assume the guess is not correct; keep guessing until correct.\n",
" correct = False\n",
" while not correct:\n",
" \n",
" print(\"\\nWhat word do you think this is?\")\n",
" show_words(python_words)\n",
" guessed_word = raw_input(\"- \") \n",
" \n",
" # The guess is correct if the guessed word's meaning matches the current meaning.\n",
" if python_words[guessed_word] == meaning:\n",
" print(\"You got it!\")\n",
" correct = True\n",
" else:\n",
" print(\"Sorry, that's just not the right word.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name=\"looping_in_order\"></a>Looping through a dictionary in order\n",
"===\n",
"Dictionaries are quite useful because they allow bits of information to be connected. One of the problems with dictionaries, however, is that they are not stored in any particular order. When you retrieve all of the keys or values in your dictionary, you can't be sure what order you will get them back. There is a quick and easy way to do this, however, when you want them in a particular order.\n",
"\n",
"Let's take a look at the order that results from a simple call to *dictionary.keys()*:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"function\n",
"list\n",
"dictionary\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"for word in python_words.keys():\n",
" print(word)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"The resulting list is not in order. The list of keys can be put in order by passing the list into the *sorted()* function, in the line that initiates the for loop:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"dictionary\n",
"function\n",
"list\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"for word in sorted(python_words.keys()):\n",
" print(word)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This approach can be used to work with the keys and values in order. For example, the words and meanings can be printed in alphabetical order by word:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Dictionary: A collection of key-value pairs.\n",
"Function: A named set of instructions that defines a set of actions in Python.\n",
"List: A collection of values that are not connected, but have an order.\n"
]
}
],
"source": [
"python_words = {'list': 'A collection of values that are not connected, but have an order.',\n",
" 'dictionary': 'A collection of key-value pairs.',\n",
" 'function': 'A named set of instructions that defines a set of actions in Python.',\n",
" }\n",
"\n",
"for word in sorted(python_words.keys()):\n",
" print(\"%s: %s\" % (word.title(), python_words[word]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"In this example, the keys have been put into alphabetical order in the for loop only; Python has not changed the way the dictionary is stored at all. So the next time the dictionary is accessed, the keys could be returned in any order. There is no way to permanently specify an order for the items in an ordinary dictionary, but if you want to do this you can use the [OrderedDict](http://docs.python.org/3.3/library/collections.html#ordereddict-objects) structure."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_looping'></a>Exercises\n",
"---\n",
"#### <a name='exercise_mountain_heights'></a>Mountain Heights\n",
"- Wikipedia has a list of the [tallest mountains in the world](http://en.wikipedia.org/wiki/List_of_mountains_by_elevation), with each mountain's elevation. Pick five mountains from this list.\n",
" - Create a dictionary with the mountain names as keys, and the elevations as values.\n",
" - Print out just the mountains' names, by looping through the keys of your dictionary.\n",
" - Print out just the mountains' elevations, by looping through the values of your dictionary.\n",
" - Print out a series of statements telling how tall each mountain is: \"Everest is 8848 meters tall.\"\n",
"- Revise your output, if necessary.\n",
" - Make sure there is an introductory sentence describing the output for each loop you write.\n",
" - Make sure there is a blank line between each group of statements.\n",
"\n",
"#### Mountain Heights 2\n",
"- Revise your final output from Mountain Heights, so that the information is listed in alphabetical order by each mountain's name.\n",
" - That is, print out a series of statements telling how tall each mountain is: \"Everest is 8848 meters tall.\"\n",
" - Make sure your output is in alphabetical order."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 7.5 : Mountain Heights\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 7.6 : Mountain Heights 2\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='nesting'></a>Nesting\n",
"===\n",
"Nesting is one of the most powerful concepts we have come to so far. Nesting involves putting a list or dictionary inside another list or dictionary. We will look at two examples here, lists inside of a dictionary and dictionaries inside of a dictionary. With nesting, the kind of information we can model in our programs is expanded greatly."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='lists_in_dictionary'></a>Lists in a dictionary\n",
"---\n",
"A dictionary connects two pieces of information. Those two pieces of information can be any kind of data structure in Python. Let's keep using strings for our keys, but let's try giving a list as a value.\n",
"\n",
"The first example will involve storing a number of people's favorite numbers. The keys consist of people's names, and the values are lists of each person's favorite numbers. In this first example, we will access each person's list one at a time."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Eric's favorite numbers are:\n",
"[3, 11, 19, 23, 42]\n",
"\n",
"Ever's favorite numbers are:\n",
"[2, 4, 5]\n",
"\n",
"Willie's favorite numbers are:\n",
"[5, 35, 120]\n"
]
}
],
"source": [
"# This program stores people's favorite numbers, and displays them.\n",
"favorite_numbers = {'eric': [3, 11, 19, 23, 42],\n",
" 'ever': [2, 4, 5],\n",
" 'willie': [5, 35, 120],\n",
" }\n",
"\n",
"# Display each person's favorite numbers.\n",
"print(\"Eric's favorite numbers are:\")\n",
"print(favorite_numbers['eric'])\n",
"\n",
"print(\"\\nEver's favorite numbers are:\")\n",
"print(favorite_numbers['ever'])\n",
"\n",
"print(\"\\nWillie's favorite numbers are:\")\n",
"print(favorite_numbers['willie'])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"We are really just working our way through each key in the dictionary, so let's use a for loop to go through the keys in the dictionary:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/plain": [
"3"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Example for a Sparse Matrix Implementation\n",
"\n",
"sparse_matrix = {}\n",
"sparse_matrix[0] = {1: 12.3, 23: 25.5}\n",
"sparse_matrix[1] = {3: 12.0, 15: 25.5}\n",
"\n",
"sparse_matrix[1][15]\n",
"\n",
"full_matrix = [[1, 3, 4], \n",
" [2, 5, 3]]\n",
"\n",
"full_matrix[1][2]"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Willie's favorite numbers are:\n",
"[5, 35, 120]\n",
"\n",
"Ever's favorite numbers are:\n",
"[2, 4, 5]\n",
"\n",
"Eric's favorite numbers are:\n",
"[3, 11, 19, 23, 42]\n"
]
}
],
"source": [
"# This program stores people's favorite numbers, and displays them.\n",
"favorite_numbers = {'eric': [3, 11, 19, 23, 42],\n",
" 'ever': [2, 4, 5],\n",
" 'willie': [5, 35, 120],\n",
" }\n",
"\n",
"# Display each person's favorite numbers.\n",
"for name in favorite_numbers:\n",
" print(\"\\n%s's favorite numbers are:\" % name.title())\n",
" print(favorite_numbers[name]) "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This structure is fairly complex, so don't worry if it takes a while for things to sink in. The dictionary itself probably makes sense; each person is connected to a list of their favorite numbers.\n",
"\n",
"This works, but we'd rather not print raw Python in our output. Let's use a for loop to print the favorite numbers individually, rather than in a Python list."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Willie's favorite numbers are:\n",
"5\n",
"35\n",
"120\n",
"\n",
"Ever's favorite numbers are:\n",
"2\n",
"4\n",
"5\n",
"\n",
"Eric's favorite numbers are:\n",
"3\n",
"11\n",
"19\n",
"23\n",
"42\n"
]
}
],
"source": [
"# This program stores people's favorite numbers, and displays them.\n",
"favorite_numbers = {'eric': [3, 11, 19, 23, 42],\n",
" 'ever': [2, 4, 5],\n",
" 'willie': [5, 35, 120],\n",
" }\n",
"\n",
"# Display each person's favorite numbers.\n",
"for name in favorite_numbers:\n",
" print(\"\\n%s's favorite numbers are:\" % name.title())\n",
" # Each value is itself a list, so we need another for loop\n",
" # to work with the list.\n",
" for favorite_number in favorite_numbers[name]:\n",
" print(favorite_number) "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Things get a little more complicated inside the for loop. The value is a list of favorite numbers, so the for loop pulls each *favorite\\_number* out of the list one at a time. If it makes more sense to you, you are free to store the list in a new variable, and use that to define your for loop:\n"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Willie's favorite numbers are:\n",
"5\n",
"35\n",
"120\n",
"\n",
"Ever's favorite numbers are:\n",
"2\n",
"4\n",
"5\n",
"\n",
"Eric's favorite numbers are:\n",
"3\n",
"11\n",
"19\n",
"23\n",
"42\n"
]
}
],
"source": [
"# This program stores people's favorite numbers, and displays them.\n",
"favorite_numbers = {'eric': [3, 11, 19, 23, 42],\n",
" 'ever': [2, 4, 5],\n",
" 'willie': [5, 35, 120],\n",
" }\n",
"\n",
"# Display each person's favorite numbers.\n",
"for name in favorite_numbers:\n",
" print(\"\\n%s's favorite numbers are:\" % name.title())\n",
" \n",
" # Each value is itself a list, so let's put that list in a variable.\n",
" current_favorite_numbers = favorite_numbers[name]\n",
" for favorite_number in current_favorite_numbers:\n",
" print(favorite_number) "
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='dictionaries_in_dictionary'></a>Dictionaries in a dictionary\n",
"---\n",
"The most powerful nesting concept we will cover right now is nesting a dictionary inside of a dictionary.\n",
"\n",
"To demonstrate this, let's make a dictionary of pets, with some information about each pet. The keys for this dictionary will consist of the pet's name. The values will include information such as the kind of animal, the owner, and whether the pet has been vaccinated."
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Here is what I know about Willie:\n",
"kind: dog\n",
"owner: eric\n",
"vaccinated: True\n",
"\n",
"Here is what I know about Walter:\n",
"kind: cockroach\n",
"owner: eric\n",
"vaccinated: False\n",
"\n",
"Here is what I know about Peso:\n",
"kind: dog\n",
"owner: chloe\n",
"vaccinated: True\n"
]
}
],
"source": [
"# This program stores information about pets. For each pet,\n",
"# we store the kind of animal, the owner's name, and\n",
"# the breed.\n",
"pets = {'willie': {'kind': 'dog', 'owner': 'eric', 'vaccinated': True},\n",
" 'walter': {'kind': 'cockroach', 'owner': 'eric', 'vaccinated': False},\n",
" 'peso': {'kind': 'dog', 'owner': 'chloe', 'vaccinated': True},\n",
" }\n",
"\n",
"# Let's show all the information for each pet.\n",
"print(\"Here is what I know about Willie:\")\n",
"print(\"kind: \" + pets['willie']['kind'])\n",
"print(\"owner: \" + pets['willie']['owner'])\n",
"print(\"vaccinated: \" + str(pets['willie']['vaccinated']))\n",
"\n",
"print(\"\\nHere is what I know about Walter:\")\n",
"print(\"kind: \" + pets['walter']['kind'])\n",
"print(\"owner: \" + pets['walter']['owner'])\n",
"print(\"vaccinated: \" + str(pets['walter']['vaccinated']))\n",
"\n",
"print(\"\\nHere is what I know about Peso:\")\n",
"print(\"kind: \" + pets['peso']['kind'])\n",
"print(\"owner: \" + pets['peso']['owner'])\n",
"print(\"vaccinated: \" + str(pets['peso']['vaccinated']))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Clearly this is some repetitive code, but it shows exactly how we access information in a nested dictionary. In the first set of `print` statements, we use the name 'willie' to unlock the 'kind' of animal he is, the 'owner' he has, and whether or not he is 'vaccinated'. We have to wrap the vaccination value in the `str` function so that Python knows we want the words 'True' and 'False', not the values `True` and `False`. We then do the same thing for each animal.\n",
"\n",
"Let's rewrite this program, using a for loop to go through the dictionary's keys:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Here is what I know about Peso:\n",
"kind: dog\n",
"owner: chloe\n",
"vaccinated: True\n",
"\n",
"Here is what I know about Willie:\n",
"kind: dog\n",
"owner: eric\n",
"vaccinated: True\n",
"\n",
"Here is what I know about Walter:\n",
"kind: cockroach\n",
"owner: eric\n",
"vaccinated: False\n"
]
}
],
"source": [
"# This program stores information about pets. For each pet,\n",
"# we store the kind of animal, the owner's name, and\n",
"# the breed.\n",
"pets = {'willie': {'kind': 'dog', 'owner': 'eric', 'vaccinated': True},\n",
" 'walter': {'kind': 'cockroach', 'owner': 'eric', 'vaccinated': False},\n",
" 'peso': {'kind': 'dog', 'owner': 'chloe', 'vaccinated': True},\n",
" }\n",
"\n",
"# Let's show all the information for each pet.\n",
"for pet_name, pet_information in pets.items():\n",
" print(\"\\nHere is what I know about %s:\" % pet_name.title())\n",
" print(\"kind: \" + pet_information['kind'])\n",
" print(\"owner: \" + pet_information['owner'])\n",
" print(\"vaccinated: \" + str(pet_information['vaccinated']))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This code is much shorter and easier to maintain. But even this code will not keep up with our dictionary. If we add more information to the dictionary later, we will have to update our print statements. Let's put a second for loop inside the first loop in order to run through all the information about each pet:"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Here is what I know about Peso:\n",
"owner: chloe\n",
"kind: dog\n",
"vaccinated: True\n",
"\n",
"Here is what I know about Willie:\n",
"owner: eric\n",
"kind: dog\n",
"vaccinated: True\n",
"\n",
"Here is what I know about Walter:\n",
"owner: eric\n",
"kind: cockroach\n",
"vaccinated: False\n"
]
}
],
"source": [
"# This program stores information about pets. For each pet,\n",
"# we store the kind of animal, the owner's name, and\n",
"# the breed.\n",
"pets = {'willie': {'kind': 'dog', 'owner': 'eric', 'vaccinated': True},\n",
" 'walter': {'kind': 'cockroach', 'owner': 'eric', 'vaccinated': False},\n",
" 'peso': {'kind': 'dog', 'owner': 'chloe', 'vaccinated': True},\n",
" }\n",
"\n",
"# Let's show all the information for each pet.\n",
"for pet_name, pet_information in pets.items():\n",
" print(\"\\nHere is what I know about %s:\" % pet_name.title())\n",
" # Each animal's dictionary is in 'information'\n",
" for key in pet_information:\n",
" print(key + \": \" + str(pet_information[key]))"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This nested loop can look pretty complicated, so again, don't worry if it doesn't make sense for a while.\n",
"\n",
"- The first loop gives us all the keys in the main dictionary, which consist of the name of each pet.\n",
"- Each of these names can be used to 'unlock' the dictionary of each pet.\n",
"- The inner loop goes through the dictionary for that individual pet, and pulls out all of the keys in that individual pet's dictionary.\n",
"- We print the key, which tells us the kind of information we are about to see, and the value for that key.\n",
"- You can see that we could improve the formatting in the output.\n",
" - We could capitalize the owner's name.\n",
" - We could print 'yes' or 'no', instead of True and False.\n",
" \n"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"Let's show one last version that uses some if statements to clean up our data for printing:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Here is what I know about Peso:\n",
"kind: dog\n",
"vaccinated: yes\n",
"owner: Chloe\n",
"\n",
"Here is what I know about Walter:\n",
"kind: cockroach\n",
"vaccinated: no\n",
"owner: Eric\n",
"\n",
"Here is what I know about Willie:\n",
"kind: dog\n",
"vaccinated: yes\n",
"owner: Eric\n"
]
}
],
"source": [
"# This program stores information about pets. For each pet,\n",
"# we store the kind of animal, the owner's name, and\n",
"# the breed.\n",
"pets = {'willie': {'kind': 'dog', 'owner': 'eric', 'vaccinated': True},\n",
" 'walter': {'kind': 'cockroach', 'owner': 'eric', 'vaccinated': False},\n",
" 'peso': {'kind': 'dog', 'owner': 'chloe', 'vaccinated': True},\n",
" }\n",
"\n",
"# Let's show all the information for each pet.\n",
"for pet_name, pet_information in pets.items():\n",
" print(\"\\nHere is what I know about %s:\" % pet_name.title())\n",
" # Each animal's dictionary is in pet_information\n",
" for key in pet_information:\n",
" if key == 'owner':\n",
" # Capitalize the owner's name.\n",
" print(key + \": \" + pet_information[key].title())\n",
" elif key == 'vaccinated':\n",
" # Print 'yes' for True, and 'no' for False.\n",
" vaccinated = pet_information['vaccinated']\n",
" if vaccinated:\n",
" print('vaccinated: yes')\n",
" else:\n",
" print('vaccinated: no')\n",
" else:\n",
" # No special formatting needed for this key.\n",
" print(key + \": \" + pet_information[key])"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"This code is a lot longer, and now we have nested if statements as well as nested for loops. But keep in mind, this structure would work if there were 1000 pets in our dictionary, and it would work if we were storing 1000 pieces of information about each pet. One level of nesting lets us model an incredible array of information."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='important_note'></a>An important note about nesting\n",
"---\n",
"While one level of nesting is really useful, nesting much deeper than that gets really complicated, really quickly. There are other structures such as classes which can be even more useful for modeling information. In addition to this, we can use Python to store information in a database, which is the proper tool for storing deeply nested information.\n",
"\n",
"Often times when you are storing information in a database you will pull a small set of that information out and put it into a dictionary, or a slightly nested structure, and then work with it. But you will rarely, if ever, work with Python data structures nested more than one level deep."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='exercises_nesting'></a>Exercises\n",
"---\n",
"#### Mountain Heights 3\n",
"- This is an extension of [Mountain Heights](#exercise_mountain_heights). Make sure you save this program under a different filename, such as *mountain\\_heights_3.py*, so that you can go back to your original program if you need to.\n",
" - The list of [tallest mountains in the world](http://en.wikipedia.org/wiki/List_of_mountains_by_elevation) provided all elevations in meters. Convert each of these elevations to feet, given that a meter is approximately 3.28 feet. You can do these calculations by hand at this point.\n",
" - Create a new dictionary, where the keys of the dictionary are still the mountains' names. This time however, the values of the dictionary should be a list of each mountain's elevation in meters, and then in feet: {'everest': [8848, 29029]}\n",
" - Print out just the mountains' names, by looping through the keys of your dictionary.\n",
" - Print out just the mountains' elevations in meters, by looping through the values of your dictionary and pulling out the first number from each list.\n",
" - Print out just the mountains' elevations in feet, by looping through the values of your dictionary and pulling out the second number from each list.\n",
" - Print out a series of statements telling how tall each mountain is: \"Everest is 8848 meters tall, or 29029 feet.\"\n",
"- Bonus:\n",
" - Start with your original program from [Mountain Heights](#exercise_mountain_heights). Write a function that reads through the elevations in meters, and returns a list of elevations in feet. Use this list to create the nested dictionary described above.\n",
"\n",
"#### Mountain Heights 4\n",
"- This is one more extension of Mountain Heights.\n",
" - Create a new dictionary, where the keys of the dictionary are once again the mountains' names. This time, the values of the dictionary are another dictionary. This dictionary should contain the elevation in either meters or feet, and the range that contains the mountain. For example: {'everest': {'elevation': 8848, 'range': 'himalaya'}}.\n",
" - Print out just the mountains' names.\n",
" - Print out just the mountains' elevations.\n",
" - Print out just the range for each mountain.\n",
" - Print out a series of statements that say everything you know about each mountain: \"Everest is an 8848-meter tall mountain in the Himalaya range.\""
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 7.7 : Mountain Heights 3\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 7.8 : Mountain Heights 4\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='overall_challenges'></a>Overall Challenges\n",
"===\n",
"#### Word Wall\n",
"- A word wall is a place on your wall where you keep track of the new words and meanings you are learning. Write a terminal app that lets you enter new words, and a meaning for each word.\n",
" - Your app should have a title bar that says the name of your program.\n",
" - Your program should give users the option to see all words and meanings that have been entered so far.\n",
" - Your program should give users the option to enter a new word and meaning.\n",
" - Your program must not allow duplicate entries.\n",
" - Your program should store existing words and meanings, even after the program closes.\n",
" - Your program should give users the option to modify an existing meaning.\n",
"- Bonus Features\n",
" - Allow users to modify the spelling of words.\n",
" - Allow users to categorize words.\n",
" - Turn the program into a game that quizzes users on words and meanings.\n",
" - (later on) Turn your program into a website that only you can use.\n",
" - (later on) Turn your program into a website that anyone can register for, and use.\n",
" - Add a visualization feature that reports on some statistics about the words and meanings that have been entered.\n",
"\n",
"#### Periodic Table App\n",
"- The [Periodic Table](http://www.ptable.com/) of the Elements was developed to organize information about the elements that make up the Universe. Write a terminal app that lets you enter information about each element in the periodic table.\n",
" - Make sure you include the following information:\n",
" - symbol, name, atomic number, row, and column\n",
" - Choose at least one other piece of information to include in your app.\n",
" - Provide a menu of options for users to:\n",
" - See all the information that is stored about any element, by entering that element's symbol.\n",
" - Choose a property, and see that property for each element in the table.\n",
"- Bonus Features\n",
" - Provide an option to view the symbols arranged like the periodic table. ([hint](#hints_periodic_table))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Challenge: Word Wall\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Challenge: Periodic Table App\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Hints\n",
"===\n",
"#### <a name='hints_periodic_table'></a>Periodic Table App\n",
"- You can use a for loop to loop through each element. Pick out the elements' row numbers and column numbers.\n",
"- Use two nested for loops to print either an element's symbol or a series of spaces, depending on how full that row is."
]
}
],
"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.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"Introducing Functions\n",
"==="
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"One of the core principles of any programming language is, \"Don't Repeat Yourself\". If you have an action that should occur many times, you can define that action once and then call that code whenever you need to carry out that action.\n",
"\n",
"We are already repeating ourselves in our code, so this is a good time to introduce simple functions. Functions mean less work for us as programmers, and effective use of functions results in code that is less error-prone."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name=\"top\"></a>Contents\n",
"===\n",
"- [What are functions?](#what)\n",
" - [General Syntax](#general_syntax)\n",
"- [Examples](#examples)\n",
" - [Returning a Value](#return_value)\n",
" - [Exercises](#exercises)\n",
"- [Challenges](#challenges)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='what'></a>What are functions?\n",
"===\n",
"Functions are a set of actions that we group together, and give a name to. You have already used a number of functions from the core Python language, such as *string.title()* and *list.sort()*. We can define our own functions, which allows us to \"teach\" Python new behavior."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='general_syntax'></a>General Syntax\n",
"---\n",
"A general function looks something like this:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [],
"source": [
"# Let's define a function.\n",
"def function_name(argument_1, argument_2):\n",
" # Do whatever we want this function to do,\n",
" # using argument_1 and argument_2\n",
"\n",
"# Use function_name to call the function.\n",
"function_name(value_1, value_2)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This code will not run, but it shows how functions are used in general."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- **Defining a function**\n",
" - Give the keyword `def`, which tells Python that you are about to *define* a function.\n",
" - Give your function a name. A variable name tells you what kind of value the variable contains; a function name should tell you what the function does.\n",
" - Give names for each value the function needs in order to do its work.\n",
" - These are basically variable names, but they are only used in the function.\n",
" - They can be different names than what you use in the rest of your program.\n",
" - These are called the function's *arguments*.\n",
" - Make sure the function definition line ends with a colon.\n",
" - Inside the function, write whatever code you need to make the function do its work."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- **Using your function**\n",
" - To *call* your function, write its name followed by parentheses.\n",
" - Inside the parentheses, give the values you want the function to work with.\n",
" - These can be variables such as `current_name` and `current_age`, or they can be actual values such as 'eric' and 5."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"<a name='examples'></a>Basic Examples\n",
"===\n",
"For a simple first example, we will look at a program that compliments people. Let's look at the example, and then try to understand the code. First we will look at a version of this program as we would have written it earlier, with no functions."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "subslide"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"You are doing good work, Adriana!\n",
"Thank you very much for your efforts on this project.\n",
"\n",
"You are doing good work, Billy!\n",
"Thank you very much for your efforts on this project.\n",
"\n",
"You are doing good work, Caroline!\n",
"Thank you very much for your efforts on this project.\n"
]
}
],
"source": [
"print(\"You are doing good work, Adriana!\")\n",
"print(\"Thank you very much for your efforts on this project.\")\n",
"\n",
"print(\"\\nYou are doing good work, Billy!\")\n",
"print(\"Thank you very much for your efforts on this project.\")\n",
"\n",
"print(\"\\nYou are doing good work, Caroline!\")\n",
"print(\"Thank you very much for your efforts on this project.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Functions take repeated code, put it in one place, and then you call that code when you want to use it. Here's what the same program looks like with a function."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"You are doing good work, Adriana!\n",
"Thank you very much for your efforts on this project.\n",
"\n",
"You are doing good work, Billy!\n",
"Thank you very much for your efforts on this project.\n",
"\n",
"You are doing good work, Caroline!\n",
"Thank you very much for your efforts on this project.\n"
]
}
],
"source": [
"def thank_you(name):\n",
" # This function prints a two-line personalized thank you message.\n",
" print(\"\\nYou are doing good work, %s!\" % name)\n",
" print(\"Thank you very much for your efforts on this project.\")\n",
" \n",
"thank_you('Adriana')\n",
"thank_you('Billy')\n",
"thank_you('Caroline')"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"In our original code, each pair of print statements was run three times, and the only difference was the name of the person being thanked. When you see repetition like this, you can usually make your program more efficient by defining a function."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"The keyword *def* tells Python that we are about to define a function. We give our function a name, *thank\\_you()* in this case. A variable's name should tell us what kind of information it holds; a function's name should tell us what the variable does. We then put parentheses. Inside these parenthese we create variable names for any variable the function will need to be given in order to do its job. In this case the function will need a name to include in the thank you message. The variable `name` will hold the value that is passed into the function *thank\\_you()*."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"To use a function we give the function's name, and then put any values the function needs in order to do its work. In this case we call the function three times, each time passing it a different name."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### A common error\n",
"A function must be defined before you use it in your program. For example, putting the function at the end of the program would not work."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'thank_you' is not defined",
"output_type": "error",
"traceback": [
"\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[1;32m<ipython-input-1-a1b6b8373f44>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mthank_you\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Adriana'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mthank_you\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Billy'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mthank_you\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'Caroline'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mthank_you\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mname\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
"\u001b[1;31mNameError\u001b[0m: name 'thank_you' is not defined"
]
}
],
"source": [
"thank_you('Adriana')\n",
"thank_you('Billy')\n",
"thank_you('Caroline')\n",
"\n",
"def thank_you(name):\n",
" # This function prints a two-line personalized thank you message.\n",
" print(\"\\nYou are doing good work, %s!\" % name)\n",
" print(\"Thank you very much for your efforts on this project.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"On the first line we ask Python to run the function *thank\\_you()*, but Python does not yet know how to do this function. We define our functions at the beginning of our programs, and then we can use them when we need to."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"A second example\n",
"---\n",
"When we introduced the different methods for [sorting a list](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/lists_tuples.ipynb#sorting_list), our code got very repetitive. It takes two lines of code to print a list using a for loop, so these two lines are repeated whenever you want to print out the contents of a list. This is the perfect opportunity to use a function, so let's see how the code looks with a function.\n",
"\n",
"First, let's see the code we had without a function:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Our students are currently in alphabetical order.\n",
"Aaron\n",
"Bernice\n",
"Cody\n",
"\n",
"Our students are now in reverse alphabetical order.\n",
"Cody\n",
"Bernice\n",
"Aaron\n"
]
}
],
"source": [
"students = ['bernice', 'aaron', 'cody']\n",
"\n",
"# Put students in alphabetical order.\n",
"students.sort()\n",
"\n",
"# Display the list in its current order.\n",
"print(\"Our students are currently in alphabetical order.\")\n",
"for student in students:\n",
" print(student.title())\n",
"\n",
"# Put students in reverse alphabetical order.\n",
"students.sort(reverse=True)\n",
"\n",
"# Display the list in its current order.\n",
"print(\"\\nOur students are now in reverse alphabetical order.\")\n",
"for student in students:\n",
" print(student.title())"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"Here's what the same code looks like, using a function to print out the list:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Our students are currently in alphabetical order.\n",
"Aaron\n",
"Bernice\n",
"Cody\n",
"\n",
"Our students are now in reverse alphabetical order.\n",
"Cody\n",
"Bernice\n",
"Aaron\n"
]
}
],
"source": [
"def show_students(students, message):\n",
" # Print out a message, and then the list of students\n",
" print(message)\n",
" for student in students:\n",
" print(student.title())\n",
"\n",
"students = ['bernice', 'aaron', 'cody']\n",
"\n",
"# Put students in alphabetical order.\n",
"students.sort()\n",
"show_students(students, \"Our students are currently in alphabetical order.\")\n",
"\n",
"#Put students in reverse alphabetical order.\n",
"students.sort(reverse=True)\n",
"show_students(students, \"\\nOur students are now in reverse alphabetical order.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"This is much cleaner code. We have an action we want to take, which is to show the students in our list along with a message. We give this action a name, *show\\_students()*. \n",
"\n",
"This function needs two pieces of information to do its work, the list of students and a message to display. Inside the function, the code for printing the message and looping through the list is exactly as it was in the non-function code.\n",
"\n",
"Now the rest of our program is cleaner, because it gets to focus on the things we are changing in the list, rather than having code for printing the list. We define the list, then we sort it and call our function to print the list. We sort it again, and then call the printing function a second time, with a different message. This is much more readable code."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"### Advantages of using functions\n",
"You might be able to see some advantages of using functions, through this example:\n",
"\n",
"- We write a set of instructions once. We save some work in this simple example, and we save even more work in larger programs."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- When our function works, we don't have to worry about that code anymore. Every time you repeat code in your program, you introduce an opportunity to make a mistake. Writing a function means there is one place to fix mistakes, and when those bugs are fixed, we can be confident that this function will continue to work correctly."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"- We can modify our function's behavior, and that change takes effect every time the function is called. This is much better than deciding we need some new behavior, and then having to change code in many different places in our program."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"For a quick example, let's say we decide our printed output would look better with some form of a bulleted list. Without functions, we'd have to change each print statement. With a function, we change just the print statement in the function:"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Our students are currently in alphabetical order.\n",
"- Aaron\n",
"- Bernice\n",
"- Cody\n",
"\n",
"Our students are now in reverse alphabetical order.\n",
"- Cody\n",
"- Bernice\n",
"- Aaron\n"
]
}
],
"source": [
"def show_students(students, message):\n",
" # Print out a message, and then the list of students\n",
" print(message)\n",
" for student in students:\n",
" print(\"- \" + student.title())\n",
"\n",
"students = ['bernice', 'aaron', 'cody']\n",
"\n",
"# Put students in alphabetical order.\n",
"students.sort()\n",
"show_students(students, \"Our students are currently in alphabetical order.\")\n",
"\n",
"#Put students in reverse alphabetical order.\n",
"students.sort(reverse=True)\n",
"show_students(students, \"\\nOur students are now in reverse alphabetical order.\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"You can think of functions as a way to \"teach\" Python some new behavior. In this case, we taught Python how to create a list of students using hyphens; now we can tell Python to do this with our students whenever we want to."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"<a name='return_value'></a>Returning a Value\n",
"---\n",
"Each function you create can return a value. This can be in addition to the primary work the function does, or it can be the function's main job. The following function takes in a number, and returns the corresponding word for that number:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 None\n",
"1 one\n",
"2 two\n",
"3 three\n"
]
}
],
"source": [
"def get_number_word(number):\n",
" # Takes in a numerical value, and returns\n",
" # the word corresponding to that number.\n",
" if number == 1:\n",
" return 'one'\n",
" elif number == 2:\n",
" return 'two'\n",
" elif number == 3:\n",
" return 'three'\n",
" # ...\n",
" \n",
"# Let's try out our function.\n",
"for current_number in range(0,4):\n",
" number_word = get_number_word(current_number)\n",
" print(current_number, number_word)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "fragment"
}
},
"source": [
"It's helpful sometimes to see programs that don't quite work as they are supposed to, and then see how those programs can be improved. In this case, there are no Python errors; all of the code has proper Python syntax. But there is a logical error, in the first line of the output."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"We want to either not include 0 in the range we send to the function, or have the function return something other than `None` when it receives a value that it doesn't know. Let's teach our function the word 'zero', but let's also add an `else` clause that returns a more informative message for numbers that are not in the if-chain.m"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 zero\n",
"1 one\n",
"2 two\n",
"3 three\n",
"4 I'm sorry, I don't know that number.\n",
"5 I'm sorry, I don't know that number.\n"
]
}
],
"source": [
"def get_number_word(number):\n",
" # Takes in a numerical value, and returns\n",
" # the word corresponding to that number.\n",
" if number == 0:\n",
" return 'zero'\n",
" elif number == 1:\n",
" return 'one'\n",
" elif number == 2:\n",
" return 'two'\n",
" elif number == 3:\n",
" return 'three'\n",
" else:\n",
" return \"I'm sorry, I don't know that number.\"\n",
" \n",
"# Let's try out our function.\n",
"for current_number in range(0,6):\n",
" number_word = get_number_word(current_number)\n",
" print(current_number, number_word)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"If you use a return statement in one of your functions, keep in mind that the function stops executing as soon as it hits a return statement. For example, we can add a line to the *get\\_number\\_word()* function that will never execute, because it comes after the function has returned a value:"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "fragment"
}
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0 zero\n",
"1 one\n",
"2 two\n",
"3 three\n",
"4 I'm sorry, I don't know that number.\n",
"5 I'm sorry, I don't know that number.\n"
]
}
],
"source": [
"def get_number_word(number):\n",
" # Takes in a numerical value, and returns\n",
" # the word corresponding to that number.\n",
" if number == 0:\n",
" return 'zero'\n",
" elif number == 1:\n",
" return 'one'\n",
" elif number == 2:\n",
" return 'two'\n",
" elif number == 3:\n",
" return 'three'\n",
" else:\n",
" return \"I'm sorry, I don't know that number.\"\n",
" \n",
" # This line will never execute, because the function has already\n",
" # returned a value and stopped executing.\n",
" print(\"This message will never be printed.\")\n",
" \n",
"# Let's try out our function.\n",
"for current_number in range(0,6):\n",
" number_word = get_number_word(current_number)\n",
" print(current_number, number_word)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "subslide"
}
},
"source": [
"More Later\n",
"---\n",
"There is much more to learn about functions, but we will get to those details later. For now, feel free to use functions whenever you find yourself writing the same code several times in a program. Some of the things you will learn when we focus on functions:\n",
"\n",
"- How to give the arguments in your function default values.\n",
"- How to let your functions accept different numbers of arguments."
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<a name='exercises'></a>Exercises\n",
"---\n",
"#### Greeter\n",
"- Write a function that takes in a person's name, and prints out a greeting.\n",
" - The greeting must be at least three lines, and the person's name must be in each line.\n",
"- Use your function to greet at least three different people.\n",
"- **Bonus:** Store your three people in a list, and call your function from a `for` loop.\n",
"\n",
"#### Full Names\n",
"- Write a function that takes in a first name and a last name, and prints out a nicely formatted full name, in a sentence. Your sentence could be as simple as, \"Hello, *full\\_name*.\"\n",
"- Call your function three times, with a different name each time.\n",
"\n",
"#### Addition Calculator\n",
"- Write a function that takes in two numbers, and adds them together. Make your function print out a sentence showing the two numbers, and the result.\n",
"- Call your function with three different sets of numbers.\n",
"\n",
"#### Return Calculator\n",
"- Modify *Addition Calculator* so that your function returns the sum of the two numbers. The printing should happen outside of the function.\n",
"\n",
"#### List Exercises - Functions\n",
"- Go back and solve each of the following exercises from the section on [Lists and Tuples](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/lists_tuples.ipynb), using functions to avoid repetetive code:\n",
" - [Ordered Working List](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/lists_tuples.ipynb#exercises_common_operations)\n",
" - [Ordered Numbers](http://nbviewer.ipython.org/urls/raw.github.com/ehmatthes/intro_programming/master/notebooks/lists_tuples.ipynb#exercises_common_operations)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 4.1 : Greeter\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 4.2 : Full Names\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 4.3 : Addition Calculator\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 4.4 : Return Calculator\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Ex 4.5 : List Exercises - Functions\n",
"\n",
"# put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"<a name='challenges'></a>Challenges\n",
"---\n",
"#### Lyrics\n",
"- Many songs follow a familiar variation of the pattern of *verse*, *refrain*, *verse*, *refrain*. The verses are the parts of the song that tell a story - they are not repeated in the song. The refrain is the part of the song that is repeated throughout the song.\n",
"- Find the lyrics to a [song you like](http://www.metrolyrics.com/dont-stop-believin-lyrics-journey.html) that follows this pattern. Write a program that prints out the lyrics to this song, using as few lines of Python code as possible. [hint](#hint_challenges_lyrics)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false,
"slideshow": {
"slide_type": "skip"
}
},
"outputs": [],
"source": [
"# Challenge: Lyrics\n",
"\n",
"# Put your code here"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"[top](#top)"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "skip"
}
},
"source": [
"Hints\n",
"===\n",
"These are placed at the bottom, so you can have a chance to solve exercises without seeing any hints.\n",
"\n",
"#### <a name='hints_lyrics'></a>Lyrics\n",
"- Define a function that prints out the lyrics of the refrain. Use this function any time the refrain comes up in the song."
]
}
],
"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.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Chapter 6 - Objected Oriented Programming"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"-- *A Python Course for the Humanities by Folgert Karsdorp and Maarten van Gompel*"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p style=\"font-size:20px; color:#FF3333; font-weight:bold;\">Chapter is still in DRAFT stage</p>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this chapter we will introduce a new programming paradigm: **Object Oriented Programming**. We will build an application that builds a social network and computes a graph of relations between people on Twitter. The nodes of the graph will be the twitter users, and the directed edges indicate that one speaks to another. The edges will carry a weight representing the number of times messages were sent. \n",
"\n",
"Given a twitter corpus, we will extract who talks to whom, and whenever a connection is found, an edge is added to our graph, or an existing edge is strenghtened.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Object oriented programming is a data-centered programming paradigm that is based on the idea of grouping data and functions that act on particular data in so-called **classes**. A class can be seen as a complex data-type, a template if you will. Variables that are of that data type are said to be **objects** or **instances** of that class.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"An example will clarify things:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class Person:\n",
" def __init__(self, name, age):\n",
" self.name = name\n",
" self.age = age"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ok, several things happen here. Here we created a class Person with a function `__init__`. Functions that start with underscores are always special functions to Python which are connected with other built-in aspects of the language. The initialisation function will be called when an object of that initialised. Let's do so:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"author = Person(\"Maarten\", 30)\n",
"print(\"My name is \" + author.name)\n",
"print(\"My age is \" + str(author.age))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Functions within a class are called **methods**. The initialisation method assigns the two parameters that are passed to variables that *belong to the object*, within a class definition the object is always represented by `self`.\n",
"\n",
"The first argument of a method is always `self`, and it will always point to the instance of the class. This first argument however is never explicitly specified when you call the method. It is implicitly passed by Python itself. That is why you see a discrepancy between the number of arguments in the instantiation and in the class definition.\n",
"\n",
"\n",
"Any variable or methods in a class can be accessed using the period (`.`) syntax:\n",
"\n",
" object.variable \n",
"\n",
"or:\n",
"\n",
" object.method\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In the above example we printed the name and age. We can turn this into a method as well, thus allowing any person to introduce himself/herself. Let's extend our example:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class Person:\n",
" def __init__(self, name, age):\n",
" self.name = name\n",
" self.age = age\n",
" \n",
" def introduceyourself(self):\n",
" print(\"My name is \" + self.name)\n",
" print(\"My age is \" + str(self.age))\n",
" \n",
"author = Person(\"Maarten\",30)\n",
"author.introduceyourself()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Do you see what happens here? Do you understand the role of `self` and notation with the period?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Unbeknowst to you, we have already made use of countless objects and methods throughout this course. Things like strings, lists, sets, dictionaries are all objects! Isn't that a shock? :) The object oriented paradigm is ubiquitous in Python!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Exercise"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Add a variable `gender` (a string) to the Person class and adapt the initialisation method accordingly. Also add a method `ismale()` that uses this new information and returns a boolean value (True/False).\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"#adapt the code:\n",
"\n",
"class Person:\n",
" def __init__(self, name, age):\n",
" self.name = name\n",
" self.age = age\n",
" \n",
" def introduceyourself(self):\n",
" print(\"My name is \" + self.name)\n",
" print(\"My age is \" + str(self.age))\n",
" \n",
"author = Person(\"Maarten\",30)\n",
"author.introduceyourself()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Inheritance *"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"One of the neat things you can do with classes is that you can build more specialised classes on top of more generic classes. `Person` for instance is a rather generic concept. We can use this generic class to build a more specialised class `Teacher`, a person that teaches a course. If you use inheritance, everything that the parent class could do, the inherited class can do as well!\n",
"\n",
"The syntax for inheritance is as follows, do not confuse it with parameters in a function/method definition. We also add an extra method `stateprofession()` otherwise `Teacher` would be no different than `Person`:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class Person:\n",
" def __init__(self, name, age):\n",
" self.name = name\n",
" self.age = age\n",
" \n",
" def introduceyourself(self):\n",
" print(\"My name is \" + self.name)\n",
" print(\"My age is \" + str(self.age))\n",
"\n",
" \n",
"class Teacher(Person): #this class inherits the class above!\n",
" def stateprofession(self):\n",
" print(\"I am a teacher!\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"author = Teacher(\"Maarten\",30)\n",
"author.introduceyourself()\n",
"author.stateprofession()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Exercise"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If the class `Person` would have already had a method `stateprofession`, then it would have been overruled (we say *overloaded*) by the one in the `Teacher` class. Edit the example above, add a print like *\"I have no profession! :'(\"* and see that nothings changes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Instead of completely overloading a method, you can also call the method of the parent class. The following example contains modified versions of all methods, adds some extra methods and variables to keep track of the courses that are taught by the teacher. The edited methods call the method of the parent class the avoid repetition of code (one of the deadly sins of computer programming):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class Teacher(Person): #this class inherits the class above!\n",
" def __init__(self, name, age):\n",
" self.courses = [] #initialise a new variable\n",
" super().__init__(name,age) #call the init of Person\n",
" \n",
" def stateprofession(self):\n",
" print(\"I am a teacher!\") \n",
" \n",
" def introduceyourself(self):\n",
" super().introduceyourself() #call the introduceyourself() of the Person\n",
" self.stateprofession()\n",
" print(\"I teach \" + str(self.nrofcourses()) + \" course(s)\")\n",
" for course in self.courses:\n",
" print(\"I teach \" + course)\n",
" \n",
" \n",
" \n",
" def addcourse(self, course):\n",
" self.courses.append(course)\n",
" \n",
" def nrofcourses(self):\n",
" return len(self.courses)\n",
" \n",
" \n",
"author = Teacher(\"Maarten\",30)\n",
"author.addcourse(\"Python\")\n",
"author.introduceyourself()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Operator overloading"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"If you write your own classes, you can define what needs to happen if an operator such as for example `+`,`/` or `<` is used on your class. You can also define what happens when the keyword `in` or built-in functions such as `len()` are you used with your class. This allows for a very elegant way of programming. Each of these operators and built-in functions have an associated method which you can overload. All of these methods start, like `__init__`, with a double underscore.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"For example. Let's allow comparison of tweets using the '<' and '>' operators. The methods for the opertors are respectively `__lt__` and `__gt__`, both take one argument, the other object to compare to. A tweet qualifies as greater than another if it is a newer, more recent, tweet:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class Tweet:\n",
" def __init__(self, message, time):\n",
" self.message = message\n",
" self.time = time # we will assume here that time is a numerical value\n",
" \n",
" def __lt__(self, other):\n",
" return self.time < other.time\n",
" \n",
" def __gt__(self, other):\n",
" return self.time > other.time \n",
" \n",
"\n",
"oldtweet = Tweet(\"this is an old tweet\",20)\n",
"newtweet = Tweet(\"this is a new tweet\",1000)\n",
"print(newtweet > oldtweet)\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You may not yet see much use in this, but consider for example the built-in function `sorted()`. Having such methods defined now means we can sort our tweets! And because we defined the methods `__lt__` and `__gt__` based on time. It will automatically sort them on time, from old to new:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"tweets = [newtweet,oldtweet]\n",
"\n",
"for tweet in sorted(tweets):\n",
" print(tweet.message)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Exercise"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Remember the `in` keyword? Used checking items in lists and keys in dictionaries? To recap:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"fruits = ['banana','pear','orange']\n",
"print('pear' in fruits)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Overloading this operator is done using the `__contains__` method. It takes as extra argument the item that is being searched for ('pear' in the above example). The method should return a boolean value. For tweets, let's implement support for the `in` operator and have it check whether a certain word is in the tweet."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class Tweet:\n",
" def __init__(self, message, time):\n",
" self.message = message\n",
" self.time = time\n",
"\n",
" def __lt__(self, other):\n",
" return self.time < other.time\n",
" \n",
" def __contains__(self, word):\n",
" #Implement the method\n",
"\n",
"tweet = \"I just flushed my toilet\"\n",
"#now write code to check if the word \"flushed\" is in the tweet\n",
"#and print something nice if that's the case\n",
"\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Iteration over an object"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Remember how we can iterate over lists and dictionaries using a for loop? To recap:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"fruits = ['banana','pear','orange']\n",
"for fruit in fruits:\n",
" print(fruit)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can do the same for our own object. We can make them support iteration. This is done by overloading the `__iter__` method. It takes no extra arguments and should be a **generator**. Which if you recall means that you should use `yield` instead of `return`. Consider the following class `TwitterUser`, if we iterate over an instance of that class, we want to iterate over all tweets. To make it more fun, let's iterate in chronologically sorted order:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"class TwitterUser:\n",
" def __init__(self, name):\n",
" self.name = name\n",
" self.tweets = [] #This will be a list of all tweets, these should be Tweet objects\n",
" \n",
" def append(self, tweet):\n",
" assert isinstance(tweet, Tweet) #this code will check if tweet is an instance\n",
" #of the Tweet class. If not, an exception\n",
" #will be raised\n",
" #append the tweet to our list\n",
" self.tweets.append(tweet)\n",
" \n",
" def __iter__(self):\n",
" for tweet in sorted(self.tweets):\n",
" yield tweet\n",
"\n",
" \n",
"tweeter = TwitterUser(\"proycon\")\n",
"tweeter.append(Tweet(\"My peanut butter sandwich has just fallen bottoms-down\",4)) \n",
"tweeter.append(Tweet(\"Tying my shoelaces\",2)) \n",
"tweeter.append(Tweet(\"Wiggling my toes\",3)) \n",
"tweeter.append(Tweet(\"Staring at a bird\",1)) \n",
"\n",
"for tweet in tweeter:\n",
" print(tweet.message)\n",
"\n",
" \n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Exercise"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The method `__len__` is invoked when the built-in function `len()` is used. We want it to return the number of tweets a user has. Implement it in the example above and then run the following test, which should return `True` if you did well:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"print(len(tweeter) == 4)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Extracting a social network of Twitter users"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we will turn to the practical assignment of this chapter. The extraction of a graph of who tweets whom. For this purpose we make available the dataset [twitterdata.zip](http://lst.science.ru.nl/~proycon/twitterdata.zip) , download and extract it in a location of your choice."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The program we are writing will consist of three classes: `Tweet`,`TweetUser` and `TweetGraph`. `TweetGraph` will maintain a dictionary of users (`TweetUser`), these are the nodes of our graph. `TweetUser` will in turn maintain a list of tweets (`Tweet`). `TweetUser` will also maintain a dictionary in which the keys are other TweetUser instances and the values indicate the weight of the relationship. This thus makes up the edges of our graph.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You will not have to write everything from scratch, we will provide a full skeleton in which you have to implement certain methods. We are going to use our external editor for this assignment. Copy the below code, edit it, and save it as `tweetnet.py`. When done, run the program from the command line, passing it one parameter, the directory where the *txt files from twitterdata.zip can be found: *python3 tweetnet.py /path/to/twitterdata/*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
"#! /usr/bin/env python3\n",
"# -*- coding: utf8 -*-\n",
"\n",
"import sys\n",
"import preprocess\n",
"\n",
"\n",
"class Tweet: \n",
" def __init__(self, message, time):\n",
" self.message = message\n",
" self.time = time\n",
" \n",
"\n",
"class TwitterUser:\n",
" def __init__(self, name):\n",
" self.name = name\n",
" self.tweets = [] #This will be a list of all tweets \n",
" self.relations = {} #This will be a dictionary in which the keys are TwitterUser objects and the values are the weight of the relation (an integer) \n",
" \n",
" def append(self, tweet):\n",
" assert isinstance(tweet, Tweet) #this is a test, if tweet is not an instance\n",
" #of Tweet, it will raise an Exception.\n",
" self.tweets.append(tweet)\n",
" \n",
" def __iter__(self):\n",
" #This function, a generator, should iterate over all tweets\n",
" #<INSERT YOUR CODE HERE>\n",
" \n",
" \n",
" def __hash__(self): \n",
" #For an object to be usable as a dictionary key, it must have a hash method. Call the hash() function over something that uniquely defined this object\n",
" #and thus can act as a key in a dictionary. In our case, the user name is good, as no two users will have the same name: \n",
" return hash(self.name)\n",
" \n",
" \n",
" def addrelation(self, user):\n",
" if user and user != self.name: #user must not be empty, and must not be the user itself\n",
" if user in self.relations:\n",
" #the user is already in our relations, strengthen the bond:\n",
" self.relations[user] += 1\n",
" elif user in graph: \n",
" #the user exists in the graph, we can add a relation!\n",
" self.relations[user] = 1\n",
" #if the user does not exist in the graph, no relations will be added \n",
" \n",
" \n",
" def computerelations(self, graph):\n",
" for tweet in self:\n",
" #tokenise the actual tweet content (use the tokeniser in preprocess!):\n",
" tokens = #<INSERT YOUR CODE HERE>\n",
" \n",
" #Search for @username tokens, extract the username, and call self.addrelation()\n",
" #<INSERT YOUR CODE HERE>\n",
" \n",
" \n",
" def printrelations(self):\n",
" #print the relations, include both users and the weight\n",
" #<INSERT YOUR CODE HERE>\n",
" \n",
" \n",
" def gephioutput(self): \n",
" #produce CSV output that gephi can import\n",
" for recipient, weight in self.relations.items():\n",
" for i in range(0, weight):\n",
" yield self.name + \",\" + recipient\n",
" \n",
" \n",
"class TwitterGraph:\n",
" def __init__(self, corpusdirectory): \n",
" self.users = {} #initialisation of dictionary that will store all twitter users. They keys are the names, the values are TwitterUser objects.\n",
" #the keys are the usernames (strings), and the values are\n",
" # TweetUser instances\n",
" \n",
" #Load the twitter corpus \n",
" #tip: use preprocess.find_corpusfiles and preprocess.read_corpus_file,\n",
" #do not use preproces.readcorpus as that will include sentence segmentation\n",
" #which we do not want\n",
" \n",
" #Each txt file contains the tweets of one user.\n",
" #all files contain three columns, separated by a TAB (\\t). The first column\n",
" #is the user, the second the time, and the third is the tweetmessage itself.\n",
" #Create Tweet instances for every line that contains a @ (ignore other lines \n",
" #to conserve memory). Add those tweet instances to the right TweetUser. Create\n",
" #TweetUser instances as new users are encountered.\n",
" \n",
" #self.users[user], which user being the username (string), should be an instance of the\n",
" #of TweetUser\n",
" \n",
" #<INSERT YOUR CODE HERE>\n",
"\n",
" \n",
" #Compute relations between users\n",
" for user in self:\n",
" assert isinstance(user,TweetUser)\n",
" user.computerelations(self)\n",
" \n",
"\n",
" \n",
" def __contains__(self, user):\n",
" #Does this user exist?\n",
" return user in self.users\n",
" \n",
" def __iter__(self):\n",
" #Iterate over all users\n",
" for user in self.users.values():\n",
" yield user\n",
"\n",
" def __getitem__(self, user): \n",
" #Retrieve the specified user\n",
" return self.users[user]\n",
" \n",
"\n",
"#this is the actual main body of the program. The program should be passed one parameter\n",
"#on the command line: the directory that contains the *.txt files from twitterdata.zip.\n",
"\n",
"#We instantiate the graph, which will load and compute all relations\n",
"twittergraph = TwitterGraph(sys.argv[1])\n",
"\n",
"#We output all relations:\n",
"for twitteruser in twittergraph:\n",
" twitteruser.printrelations()\n",
"\n",
"#And we output to a file so you can visualise your graph in the program GEPHI\n",
"f = open('gephigraph.csv','wt',encoding='utf-8')\n",
"for twitteruser in twittergraph:\n",
" for line in twitteruser.gephioutput(): \n",
" f.write(line + \"\\n\")\n",
"f.close()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ignore this, it's only here to make the page pretty:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [
{
"data": {
"text/html": [
"/*\n",
"Placeholder for custom user CSS\n",
"\n",
"mainly to be overridden in profile/static/custom/custom.css\n",
"\n",
"This will always be an empty file in IPython\n",
"*/\n",
"<style>\n",
" @import url(http://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,700,700italic);\n",
"\n",
" div.cell{\n",
" font-family:'roboto','helvetica','sans';\n",
" color:#444;\n",
" width:800px;\n",
" margin-left:16% !important;\n",
" margin-right:auto;\n",
" }\n",
"\n",
" div.text_cell_render{\n",
" font-family: 'roboto','helvetica','sans';\n",
" line-height: 145%;\n",
" font-size: 120%;\n",
" color:#444;\n",
" width:800px;\n",
" margin-left:auto;\n",
" margin-right:auto;\n",
" }\n",
" .CodeMirror{\n",
" font-family: \"Menlo\", source-code-pro,Consolas, monospace;\n",
" }\n",
" .prompt{\n",
" display: None;\n",
" } \n",
" .warning{\n",
" color: rgb( 240, 20, 20 )\n",
" } \n",
"</style>\n",
"<script>\n",
" MathJax.Hub.Config({\n",
" TeX: {\n",
" extensions: [\"AMSmath.js\"]\n",
" },\n",
" tex2jax: {\n",
" inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\n",
" displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ]\n",
" },\n",
" displayAlign: 'center', // Change this to 'center' to center equations.\n",
" \"HTML-CSS\": {\n",
" styles: {'.MathJax_Display': {\"margin\": 4}}\n",
" }\n",
" });\n",
"</script>"
],
"text/plain": [
"<IPython.core.display.HTML at 0x1047bc5f8>"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"from IPython.core.display import HTML\n",
"def css_styling():\n",
" styles = open(\"styles/custom.css\", \"r\").read()\n",
" return HTML(styles)\n",
"css_styling()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<p><small><a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\"><img alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-sa/4.0/88x31.png\" /></a><br /><span xmlns:dct=\"http://purl.org/dc/terms/\" property=\"dct:title\">Python Programming for the Humanities</span> by <a xmlns:cc=\"http://creativecommons.org/ns#\" href=\"http://fbkarsdorp.github.io/python-course\" property=\"cc:attributionName\" rel=\"cc:attributionURL\">http://fbkarsdorp.github.io/python-course</a> is licensed under a <a rel=\"license\" href=\"http://creativecommons.org/licenses/by-sa/4.0/\">Creative Commons Attribution-ShareAlike 4.0 International License</a>. Based on a work at <a xmlns:dct=\"http://purl.org/dc/terms/\" href=\"https://github.com/fbkarsdorp/python-course\" rel=\"dct:source\">https://github.com/fbkarsdorp/python-course</a>.</small></p>"
]
}
],
"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.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Awesome Jupyter Notebook\n",
"> Session 2\n",
"\n",
"> Python Workshop for Benjama EEP\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Objectives\n",
"1. bool - True, False\n",
"1. [If-else](04 If Statements.ipynb)\n",
"2. [While](05 While Loops and User Input.ipynb)\n",
"3. For\n",
"4. [Function](07 Introduction to Functions.ipynb)\n",
"5. [Object Oriented Programming](Object Oriented Programming.ipynb)\n",
"6. [Awesome Data Science Notebooks](https://github.com/jakevdp/PythonDataScienceHandbook)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## List - ลำดับ\n",
"```python\n",
"speakers = [ 'K', 'Kai', 'Or', 'Paul', 'Tom', 'Woot' ]\n",
"heights = [ 180, 164, 165, 165, 180, 170 ]\n",
"pop = [ 3.25, 3.9, 4, 3, 3.5, 3.44 ] \n",
"```\n",
"\n",
"### เข้าถึงข้อมูลในลำดับ\n",
"```python\n",
"print(speakers[0])\n",
"print(speakers[1])\n",
"print(speakers[2])\n",
"```\n",
"\n",
"### การกำหนดค่าลำดับ\n",
"```python\n",
"speakers[0] = 'Kriengsak'\n",
"print(str(speakers))\n",
"speakers[0] = 'K'\n",
"print(str(speakers))\n",
"```\n",
"\n",
"### การหาค่าต่ำสุด-สูงสุด-ผลรวม ของลำดับ\n",
"```python\n",
"print( max(heights) )\n",
"print( min(pop) )\n",
"print( sum(heights) )\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## bool - ค่าจริง-เท็จ\n",
"```python\n",
"speakers = [ 'K', 'Kai', 'Or', 'Paul', 'Tom', 'Woot' ]\n",
"heights = [ 180, 164, 165, 165, 180, 170 ]\n",
"popularity = [ 3.25, 3.9, 4, 3, 3.5, 3.44 ] \n",
"\n",
"print( 'K' in speakers )\n",
"print( 'Justin Bieber' in speakers )\n",
"print( speakers[0] == 'K' )\n",
"print( speakers[3] == 'Wichit' )\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## If-else\n",
"\n",
"### เงื่อนไขเดียว\n",
"```python\n",
"if ค่าจริงเท็จ: \n",
" คำสั่งที่จะทำเมื่อเป็นจริง\n",
"else:\n",
" คำสั่งที่จะทำเมื่อเป็นเท็จ\n",
"```\n",
"\n",
"> ต้วอย่าง\n",
"\n",
"```python\n",
"if 'Justin Bieber' in speakers:\n",
" print('นักร้องดังนานาชาติมา')\n",
"else:\n",
" print('ไม่มีนักร้องดังมางาน')\n",
"```\n",
"\n",
"### หลายเงื่อนไข\n",
"```python\n",
"if เงื่อนไข1:\n",
" คำสั่งที่จะทำเมื่อเงื่อนไข1เป็นจริง\n",
"elif เงื่อนไข2:\n",
" คำสั่งที่จะทำเมื่อเงื่อนไข2เป็นจริง\n",
"elif เงื่อนไข3:\n",
" คำสั่งที่จะทำเมื่อเงื่อนไข3เป็นจริง\n",
"else: \n",
" คำสั่งที่จะทำเมื่อเงื่อนไขทั้งหมดเป็นเท็จ\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## While\n",
"```python\n",
"while เงื่อนไข:\n",
" คำสั่งที่จะทำเมื่อตรวจสอบเงื่อนไขในแต่ละรอบแล้วเป็นจริง\n",
"```\n",
"\n",
"> ตัวอย่าง\n",
"\n",
"```python\n",
"i = 0\n",
"while i < 10:\n",
" print('i = '+str(i))\n",
" i = i+1\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## For\n",
"```python\n",
"for สมาชิก in ลำดับ:\n",
" คำสั่งที่จะทำสำหรับสมาชิกแต่ละตัว\n",
"```\n",
"\n",
"> ตัวอย่าง\n",
"\n",
"```python\n",
"speakers = [ 'K', 'Kai', 'Or', 'Paul', 'Tom', 'Woot' ]\n",
"for speaker in speakers:\n",
" print(speaker)\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Function - การเขียนฟังก์ชัน\n",
"```python\n",
"def ชื่อฟังก์ชัน(รายการข้อมูลที่รับมา):\n",
" คำสั่งภายในฟังก์ชัน\n",
"```\n",
"\n",
"> ตัวอย่าง\n",
"\n",
"```python\n",
"def statsummary(a):\n",
" import statistics\n",
" print('ลำดับ: '+str(a))\n",
" print('ค่าเฉลี่ยของลำดับ: '+str(statistics.mean(a)))\n",
" print('ค่าเบี่ยงเบนมาตรฐานของลำดับ: '+str(statistics.stdev(a)))\n",
"\n",
"heights = [ 180, 164, 165, 165, 180, 170 ]\n",
"statssummary(heights)\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Dictionary/json - ชนิดข้อมูลที่นิยมใช้แลกเปลี่ยนข้อมูล\n",
"* อัตราแลกเปลี่ยน https://api.fixer.io/lastest\n",
"* ข้อมูลผู้ใช้บน github https://api.github.com/users \n",
"* Google: YouTube Data API, Live Stream, Analytics https://developers.google.com/youtube/v3/\n",
"* Facebook: [Graph API](https://developers.facebook.com/docs/graph-api/)\n",
"* [The Movie Database](https://www.themoviedb.org/)\n",
"\n",
"### ข้อมูลจากเครื่องวิทยากร\n",
"#### แบบ json\n",
"* http://หมายเลขไอพีเครื่องวิทยากร/api/info\n",
"* http://หมายเลขไอพีเครื่องวิทยากร/api/exchange\n",
"\n",
"#### แบบข้อความธรรมดา\n",
"* http://หมายเลขไอพีเครื่องวิทยากร/speakers/txt\n",
"* http://หมายเลขไอพีเครื่องวิทยากร/height/txt\n",
"* http://หมายเลขไอพีเครื่องวิทยากร/pop/txt\n",
"\n",
"### รูปแบบข้อมูล dictionary\n",
"```python\n",
"speakers = {\n",
" 'K': 'เกรียงศักดิ์',\n",
" 'Woot': 'วราวุฒิ',\n",
" 'Tom': 'ไพชยนต์'\n",
"}\n",
"```\n",
"\n",
"เนื่องจาก str ใน python ใช้ได้ทั้ง '' และ \"\" \n",
"```python\n",
"speakers = {\n",
" \"K\": \"เกรียงศักดิ์\",\n",
" \"Woot\": \"วราวุฒิ\",\n",
" \"Tom\": \"ไพชยนต์\"\n",
"}\n",
"```\n",
"\n",
"> ตัวอย่าง info\n",
"\n",
"```python\n",
"{\n",
" \"K\": {\n",
" \"ชื่อ-สกุล\": \"เกรียงศักดิ์ ตรีประพิณ\",\n",
" \"e-mail\": \"kriengsak.t@ubu.ac.th\",\n",
" \"picture\": \"image/K.jpg\"\n",
" },\n",
" \"Kai\": {\n",
" \"ชื่อ-สกุล\": \"ปิยนันท์ พนากานต์\", \n",
" \"e-mail\": \"piyanan.p@ubu.ac.th\",\n",
" \"picture\": \"image/Kai.jpg\"\n",
" },\n",
" \"Or\": {\n",
" \"ชื่อ-สกุล\": \"วาสนา เหง้าเกษ\",\n",
" \"e-mail\": \"wasana.n@ubu.ac.th\",\n",
" \"picture\": \"image/Or.jpg\"\n",
" },\n",
" \"Paul\": {\n",
" \"ชื่อ-สกุล\": \"วิชิต สมบัติ\",\n",
" \"e-mail\": \"wichit.s@ubu.ac.th\",\n",
" \"picture\": \"image/Paul.jpg\"\n",
" },\n",
" \"Tom\": {\n",
" \"ชื่อ-สกุล\": \"ไพชยนต์ คงไชย\",\n",
" \"e-mail\": \"phaichayon.k@ubu.ac.th\",\n",
" \"picture\": \"image/Tom.jpg\"\n",
" },\n",
" \"Woot\": {\n",
" \"ชื่อ-สกุล\": \"วราวุฒิ ผ้าเจริญ\",\n",
" \"e-mail\": \"warawoot.p@ubu.ac.th\",\n",
" \"picture\": \"image/Woot.jpg\"\n",
" }\n",
"}\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## การรับส่งข้อมูล json\n",
"```python\n",
"import requests\n",
"r = requests.get('http://api.fixer.io/latest')\n",
"x = r.json()\n",
"print( type(x) )\n",
"print(x)\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## More on import \n",
"คำสั่งเพื่อสร้างหน้าต่างขึ้นมา\n",
"\n",
"```python\n",
"import sys\n",
"import PyQt5.QtWidgets \n",
"\n",
"app = PyQt5.QtWidgets.QApplication(sys.argv)\n",
"w = PyQt5.QtWidgets.QWidget()\n",
"w.resize(250, 150)\n",
"w.move(300, 300)\n",
"w.show()\n",
"\n",
"sys.exit(app.exec_())\n",
"```\n",
"\n",
"เราสามารถทำการย่อชื่อโดยใช้คำสั่ง import ช่วยให้สั้นลงได้ดังนี้\n",
"```python\n",
"import sys\n",
"from PyQt5.QtWidgets import QApplication, QWidget\n",
"\n",
"app = QApplication(sys.argv)\n",
"w = QWidget()\n",
"w.resize(250, 150)\n",
"w.move(300, 300)\n",
"w.show()\n",
"\n",
"sys.exit(app.exec_())\n",
"```\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# แนวคิดเชิงวัตถุ และการสืบทอดคุณสมบัติ\n",
"เราสามารถเขียนนิยามหน้าต่างของเราเองได้ดังนี้\n",
"```python\n",
"import sys\n",
"from PyQt5.QtWidgets import QApplication, QWidget\n",
"from PyQt5.QtGui import QIcon\n",
"\n",
"\n",
"class MyWindow(QWidget):\n",
" \n",
" def __init__(self):\n",
" super().__init__()\n",
" self.setGeometry(300, 300, 250, 150)\n",
" self.setWindowTitle('Icon')\n",
" self.setWindowIcon(QIcon('icon.png'))\n",
" self.show()\n",
" \n",
" \n",
"if __name__ == '__main__':\n",
" \n",
" app = QApplication(sys.argv)\n",
" ex = Example()\n",
" sys.exit(app.exec_())\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.5.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
import sys
import PyQt5.QtWidgets
app = PyQt5.QtWidgets.QApplication(sys.argv)
w = PyQt5.QtWidgets.QWidget()
w.resize(250, 150)
w.move(300, 300)
w.show()
sys.exit(app.exec_())
import sys
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtGui import QIcon
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 300, 220)
self.setWindowTitle('Icon')
self.setWindowIcon(QIcon('csubu.jpg'))
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyWindow()
sys.exit(app.exec_())
% Default to the notebook output style
% Inherit from the specified cell style.
\documentclass[11pt]{article}
\usepackage[T1]{fontenc}
% Nicer default font (+ math font) than Computer Modern for most use cases
\usepackage{mathpazo}
% Basic figure setup, for now with no caption control since it's done
% automatically by Pandoc (which extracts ![](path) syntax from Markdown).
\usepackage{graphicx}
% We will generate all images so they have a width \maxwidth. This means
% that they will get their normal width if they fit onto the page, but
% are scaled down if they would overflow the margins.
\makeatletter
\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth
\else\Gin@nat@width\fi}
\makeatother
\let\Oldincludegraphics\includegraphics
% Set max figure width to be 80% of text width, for now hardcoded.
\renewcommand{\includegraphics}[1]{\Oldincludegraphics[width=.8\maxwidth]{#1}}
% Ensure that by default, figures have no caption (until we provide a
% proper Figure object with a Caption API and a way to capture that
% in the conversion process - todo).
\usepackage{caption}
\DeclareCaptionLabelFormat{nolabel}{}
\captionsetup{labelformat=nolabel}
\usepackage{adjustbox} % Used to constrain images to a maximum size
\usepackage{xcolor} % Allow colors to be defined
\usepackage{enumerate} % Needed for markdown enumerations to work
\usepackage{geometry} % Used to adjust the document margins
\usepackage{amsmath} % Equations
\usepackage{amssymb} % Equations
\usepackage{textcomp} % defines textquotesingle
% Hack from http://tex.stackexchange.com/a/47451/13684:
\AtBeginDocument{%
\def\PYZsq{\textquotesingle}% Upright quotes in Pygmentized code
}
\usepackage{upquote} % Upright quotes for verbatim code
\usepackage{eurosym} % defines \euro
\usepackage[mathletters]{ucs} % Extended unicode (utf-8) support
\usepackage[utf8x]{inputenc} % Allow utf-8 characters in the tex document
\usepackage{fancyvrb} % verbatim replacement that allows latex
\usepackage{grffile} % extends the file name processing of package graphics
% to support a larger range
% The hyperref package gives us a pdf with properly built
% internal navigation ('pdf bookmarks' for the table of contents,
% internal cross-reference links, web links for URLs, etc.)
\usepackage{hyperref}
\usepackage{longtable} % longtable support required by pandoc >1.10
\usepackage{booktabs} % table support for pandoc > 1.12.2
\usepackage[inline]{enumitem} % IRkernel/repr support (it uses the enumerate* environment)
\usepackage[normalem]{ulem} % ulem is needed to support strikethroughs (\sout)
% normalem makes italics be italics, not underlines
% Colors for the hyperref package
\definecolor{urlcolor}{rgb}{0,.145,.698}
\definecolor{linkcolor}{rgb}{.71,0.21,0.01}
\definecolor{citecolor}{rgb}{.12,.54,.11}
% ANSI colors
\definecolor{ansi-black}{HTML}{3E424D}
\definecolor{ansi-black-intense}{HTML}{282C36}
\definecolor{ansi-red}{HTML}{E75C58}
\definecolor{ansi-red-intense}{HTML}{B22B31}
\definecolor{ansi-green}{HTML}{00A250}
\definecolor{ansi-green-intense}{HTML}{007427}
\definecolor{ansi-yellow}{HTML}{DDB62B}
\definecolor{ansi-yellow-intense}{HTML}{B27D12}
\definecolor{ansi-blue}{HTML}{208FFB}
\definecolor{ansi-blue-intense}{HTML}{0065CA}
\definecolor{ansi-magenta}{HTML}{D160C4}
\definecolor{ansi-magenta-intense}{HTML}{A03196}
\definecolor{ansi-cyan}{HTML}{60C6C8}
\definecolor{ansi-cyan-intense}{HTML}{258F8F}
\definecolor{ansi-white}{HTML}{C5C1B4}
\definecolor{ansi-white-intense}{HTML}{A1A6B2}
% commands and environments needed by pandoc snippets
% extracted from the output of `pandoc -s`
\providecommand{\tightlist}{%
\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
% Add ',fontsize=\small' for more characters per line
\newenvironment{Shaded}{}{}
\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{{#1}}}
\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{{#1}}}
\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{{#1}}}}
\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{{#1}}}
\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{{#1}}}
\newcommand{\RegionMarkerTok}[1]{{#1}}
\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{{#1}}}}
\newcommand{\NormalTok}[1]{{#1}}
% Additional commands for more recent versions of Pandoc
\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{{#1}}}
\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{{#1}}}
\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{{#1}}}
\newcommand{\ImportTok}[1]{{#1}}
\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{{#1}}}}
\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{{#1}}}
\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{{#1}}}}
\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{{#1}}}
\newcommand{\BuiltInTok}[1]{{#1}}
\newcommand{\ExtensionTok}[1]{{#1}}
\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{{#1}}}
\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{{#1}}}
\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{{#1}}}}}
% Define a nice break command that doesn't care if a line doesn't already
% exist.
\def\br{\hspace*{\fill} \\* }
% Math Jax compatability definitions
\def\gt{>}
\def\lt{<}
% Document parameters
\title{Python Summary}
% Pygments definitions
\makeatletter
\def\PY@reset{\let\PY@it=\relax \let\PY@bf=\relax%
\let\PY@ul=\relax \let\PY@tc=\relax%
\let\PY@bc=\relax \let\PY@ff=\relax}
\def\PY@tok#1{\csname PY@tok@#1\endcsname}
\def\PY@toks#1+{\ifx\relax#1\empty\else%
\PY@tok{#1}\expandafter\PY@toks\fi}
\def\PY@do#1{\PY@bc{\PY@tc{\PY@ul{%
\PY@it{\PY@bf{\PY@ff{#1}}}}}}}
\def\PY#1#2{\PY@reset\PY@toks#1+\relax+\PY@do{#2}}
\expandafter\def\csname PY@tok@nv\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@kc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@gd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@no\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@cp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.74,0.48,0.00}{##1}}}
\expandafter\def\csname PY@tok@nd\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
\expandafter\def\csname PY@tok@il\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@sa\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@vm\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@nb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@vc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@mi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@k\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@si\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
\expandafter\def\csname PY@tok@gi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.63,0.00}{##1}}}
\expandafter\def\csname PY@tok@cs\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@kt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.69,0.00,0.25}{##1}}}
\expandafter\def\csname PY@tok@kn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@vi\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@mo\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@gr\endcsname{\def\PY@tc##1{\textcolor[rgb]{1.00,0.00,0.00}{##1}}}
\expandafter\def\csname PY@tok@sx\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@sr\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.53}{##1}}}
\expandafter\def\csname PY@tok@ow\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.67,0.13,1.00}{##1}}}
\expandafter\def\csname PY@tok@ni\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.60,0.60,0.60}{##1}}}
\expandafter\def\csname PY@tok@s1\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@c\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@ge\endcsname{\let\PY@it=\textit}
\expandafter\def\csname PY@tok@ne\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.82,0.25,0.23}{##1}}}
\expandafter\def\csname PY@tok@mb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@kd\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@gp\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@cpf\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@err\endcsname{\def\PY@bc##1{\setlength{\fboxsep}{0pt}\fcolorbox[rgb]{1.00,0.00,0.00}{1,1,1}{\strut ##1}}}
\expandafter\def\csname PY@tok@o\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@vg\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@s2\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@sh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@m\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@nn\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@ch\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@cm\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@go\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.53,0.53,0.53}{##1}}}
\expandafter\def\csname PY@tok@mf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@nl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.63,0.63,0.00}{##1}}}
\expandafter\def\csname PY@tok@nc\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@dl\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@c1\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.25,0.50,0.50}{##1}}}
\expandafter\def\csname PY@tok@s\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@nt\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@kp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@gt\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.27,0.87}{##1}}}
\expandafter\def\csname PY@tok@mh\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.40,0.40,0.40}{##1}}}
\expandafter\def\csname PY@tok@na\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.49,0.56,0.16}{##1}}}
\expandafter\def\csname PY@tok@gs\endcsname{\let\PY@bf=\textbf}
\expandafter\def\csname PY@tok@w\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.73,0.73}{##1}}}
\expandafter\def\csname PY@tok@sb\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@fm\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@gh\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,0.50}{##1}}}
\expandafter\def\csname PY@tok@bp\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@nf\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.00,0.00,1.00}{##1}}}
\expandafter\def\csname PY@tok@sc\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@se\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.73,0.40,0.13}{##1}}}
\expandafter\def\csname PY@tok@kr\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.00,0.50,0.00}{##1}}}
\expandafter\def\csname PY@tok@ss\endcsname{\def\PY@tc##1{\textcolor[rgb]{0.10,0.09,0.49}{##1}}}
\expandafter\def\csname PY@tok@sd\endcsname{\let\PY@it=\textit\def\PY@tc##1{\textcolor[rgb]{0.73,0.13,0.13}{##1}}}
\expandafter\def\csname PY@tok@gu\endcsname{\let\PY@bf=\textbf\def\PY@tc##1{\textcolor[rgb]{0.50,0.00,0.50}{##1}}}
\def\PYZbs{\char`\\}
\def\PYZus{\char`\_}
\def\PYZob{\char`\{}
\def\PYZcb{\char`\}}
\def\PYZca{\char`\^}
\def\PYZam{\char`\&}
\def\PYZlt{\char`\<}
\def\PYZgt{\char`\>}
\def\PYZsh{\char`\#}
\def\PYZpc{\char`\%}
\def\PYZdl{\char`\$}
\def\PYZhy{\char`\-}
\def\PYZsq{\char`\'}
\def\PYZdq{\char`\"}
\def\PYZti{\char`\~}
% for compatibility with earlier versions
\def\PYZat{@}
\def\PYZlb{[}
\def\PYZrb{]}
\makeatother
% Exact colors from NB
\definecolor{incolor}{rgb}{0.0, 0.0, 0.5}
\definecolor{outcolor}{rgb}{0.545, 0.0, 0.0}
% Prevent overflowing lines due to hard-to-break entities
\sloppy
% Setup hyperref package
\hypersetup{
breaklinks=true, % so long urls are correctly broken across lines
colorlinks=true,
urlcolor=urlcolor,
linkcolor=linkcolor,
citecolor=citecolor,
}
% Slightly bigger margins than the latex defaults
\geometry{verbose,tmargin=1in,bmargin=1in,lmargin=1in,rmargin=1in}
\begin{document}
\maketitle
\section{Awesome Jupyter Notebook}\label{awesome-jupyter-notebook}
\begin{quote}
Session 2
\end{quote}
\begin{quote}
Python Workshop for Benjama EEP
\end{quote}
\subsection{Objectives}\label{objectives}
\begin{enumerate}
\def\labelenumi{\arabic{enumi}.}
\tightlist
\item
bool - True, False
\item
\href{04\%20If\%20Statements.ipynb}{If-else}
\item
\href{05\%20While\%20Loops\%20and\%20User\%20Input.ipynb}{While}
\item
For
\item
\href{07\%20Introduction\%20to\%20Functions.ipynb}{Function}
\item
\href{Object\%20Oriented\%20Programming.ipynb}{Object Oriented
Programming}
\end{enumerate}
\subsection{List - ลำดับ}\label{list---uxe25uxe33uxe14uxe1a}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{speakers }\OperatorTok{=} \NormalTok{[ }\StringTok{'K'}\NormalTok{, }\StringTok{'Kai'}\NormalTok{, }\StringTok{'Or'}\NormalTok{, }\StringTok{'Paul'}\NormalTok{, }\StringTok{'Tom'}\NormalTok{, }\StringTok{'Woot'} \NormalTok{]}
\NormalTok{heights }\OperatorTok{=} \NormalTok{[ }\DecValTok{180}\NormalTok{, }\DecValTok{164}\NormalTok{, }\DecValTok{165}\NormalTok{, }\DecValTok{165}\NormalTok{, }\DecValTok{180}\NormalTok{, }\DecValTok{170} \NormalTok{]}
\NormalTok{pop }\OperatorTok{=} \NormalTok{[ }\FloatTok{3.25}\NormalTok{, }\FloatTok{3.9}\NormalTok{, }\DecValTok{4}\NormalTok{, }\DecValTok{3}\NormalTok{, }\FloatTok{3.5}\NormalTok{, }\FloatTok{3.44} \NormalTok{] }
\end{Highlighting}
\end{Shaded}
\subsubsection{เข้าถึงข้อมูลในลำดับ}\label{uxe40uxe02uxe32uxe16uxe07uxe02uxe2duxe21uxe25uxe43uxe19uxe25uxe33uxe14uxe1a}
\begin{Shaded}
\begin{Highlighting}[]
\BuiltInTok{print}\NormalTok{(speakers[}\DecValTok{0}\NormalTok{])}
\BuiltInTok{print}\NormalTok{(speakers[}\DecValTok{1}\NormalTok{])}
\BuiltInTok{print}\NormalTok{(speakers[}\DecValTok{2}\NormalTok{])}
\end{Highlighting}
\end{Shaded}
\subsubsection{การกำหนดค่าลำดับ}\label{uxe01uxe32uxe23uxe01uxe33uxe2buxe19uxe14uxe04uxe32uxe25uxe33uxe14uxe1a}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{speakers[}\DecValTok{0}\NormalTok{] }\OperatorTok{=} \StringTok{'Kriengsak'}
\BuiltInTok{print}\NormalTok{(}\BuiltInTok{str}\NormalTok{(speakers))}
\NormalTok{speakers[}\DecValTok{0}\NormalTok{] }\OperatorTok{=} \StringTok{'K'}
\BuiltInTok{print}\NormalTok{(}\BuiltInTok{str}\NormalTok{(speakers))}
\end{Highlighting}
\end{Shaded}
\subsubsection{การหาค่าต่ำสุด-สูงสุด-ผลรวม
ของลำดับ}\label{uxe01uxe32uxe23uxe2buxe32uxe04uxe32uxe15uxe33uxe2auxe14-uxe2auxe07uxe2auxe14-uxe1cuxe25uxe23uxe27uxe21-uxe02uxe2duxe07uxe25uxe33uxe14uxe1a}
\begin{Shaded}
\begin{Highlighting}[]
\BuiltInTok{print}\NormalTok{( }\BuiltInTok{max}\NormalTok{(heights) )}
\BuiltInTok{print}\NormalTok{( }\BuiltInTok{min}\NormalTok{(pop) )}
\BuiltInTok{print}\NormalTok{( }\BuiltInTok{sum}\NormalTok{(heights) )}
\end{Highlighting}
\end{Shaded}
\subsection{bool -
ค่าจริง-เท็จ}\label{bool---uxe04uxe32uxe08uxe23uxe07-uxe40uxe17uxe08}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{speakers }\OperatorTok{=} \NormalTok{[ }\StringTok{'K'}\NormalTok{, }\StringTok{'Kai'}\NormalTok{, }\StringTok{'Or'}\NormalTok{, }\StringTok{'Paul'}\NormalTok{, }\StringTok{'Tom'}\NormalTok{, }\StringTok{'Woot'} \NormalTok{]}
\NormalTok{heights }\OperatorTok{=} \NormalTok{[ }\DecValTok{180}\NormalTok{, }\DecValTok{164}\NormalTok{, }\DecValTok{165}\NormalTok{, }\DecValTok{165}\NormalTok{, }\DecValTok{180}\NormalTok{, }\DecValTok{170} \NormalTok{]}
\NormalTok{popularity }\OperatorTok{=} \NormalTok{[ }\FloatTok{3.25}\NormalTok{, }\FloatTok{3.9}\NormalTok{, }\DecValTok{4}\NormalTok{, }\DecValTok{3}\NormalTok{, }\FloatTok{3.5}\NormalTok{, }\FloatTok{3.44} \NormalTok{] }
\BuiltInTok{print}\NormalTok{( }\StringTok{'K'} \OperatorTok{in} \NormalTok{speakers )}
\BuiltInTok{print}\NormalTok{( }\StringTok{'Justin Bieber'} \OperatorTok{in} \NormalTok{speakers )}
\BuiltInTok{print}\NormalTok{( speakers[}\DecValTok{0}\NormalTok{] }\OperatorTok{==} \StringTok{'K'} \NormalTok{)}
\BuiltInTok{print}\NormalTok{( speakers[}\DecValTok{3}\NormalTok{] }\OperatorTok{==} \StringTok{'Wichit'} \NormalTok{)}
\end{Highlighting}
\end{Shaded}
\subsection{If-else}\label{if-else}
\subsubsection{เงื่อนไขเดียว}\label{uxe40uxe07uxe2duxe19uxe44uxe02uxe40uxe14uxe22uxe27}
\begin{Shaded}
\begin{Highlighting}[]
\ControlFlowTok{if} \NormalTok{ค่าจริงเท็จ: }
\NormalTok{คำสั่งที่จะทำเมื่อเป็นจริง}
\ControlFlowTok{else}\NormalTok{:}
\NormalTok{คำสั่งที่จะทำเมื่อเป็นเท็จ}
\end{Highlighting}
\end{Shaded}
\begin{quote}
ต้วอย่าง
\end{quote}
\begin{Shaded}
\begin{Highlighting}[]
\ControlFlowTok{if} \StringTok{'Justin Bieber'} \OperatorTok{in} \NormalTok{speakers:}
\BuiltInTok{print}\NormalTok{(}\StringTok{'นักร้องดังนานาชาติมา'}\NormalTok{)}
\ControlFlowTok{else}\NormalTok{:}
\BuiltInTok{print}\NormalTok{(}\StringTok{'ไม่มีนักร้องดังมางาน'}\NormalTok{)}
\end{Highlighting}
\end{Shaded}
\subsubsection{หลายเงื่อนไข}\label{uxe2buxe25uxe32uxe22uxe40uxe07uxe2duxe19uxe44uxe02}
\begin{Shaded}
\begin{Highlighting}[]
\ControlFlowTok{if} \NormalTok{เงื่อนไข}\DecValTok{1}\NormalTok{:}
\NormalTok{คำสั่งที่จะทำเมื่อเงื่อนไข}\DecValTok{1}\NormalTok{เป็นจริง}
\ControlFlowTok{elif} \NormalTok{เงื่อนไข}\DecValTok{2}\NormalTok{:}
\NormalTok{คำสั่งที่จะทำเมื่อเงื่อนไข}\DecValTok{2}\NormalTok{เป็นจริง}
\ControlFlowTok{elif} \NormalTok{เงื่อนไข}\DecValTok{3}\NormalTok{:}
\NormalTok{คำสั่งที่จะทำเมื่อเงื่อนไข}\DecValTok{3}\NormalTok{เป็นจริง}
\ControlFlowTok{else}\NormalTok{: }
\NormalTok{คำสั่งที่จะทำเมื่อเงื่อนไขทั้งหมดเป็นเท็จ}
\end{Highlighting}
\end{Shaded}
\subsection{While}\label{while}
\begin{Shaded}
\begin{Highlighting}[]
\ControlFlowTok{while} \NormalTok{เงื่อนไข:}
\NormalTok{คำสั่งที่จะทำเมื่อตรวจสอบเงื่อนไขในแต่ละรอบแล้วเป็นจริง}
\end{Highlighting}
\end{Shaded}
\begin{quote}
ตัวอย่าง
\end{quote}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{i }\OperatorTok{=} \DecValTok{0}
\ControlFlowTok{while} \NormalTok{i }\OperatorTok{<} \DecValTok{10}\NormalTok{:}
\BuiltInTok{print}\NormalTok{(}\StringTok{'i = '}\OperatorTok{+}\BuiltInTok{str}\NormalTok{(i))}
\NormalTok{i }\OperatorTok{=} \NormalTok{i}\DecValTok{+1}
\end{Highlighting}
\end{Shaded}
\subsection{For}\label{for}
\begin{Shaded}
\begin{Highlighting}[]
\ControlFlowTok{for} \NormalTok{สมาชิก }\OperatorTok{in} \NormalTok{ลำดับ:}
\NormalTok{คำสั่งที่จะทำสำหรับสมาชิกแต่ละตัว}
\end{Highlighting}
\end{Shaded}
\begin{quote}
ตัวอย่าง
\end{quote}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{speakers }\OperatorTok{=} \NormalTok{[ }\StringTok{'K'}\NormalTok{, }\StringTok{'Kai'}\NormalTok{, }\StringTok{'Or'}\NormalTok{, }\StringTok{'Paul'}\NormalTok{, }\StringTok{'Tom'}\NormalTok{, }\StringTok{'Woot'} \NormalTok{]}
\ControlFlowTok{for} \NormalTok{speaker }\OperatorTok{in} \NormalTok{speakers:}
\BuiltInTok{print}\NormalTok{(speaker)}
\end{Highlighting}
\end{Shaded}
\subsection{Function -
การเขียนฟังก์ชัน}\label{function---uxe01uxe32uxe23uxe40uxe02uxe22uxe19uxe1fuxe07uxe01uxe0auxe19}
\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{def} \NormalTok{ชื่อฟังก์ชัน(รายการข้อมูลที่รับมา):}
\NormalTok{คำสั่งภายในฟังก์ชัน}
\end{Highlighting}
\end{Shaded}
\begin{quote}
ตัวอย่าง
\end{quote}
\begin{Shaded}
\begin{Highlighting}[]
\KeywordTok{def} \NormalTok{statsummary(a):}
\ImportTok{import} \NormalTok{statistics}
\BuiltInTok{print}\NormalTok{(}\StringTok{'ลำดับ: '}\OperatorTok{+}\BuiltInTok{str}\NormalTok{(a))}
\BuiltInTok{print}\NormalTok{(}\StringTok{'ค่าเฉลี่ยของลำดับ: '}\OperatorTok{+}\BuiltInTok{str}\NormalTok{(statistics.mean(a)))}
\BuiltInTok{print}\NormalTok{(}\StringTok{'ค่าเบี่ยงเบนมาตรฐานของลำดับ: '}\OperatorTok{+}\BuiltInTok{str}\NormalTok{(statistics.stdev(a)))}
\NormalTok{heights }\OperatorTok{=} \NormalTok{[ }\DecValTok{180}\NormalTok{, }\DecValTok{164}\NormalTok{, }\DecValTok{165}\NormalTok{, }\DecValTok{165}\NormalTok{, }\DecValTok{180}\NormalTok{, }\DecValTok{170} \NormalTok{]}
\NormalTok{statssummary(heights)}
\end{Highlighting}
\end{Shaded}
\subsection{Dictionary/json -
ชนิดข้อมูลที่นิยมใช้แลกเปลี่ยนข้อมูล}\label{dictionaryjson---uxe0auxe19uxe14uxe02uxe2duxe21uxe25uxe17uxe19uxe22uxe21uxe43uxe0auxe41uxe25uxe01uxe40uxe1buxe25uxe22uxe19uxe02uxe2duxe21uxe25}
\begin{itemize}
\tightlist
\item
อัตราแลกเปลี่ยน https://api.fixer.io/lastest
\item
ข้อมูลผู้ใช้บน github https://api.github.com/users
\item
Google: YouTube Data API, Live Stream, Analytics
https://developers.google.com/youtube/v3/
\item
Facebook: \href{https://developers.facebook.com/docs/graph-api/}{Graph
API}
\item
\href{https://www.themoviedb.org/}{The Movie Database}
\end{itemize}
\subsubsection{ข้อมูลจากเครื่องวิทยากร}\label{uxe02uxe2duxe21uxe25uxe08uxe32uxe01uxe40uxe04uxe23uxe2duxe07uxe27uxe17uxe22uxe32uxe01uxe23}
\paragraph{แบบ json}\label{uxe41uxe1auxe1a-json}
\begin{itemize}
\tightlist
\item
http://หมายเลขไอพีเครื่องวิทยากร/api/info
\item
http://หมายเลขไอพีเครื่องวิทยากร/api/exchange
\end{itemize}
\paragraph{แบบข้อความธรรมดา}\label{uxe41uxe1auxe1auxe02uxe2duxe04uxe27uxe32uxe21uxe18uxe23uxe23uxe21uxe14uxe32}
\begin{itemize}
\tightlist
\item
http://หมายเลขไอพีเครื่องวิทยากร/speakers/txt
\item
http://หมายเลขไอพีเครื่องวิทยากร/height/txt
\item
http://หมายเลขไอพีเครื่องวิทยากร/pop/txt
\end{itemize}
\subsubsection{รูปแบบข้อมูล
dictionary}\label{uxe23uxe1buxe41uxe1auxe1auxe02uxe2duxe21uxe25-dictionary}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{speakers }\OperatorTok{=} \NormalTok{\{}
\StringTok{'K'}\NormalTok{: }\StringTok{'เกรียงศักดิ์'}\NormalTok{,}
\CommentTok{'Woot'}\NormalTok{: }\StringTok{'วราวุฒิ'}\NormalTok{,}
\CommentTok{'Tom'}\NormalTok{: }\StringTok{'ไพชยนต์'}
\NormalTok{\}}
\end{Highlighting}
\end{Shaded}
เนื่องจาก str ใน python ใช้ได้ทั้ง '' และ ""
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{speakers }\OperatorTok{=} \NormalTok{\{}
\StringTok{"K"}\NormalTok{: }\StringTok{"เกรียงศักดิ์"}\NormalTok{,}
\CommentTok{"Woot"}\NormalTok{: }\StringTok{"วราวุฒิ"}\NormalTok{,}
\CommentTok{"Tom"}\NormalTok{: }\StringTok{"ไพชยนต์"}
\NormalTok{\}}
\end{Highlighting}
\end{Shaded}
\begin{quote}
ตัวอย่าง info
\end{quote}
\begin{Shaded}
\begin{Highlighting}[]
\NormalTok{\{}
\StringTok{"K"}\NormalTok{: \{}
\StringTok{"ชื่อ-สกุล"}\NormalTok{: }\StringTok{"เกรียงศักดิ์ ตรีประพิณ"}\NormalTok{,}
\CommentTok{"e-mail"}\NormalTok{: }\StringTok{"kriengsak.t@ubu.ac.th"}\NormalTok{,}
\CommentTok{"picture"}\NormalTok{: }\StringTok{"image/K.jpg"}
\NormalTok{\},}
\CommentTok{"Kai"}\NormalTok{: \{}
\StringTok{"ชื่อ-สกุล"}\NormalTok{: }\StringTok{"ปิยนันท์ พนากานต์"}\NormalTok{, }
\CommentTok{"e-mail"}\NormalTok{: }\StringTok{"piyanan.p@ubu.ac.th"}\NormalTok{,}
\CommentTok{"picture"}\NormalTok{: }\StringTok{"image/Kai.jpg"}
\NormalTok{\},}
\CommentTok{"Or"}\NormalTok{: \{}
\StringTok{"ชื่อ-สกุล"}\NormalTok{: }\StringTok{"วาสนา เหง้าเกษ"}\NormalTok{,}
\CommentTok{"e-mail"}\NormalTok{: }\StringTok{"wasana.n@ubu.ac.th"}\NormalTok{,}
\CommentTok{"picture"}\NormalTok{: }\StringTok{"image/Or.jpg"}
\NormalTok{\},}
\CommentTok{"Paul"}\NormalTok{: \{}
\StringTok{"ชื่อ-สกุล"}\NormalTok{: }\StringTok{"วิชิต สมบัติ"}\NormalTok{,}
\CommentTok{"e-mail"}\NormalTok{: }\StringTok{"wichit.s@ubu.ac.th"}\NormalTok{,}
\CommentTok{"picture"}\NormalTok{: }\StringTok{"image/Paul.jpg"}
\NormalTok{\},}
\CommentTok{"Tom"}\NormalTok{: \{}
\StringTok{"ชื่อ-สกุล"}\NormalTok{: }\StringTok{"ไพชยนต์ คงไชย"}\NormalTok{,}
\CommentTok{"e-mail"}\NormalTok{: }\StringTok{"phaichayon.k@ubu.ac.th"}\NormalTok{,}
\CommentTok{"picture"}\NormalTok{: }\StringTok{"image/Tom.jpg"}
\NormalTok{\},}
\CommentTok{"Woot"}\NormalTok{: \{}
\StringTok{"ชื่อ-สกุล"}\NormalTok{: }\StringTok{"วราวุฒิ ผ้าเจริญ"}\NormalTok{,}
\CommentTok{"e-mail"}\NormalTok{: }\StringTok{"warawoot.p@ubu.ac.th"}\NormalTok{,}
\CommentTok{"picture"}\NormalTok{: }\StringTok{"image/Woot.jpg"}
\NormalTok{\}}
\NormalTok{\}}
\end{Highlighting}
\end{Shaded}
\subsection{การรับส่งข้อมูล
json}\label{uxe01uxe32uxe23uxe23uxe1auxe2auxe07uxe02uxe2duxe21uxe25-json}
\begin{Shaded}
\begin{Highlighting}[]
\ImportTok{import} \NormalTok{requests}
\NormalTok{r }\OperatorTok{=} \NormalTok{requests.get(}\StringTok{'http://api.fixer.io/latest'}\NormalTok{)}
\NormalTok{x }\OperatorTok{=} \NormalTok{r.json()}
\BuiltInTok{print}\NormalTok{( }\BuiltInTok{type}\NormalTok{(x) )}
\BuiltInTok{print}\NormalTok{(x)}
\end{Highlighting}
\end{Shaded}
\subsection{More on import}\label{more-on-import}
คำสั่งเพื่อสร้างหน้าต่างขึ้นมา
\begin{Shaded}
\begin{Highlighting}[]
\ImportTok{import} \NormalTok{sys}
\ImportTok{import} \NormalTok{PyQt5.QtWidgets }
\NormalTok{app }\OperatorTok{=} \NormalTok{PyQt5.QtWidgets.QApplication(sys.argv)}
\NormalTok{w }\OperatorTok{=} \NormalTok{PyQt5.QtWidgets.QWidget()}
\NormalTok{w.resize(}\DecValTok{250}\NormalTok{, }\DecValTok{150}\NormalTok{)}
\NormalTok{w.move(}\DecValTok{300}\NormalTok{, }\DecValTok{300}\NormalTok{)}
\NormalTok{w.show()}
\NormalTok{sys.exit(app.exec_())}
\end{Highlighting}
\end{Shaded}
เราสามารถทำการย่อชื่อโดยใช้คำสั่ง import ช่วยให้สั้นลงได้ดังนี้
\begin{Shaded}
\begin{Highlighting}[]
\ImportTok{import} \NormalTok{sys}
\ImportTok{from} \NormalTok{PyQt5.QtWidgets }\ImportTok{import} \NormalTok{QApplication, QWidget}
\NormalTok{app }\OperatorTok{=} \NormalTok{QApplication(sys.argv)}
\NormalTok{w }\OperatorTok{=} \NormalTok{QWidget()}
\NormalTok{w.resize(}\DecValTok{250}\NormalTok{, }\DecValTok{150}\NormalTok{)}
\NormalTok{w.move(}\DecValTok{300}\NormalTok{, }\DecValTok{300}\NormalTok{)}
\NormalTok{w.show()}
\NormalTok{sys.exit(app.exec_())}
\end{Highlighting}
\end{Shaded}
\section{แนวคิดเชิงวัตถุ
และการสืบทอดคุณสมบัติ}\label{uxe41uxe19uxe27uxe04uxe14uxe40uxe0auxe07uxe27uxe15uxe16-uxe41uxe25uxe30uxe01uxe32uxe23uxe2auxe1auxe17uxe2duxe14uxe04uxe13uxe2auxe21uxe1auxe15}
เราสามารถเขียนนิยามหน้าต่างของเราเองได้ดังนี้
\begin{Shaded}
\begin{Highlighting}[]
\ImportTok{import} \NormalTok{sys}
\ImportTok{from} \NormalTok{PyQt5.QtWidgets }\ImportTok{import} \NormalTok{QApplication, QWidget}
\ImportTok{from} \NormalTok{PyQt5.QtGui }\ImportTok{import} \NormalTok{QIcon}
\KeywordTok{class} \NormalTok{MyWindow(QWidget):}
\KeywordTok{def} \FunctionTok{__init__}\NormalTok{(}\VariableTok{self}\NormalTok{):}
\BuiltInTok{super}\NormalTok{().}\FunctionTok{__init__}\NormalTok{()}
\VariableTok{self}\NormalTok{.setGeometry(}\DecValTok{300}\NormalTok{, }\DecValTok{300}\NormalTok{, }\DecValTok{250}\NormalTok{, }\DecValTok{150}\NormalTok{)}
\VariableTok{self}\NormalTok{.setWindowTitle(}\StringTok{'Icon'}\NormalTok{)}
\VariableTok{self}\NormalTok{.setWindowIcon(QIcon(}\StringTok{'icon.png'}\NormalTok{))}
\VariableTok{self}\NormalTok{.show()}
\ControlFlowTok{if} \VariableTok{__name__} \OperatorTok{==} \StringTok{'__main__'}\NormalTok{:}
\NormalTok{app }\OperatorTok{=} \NormalTok{QApplication(sys.argv)}
\NormalTok{ex }\OperatorTok{=} \NormalTok{Example()}
\NormalTok{sys.exit(app.exec_())}
\end{Highlighting}
\end{Shaded}
% Add a bibliography block to the postdoc
\end{document}
{
"K": {
"ชื่อ-สกุล": "เกรียงศักดิ์ ตรีประพิณ",
"e-mail": "kriengsak.t@ubu.ac.th",
"picture": "image/K.jpg"
},
"Kai": {
"ชื่อ-สกุล": "ปิยนันท์ พนากานต์",
"e-mail": "piyanan.p@ubu.ac.th",
"picture": "image/Kai.jpg"
},
"Or": {
"ชื่อ-สกุล": "วาสนา เหง้าเกษ",
"e-mail": "wasana.n@ubu.ac.th",
"picture": "image/Or.jpg"
},
"Paul": {
"ชื่อ-สกุล": "วิชิต สมบัติ",
"e-mail": "wichit.s@ubu.ac.th",
"picture": "image/Paul.jpg"
},
"Tom": {
"ชื่อ-สกุล": "ไพชยนต์ คงไชย",
"e-mail": "phaichayon.k@ubu.ac.th",
"picture": "image/Tom.jpg"
},
"Woot": {
"ชื่อ-สกุล": "วราวุฒิ ผ้าเจริญ",
"e-mail": "warawoot.p@ubu.ac.th",
"picture": "image/Woot.jpg"
}
}
{
"base": "EUR",
"date": "2018-01-19",
"source": "https://api.fixer.io/latest",
"rates": {
"AUD": 1.5302,
"BGN": 1.9558,
"BRL": 3.9312,
"CAD": 1.5246,
"CHF": 1.1758,
"CNY": 7.8481,
"CZK": 25.433,
"DKK": 7.4454,
"GBP": 0.88365,
"HKD": 9.5814,
"HRK": 7.4352,
"HUF": 309.2,
"IDR": 16316,
"ILS": 4.1837,
"INR": 78.239,
"JPY": 135.54,
"KRW": 1306.9,
"MXN": 22.816,
"MYR": 4.826,
"NOK": 9.6243,
"NZD": 1.6831,
"PHP": 62.138,
"PLN": 4.1716,
"RON": 4.6594,
"RUB": 69.332,
"SEK": 9.8333,
"SGD": 1.6178,
"THB": 39.069,
"TRY": 4.6557,
"USD": 1.2255,
"ZAR": 14.955
}
}
# Micro-Service Web
## สิ่งที่ต้องติดตั้งก่อน
```sh
pip install -r requirements.txt
```
## วิธี run
```sh
python3 server.py
```
## วิธีเรียกใช้
```sh
http://localhost:5000/info
http://localhost:5000/speakers/txt
http://localhost:5000/speakers/json
http://localhost:5000/height/txt
http://localhost:5000/height/json
http://localhost:5000/pop/txt
http://localhost:5000/pop/json
http://localhost:5000/picture/K
http://localhost:5000/picture/Tom
http://localhost:5000/picture/Woot
```
from flask import Flask, jsonify, send_file #, url_for
import os, json
app = Flask(__name__)
def read(fname):
with open(fname, 'r') as f:
data = f.read()
f.close()
return json.loads(data)
@app.route('/')
def api_root():
return """Welcome I'm a <a href="http://www.python.org">python</a> server that give you data."""
@app.errorhandler(404)
def not_found(a):
return """Error! Ask the right question. <br/> ระบุข้อมูลและรูปแบบให้ถูกต้องด้วย """
@app.route('/<data>/<dataformat>')
def app_data(data, dataformat):
DATA = {
'speakers': ["K","Kai","Or","Paul","Tom","Woot"],
'height': [180,164,165,165,180,170],
'pop': [3.25,3.9,4,3,3.5,3.44],
'popularity': [3.25,3.9,4,3,3.5,3.44]
}
try:
if dataformat in ['txt', 'text', 'TXT']:
return " ".join(DATA[data])
if dataformat in ['json', 'JSON', 'jsn']:
return jsonify(DATA[data])
except: pass
return """Error! Ask the right question. <br/> ระบุข้อมูลและรูปแบบให้ถูกต้องด้วย """
@app.route('/api/<name>')
def api_name(name):
return jsonify(read('api/{}.json'.format(name)))
@app.route('/picture/<speaker>')
def api_image(speaker):
fname = 'image/{}.jpg'.format(speaker)
if os.path.exists(fname):
return send_file(fname, mimetype="image/jpeg")
return """Error! no picture for {}.""".format(speaker)
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
import statistics
line = input('speakers ')
speakers = map(str, line.split(' '))
print(speakers)
line = input('height ')
height = map(int, line.split(' '))
print(statistics.mode(height))
line = input('pop ')
pop = map(float, line.split(' '))
print(statistics.mean(pop))
......@@ -3,7 +3,7 @@ from PyQt5.QtWidgets import QWidget, QPushButton, QLineEdit, QLabel, QGridLayout
from PyQt5.QtGui import QImage, QImageWriter, QPainter, QPen, qRgb, QPixmap
import os
import matplotlib.pyplot as plt
#import matplotlib.pyplot as plt
# Import datasets, classifiers and performance metrics
from sklearn import datasets, svm, metrics
......@@ -191,4 +191,4 @@ class Board(QWidget):
print("Classification report for classifier %s:\n%s\n"
% (classifier, metrics.classification_report(digit_label, predicted)))
print("Confusion matrix:\n%s" % metrics.confusion_matrix(digit_label, predicted))
print("\naccuracy = ",accuracy_score(digit_label, predicted))
\ No newline at end of file
print("\naccuracy = ",accuracy_score(digit_label, predicted))
......@@ -3,7 +3,7 @@ from PyQt5.QtWidgets import QWidget, QPushButton, QLineEdit, QLabel, QGridLayout
from PyQt5.QtGui import QImage, QImageWriter, QPainter, QPen, qRgb, QPixmap
import os
import matplotlib.pyplot as plt
#import matplotlib.pyplot as plt
# Import datasets, classifiers and performance metrics
from sklearn import datasets, svm, metrics
......@@ -191,4 +191,4 @@ class Board(QWidget):
print("Classification report for classifier %s:\n%s\n"
% (classifier, metrics.classification_report(digit_label, predicted)))
print("Confusion matrix:\n%s" % metrics.confusion_matrix(digit_label, predicted))
print("\naccuracy = ",accuracy_score(digit_label, predicted))
\ No newline at end of file
print("\naccuracy = ",accuracy_score(digit_label, predicted))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment