├── .gitignore ├── 01- Buckets and Variables.ipynb ├── 02- Operators.ipynb ├── 03- Calling Functions.ipynb ├── 04- Simple Lists.ipynb ├── 05- For and If.ipynb ├── 06- If and Else.ipynb ├── 07- Making Functions.ipynb ├── 08- Finding Primes.ipynb ├── 09- More Functions.ipynb ├── 10- Dictionaries.ipynb ├── Animal Guessing Game.ipynb ├── README.md ├── animal-guesser-tree-1.png ├── animal-guesser-tree-2.png ├── animal-guesser-tree-3.png ├── animal-guesser.py ├── cookie-python └── Check │ ├── __init__.py │ └── check.py ├── misc ├── 01-output.pdf └── screenshot.png └── start-me-up /.gitignore: -------------------------------------------------------------------------------- 1 | .ipynb.output 2 | *.pyc 3 | .ipynb.output 4 | -------------------------------------------------------------------------------- /01- Buckets and Variables.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "1- Buckets and Variables" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Hi there! Welcome to the first Python exercises! Before we get started, I need to explain some things. First, every time you see a gray box with the words **In [ ]**, like this:" 15 | ] 16 | }, 17 | { 18 | "cell_type": "code", 19 | "collapsed": false, 20 | "input": [], 21 | "language": "python", 22 | "metadata": {}, 23 | "outputs": [] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "It means that you can type things in it. Usually, there is a part for you to change shown with an *underbar* symbol: `_`\n", 30 | "\n", 31 | "Each of the gray boxes end with a line that says: `check()`\n", 32 | "\n", 33 | "That line tells me to correct your work and tell you if you did the assignment correctly. So you can just ignore it (but don't change it).\n", 34 | "\n", 35 | "Finally, after you have made your changes press the button at the top that looks like triangle. That will *run* what you've typed.\n", 36 | "\n", 37 | "Shall we begin?" 38 | ] 39 | }, 40 | { 41 | "cell_type": "heading", 42 | "level": 2, 43 | "metadata": {}, 44 | "source": [ 45 | "Welcome" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "When we *program* a project, we often have to store things. These *things* are pieces of information we call \"data\", and today's assignment is all about making data and holding it in *variables*. Variables are like little boxes that can hold some data. Each variable has a name. This lets us get or change the data in a variable by using its name.\n", 53 | "\n", 54 | "Of course this will make sense as we play with it. Let's begin.\n", 55 | "\n", 56 | "Your first assignment is to put the number 42 into a variable box named \"pizza\". I told you that a variable could be named just about anything." 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "collapsed": false, 62 | "input": [ 63 | "pizza = _\n", 64 | "\n", 65 | "check(1, 1, pizza) ## This is one of those lines to ignore right now." 66 | ], 67 | "language": "python", 68 | "metadata": {}, 69 | "outputs": [ 70 | { 71 | "output_type": "stream", 72 | "stream": "stdout", 73 | "text": [ 74 | "You need to change the _ symbol to the number 42.\n" 75 | ] 76 | } 77 | ], 78 | "prompt_number": 1 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "Python has two types of numbers:\n", 85 | "\n", 86 | " * A regular, whole number like 1, 8, -142 or 275382876634695077374\n", 87 | " * A fraction/decimal number like 5.5 (for $5 \\frac{1}{2}$)\n", 88 | "\n", 89 | "In this assignment, you need to put $2\\frac{1}{2}$ into the `apple` variable. In Python, we first right all fractions as decimals, so first convert $2\\frac{1}{2}$ to a decimal, and the assignment will be almost done:" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "collapsed": true, 95 | "input": [ 96 | "apple = _\n", 97 | "\n", 98 | "check(1, 2, apple)" 99 | ], 100 | "language": "python", 101 | "metadata": {}, 102 | "outputs": [ 103 | { 104 | "output_type": "stream", 105 | "stream": "stdout", 106 | "text": [ 107 | "You need to change the _ symbol to the number 2.5\n" 108 | ] 109 | } 110 | ], 111 | "prompt_number": 2 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "Python can also store words. If Python sees words like `orange`, it will think that is a variable, so if we want to use the words \"coconut shells\", you have to put them in quotes, like this:\n", 118 | "\n", 119 | " carrying = \"coconut shells\"\n", 120 | "\n", 121 | "The same words can be placed in more than one variable box. For instance, this is fine:\n", 122 | "\n", 123 | " carrying = \"coconut shells\"\n", 124 | " banging = \"coconut shells\"\n", 125 | "\n", 126 | "In this assignment, I want you to introduce yourself by putting your name in the `name` variable. Remember the quotes!" 127 | ] 128 | }, 129 | { 130 | "cell_type": "code", 131 | "collapsed": false, 132 | "input": [ 133 | "name = _\n", 134 | "\n", 135 | "check(1, 3, name)" 136 | ], 137 | "language": "python", 138 | "metadata": {}, 139 | "outputs": [ 140 | { 141 | "output_type": "stream", 142 | "stream": "stdout", 143 | "text": [ 144 | "You need to change the _ symbol to the number you name inside quotes, like \"David\"\n" 145 | ] 146 | } 147 | ], 148 | "prompt_number": 3 149 | }, 150 | { 151 | "cell_type": "markdown", 152 | "metadata": {}, 153 | "source": [ 154 | "Words in quotes are called *strings* ... think of it like *stringing words and letters together*. You can use either the double quotes (\") or the single quotes ('). We usually choose double quotes if the string or words we are writing uses an apostrophe, like:\n", 155 | "\n", 156 | " weapon = \"King Arthur's sword is Excalibur\"\n", 157 | "\n", 158 | "If we want our string of words to be quoted, then we wrap up the string in single quotes, like this:\n", 159 | "\n", 160 | " reading = 'I am reading, \"The Holy Grail\".'\n", 161 | "\n", 162 | "**Warning:** The start and end of your string must use the same type of quote. You can mis-match them. For instance, the following is wrong:\n", 163 | "\n", 164 | " bird = \"Unladen swallow' <-- Error!\n", 165 | "\n", 166 | "Now it is time to practice. I want you to write a sentence about *Pat's ball* and assign it to the variable `sentence`:\n" 167 | ] 168 | }, 169 | { 170 | "cell_type": "code", 171 | "collapsed": false, 172 | "input": [ 173 | "sentence = _\n", 174 | "\n", 175 | "check(1, 4, sentence)" 176 | ], 177 | "language": "python", 178 | "metadata": {}, 179 | "outputs": [ 180 | { 181 | "output_type": "stream", 182 | "stream": "stdout", 183 | "text": [ 184 | "The sentence should say something about Pat's ball.\n" 185 | ] 186 | } 187 | ], 188 | "prompt_number": 4 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": {}, 193 | "source": [ 194 | "What if you wanted to write a *paragraph* that needed more than one line? To do this, you use *three quotes*, like this:\n", 195 | "\n", 196 | " paragraph = \"\"\"Flora and Charlie are nice kids who like to play ball with the kids across the street.\n", 197 | " One day, Flora and Charlie went across the street, but...\"\"\"\n", 198 | "\n", 199 | "For this next assignment, write a paragraph of words that has at least two lines in it:" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "collapsed": false, 205 | "input": [ 206 | "paragraph = _\n", 207 | "\n", 208 | "check(1, 5, paragraph)" 209 | ], 210 | "language": "python", 211 | "metadata": {}, 212 | "outputs": [ 213 | { 214 | "output_type": "stream", 215 | "stream": "stdout", 216 | "text": [ 217 | "You need to change the _ symbol to a string with more than one line.\n" 218 | ] 219 | } 220 | ], 221 | "prompt_number": 5 222 | }, 223 | { 224 | "cell_type": "markdown", 225 | "metadata": {}, 226 | "source": [ 227 | "A variable can't be named anything. For instance, you can not use a space inside a variable name. You can guess why, right? Look at this example:\n", 228 | "\n", 229 | " i like = \"spam\"\n", 230 | "\n", 231 | "That's right, Python will think that \"i\" and \"like\" are two different variables. If you want a variable to look like two words, use an *underbar* (we sometimes call that symbol an *underscore*), like this:\n", 232 | "\n", 233 | " i_like = \"spam\"\n", 234 | "\n", 235 | "Also, each variable must start with a letter. After that, it can be letters or numbers or the underbar.\n", 236 | "\n", 237 | "What about the spaces around the equals sign? Python doesn't care about those spaces. The following three lines are the same to Python:\n", 238 | "\n", 239 | " breakfast=\"spam and eggs\"\n", 240 | " breakfast = \"spam and eggs\"\n", 241 | " breakfast = \"spam and eggs\"\n", 242 | "\n", 243 | "Why do we use spaces? I think Python code with spaces is more readable. But that is up to you." 244 | ] 245 | } 246 | ], 247 | "metadata": {} 248 | } 249 | ] 250 | } -------------------------------------------------------------------------------- /02- Operators.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "02- Operators" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Our second assignment is about *operators*. An operator is something that works on some data ... often numbers. Yes, this is where we get into the math, but you should be happy about that, since getting Python to do your math homework is better than using a calculator." 15 | ] 16 | }, 17 | { 18 | "cell_type": "heading", 19 | "level": 3, 20 | "metadata": {}, 21 | "source": [ 22 | "Addition" 23 | ] 24 | }, 25 | { 26 | "cell_type": "markdown", 27 | "metadata": {}, 28 | "source": [ 29 | "Let's suppose we have a math problem like this one:\n", 30 | "\n", 31 | " $35 + 7$\n", 32 | "\n", 33 | "How would you solve that in Python? Pretty much the same way:" 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "collapsed": false, 39 | "input": [ 40 | "35 + 7" 41 | ], 42 | "language": "python", 43 | "metadata": {}, 44 | "outputs": [ 45 | { 46 | "output_type": "pyout", 47 | "prompt_number": 1, 48 | "text": [ 49 | "42" 50 | ] 51 | } 52 | ], 53 | "prompt_number": 1 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "The `+` symbol is an *operator*. Some of them will be obvious to you, but others may be strange:" 60 | ] 61 | }, 62 | { 63 | "cell_type": "heading", 64 | "level": 3, 65 | "metadata": {}, 66 | "source": [ 67 | "Subtraction" 68 | ] 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "metadata": {}, 73 | "source": [ 74 | "As you can guess, subtraction is just that minus-looking symbol we sometimes call a hyphen. So far, so good." 75 | ] 76 | }, 77 | { 78 | "cell_type": "code", 79 | "collapsed": false, 80 | "input": [ 81 | "131 - 89" 82 | ], 83 | "language": "python", 84 | "metadata": {}, 85 | "outputs": [ 86 | { 87 | "output_type": "pyout", 88 | "prompt_number": 2, 89 | "text": [ 90 | "42" 91 | ] 92 | } 93 | ], 94 | "prompt_number": 2 95 | }, 96 | { 97 | "cell_type": "heading", 98 | "level": 3, 99 | "metadata": {}, 100 | "source": [ 101 | "Multiplication" 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": {}, 107 | "source": [ 108 | "How do we do multiplication, like:\n", 109 | "\n", 110 | "$6 \\times 7$\n", 111 | "\n", 112 | "If we used the \"x\" letter, Python would think it was a variable named `x`, so we use the asterisk (hold down the Shift and type `8` on most keyboards)." 113 | ] 114 | }, 115 | { 116 | "cell_type": "code", 117 | "collapsed": false, 118 | "input": [ 119 | "6 * 7" 120 | ], 121 | "language": "python", 122 | "metadata": {}, 123 | "outputs": [ 124 | { 125 | "output_type": "pyout", 126 | "prompt_number": 3, 127 | "text": [ 128 | "42" 129 | ] 130 | } 131 | ], 132 | "prompt_number": 3 133 | }, 134 | { 135 | "cell_type": "heading", 136 | "level": 3, 137 | "metadata": {}, 138 | "source": [ 139 | "Division" 140 | ] 141 | }, 142 | { 143 | "cell_type": "markdown", 144 | "metadata": {}, 145 | "source": [ 146 | "You realize that division is really just a fraction, right? $\\frac{3}{4}$ is really just 3 divided by 4. Since we don't have a $\\div$ key on our computer, we use the *slash* key: `/`" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "collapsed": false, 152 | "input": [ 153 | "126 / 3" 154 | ], 155 | "language": "python", 156 | "metadata": {}, 157 | "outputs": [ 158 | { 159 | "output_type": "pyout", 160 | "prompt_number": 4, 161 | "text": [ 162 | "42" 163 | ] 164 | } 165 | ], 166 | "prompt_number": 4 167 | }, 168 | { 169 | "cell_type": "heading", 170 | "level": 3, 171 | "metadata": {}, 172 | "source": [ 173 | "Remainder" 174 | ] 175 | }, 176 | { 177 | "cell_type": "markdown", 178 | "metadata": {}, 179 | "source": [ 180 | "If you divide 8 by 3, you get 2 with a *remainder*. If you want the remainder, you use the `%` operator, which we call by a few different names: *modulo* or *modulus*" 181 | ] 182 | }, 183 | { 184 | "cell_type": "code", 185 | "collapsed": false, 186 | "input": [ 187 | "8 % 3" 188 | ], 189 | "language": "python", 190 | "metadata": {}, 191 | "outputs": [ 192 | { 193 | "output_type": "pyout", 194 | "prompt_number": 5, 195 | "text": [ 196 | "2" 197 | ] 198 | } 199 | ], 200 | "prompt_number": 5 201 | }, 202 | { 203 | "cell_type": "heading", 204 | "level": 3, 205 | "metadata": {}, 206 | "source": [ 207 | "Powers" 208 | ] 209 | }, 210 | { 211 | "cell_type": "markdown", 212 | "metadata": {}, 213 | "source": [ 214 | "In math, we sometimes use *powers*, like $4^2$, which means \"four times itself 2 times\": $4 \\times 4$. We use this so much we call it *4 squared*.\n", 215 | "\n", 216 | "The general way, like $4^5$ (which is $4 \\times 4 \\times 4 \\times 4 \\times 4$) is written using *two asterisks*:" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "collapsed": false, 222 | "input": [ 223 | "4**5" 224 | ], 225 | "language": "python", 226 | "metadata": {}, 227 | "outputs": [ 228 | { 229 | "output_type": "pyout", 230 | "prompt_number": 6, 231 | "text": [ 232 | "1024" 233 | ] 234 | } 235 | ], 236 | "prompt_number": 6 237 | }, 238 | { 239 | "cell_type": "heading", 240 | "level": 3, 241 | "metadata": {}, 242 | "source": [ 243 | "Python Better than a Calculator?" 244 | ] 245 | }, 246 | { 247 | "cell_type": "markdown", 248 | "metadata": {}, 249 | "source": [ 250 | "So far, everything I've showed you is just what you could do with a calculator. But Python may impress you. Grab a calculator that has a power function key (it will look like $x^y$), and press: $2 ... x^y ... 1024$\n", 251 | "\n", 252 | "What did you get? You'll end up either getting an error, or the calculator starts to *round* using *Exponential Notation* (that's what the `E` sign means). While I won't explain Exponential Notation, let me just say that you can't see all the digits that are part of the answer.\n", 253 | "\n", 254 | "Now, in the cell below, type: `2 ** 1024` and what the Python Magic:" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "collapsed": false, 260 | "input": [], 261 | "language": "python", 262 | "metadata": {}, 263 | "outputs": [], 264 | "prompt_number": 6 265 | }, 266 | { 267 | "cell_type": "markdown", 268 | "metadata": {}, 269 | "source": [ 270 | "Yeah, you should be impressed." 271 | ] 272 | }, 273 | { 274 | "cell_type": "heading", 275 | "level": 3, 276 | "metadata": {}, 277 | "source": [ 278 | "How About Pi?" 279 | ] 280 | }, 281 | { 282 | "cell_type": "markdown", 283 | "metadata": {}, 284 | "source": [ 285 | "Well, if Python can show me all the digits to an operation like that, then what about $\\pi$ ? First of all, you already know that $\\pi$ is an *irrational* number, meaning that it is a non-repeating, *never-ending* number. So we can't render it, even in Python.\n", 286 | "\n", 287 | "However, you can make a variable called `pi` that holds as many digits that you have memorized. Let's do that:" 288 | ] 289 | }, 290 | { 291 | "cell_type": "code", 292 | "collapsed": true, 293 | "input": [ 294 | "pi = _\n", 295 | "\n", 296 | "check(2, 1, pi)" 297 | ], 298 | "language": "python", 299 | "metadata": {}, 300 | "outputs": [ 301 | { 302 | "output_type": "stream", 303 | "stream": "stdout", 304 | "text": [ 305 | "Just like our previous assignments, you need to replace the _ symbol above with the answer. In this case, the answer begins with 3. something something.\n" 306 | ] 307 | } 308 | ], 309 | "prompt_number": 7 310 | }, 311 | { 312 | "cell_type": "markdown", 313 | "metadata": {}, 314 | "source": [ 315 | "Python already comes with a variable holding a few digits of pi, but you get to it with `math.pi`. Type this variable in the new box, and let's see the difference between your version of pi and Python's." 316 | ] 317 | }, 318 | { 319 | "cell_type": "code", 320 | "collapsed": false, 321 | "input": [ 322 | "_\n", 323 | "\n", 324 | "check(2, 2, pi)" 325 | ], 326 | "language": "python", 327 | "metadata": {}, 328 | "outputs": [ 329 | { 330 | "output_type": "stream", 331 | "stream": "stdout", 332 | "text": [ 333 | "3.14159265359\n", 334 | "\n" 335 | ] 336 | } 337 | ], 338 | "prompt_number": 10 339 | }, 340 | { 341 | "cell_type": "heading", 342 | "level": 3, 343 | "metadata": {}, 344 | "source": [ 345 | "Storing our Answers in Variable Boxes" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "As you can guess, we can store our answers from operators in variables. Let's use `math.pi` to find the area of a circle that is 6 inches across. You remember the formula, right? $A = \\pi r^2$" 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "collapsed": false, 358 | "input": [ 359 | "r = _\n", 360 | "area = _\n", 361 | "\n", 362 | "check(2, 3, area)" 363 | ], 364 | "language": "python", 365 | "metadata": {}, 366 | "outputs": [ 367 | { 368 | "output_type": "stream", 369 | "stream": "stdout", 370 | "text": [ 371 | "Hint: The diameter is 6, but the formula uses `r` which is the radius.\n" 372 | ] 373 | } 374 | ], 375 | "prompt_number": 9 376 | }, 377 | { 378 | "cell_type": "markdown", 379 | "metadata": {}, 380 | "source": [ 381 | "So I've shown you that Python is better than a calculator, but you haven't seen anything yet. In the next episode, I'll show you more." 382 | ] 383 | } 384 | ], 385 | "metadata": {} 386 | } 387 | ] 388 | } -------------------------------------------------------------------------------- /03- Calling Functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "03-Calling Functions" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "Operators are only one way to *get things done*. The other way is to call a *function*. A function has a name, so if we want a particular function *to go and do something*, we call it by name with two final parenthesis, like this:\n", 15 | "\n", 16 | " something()\n", 17 | "\n", 18 | "Python has a function called `random` which returns a random number between 0 and 1. Let's call that:" 19 | ] 20 | }, 21 | { 22 | "cell_type": "code", 23 | "collapsed": false, 24 | "input": [ 25 | "random()" 26 | ], 27 | "language": "python", 28 | "metadata": {}, 29 | "outputs": [ 30 | { 31 | "output_type": "pyout", 32 | "prompt_number": 1, 33 | "text": [ 34 | "0.25315989397277505" 35 | ] 36 | } 37 | ], 38 | "prompt_number": 1 39 | }, 40 | { 41 | "cell_type": "markdown", 42 | "metadata": {}, 43 | "source": [ 44 | "Every time you press the **Play** button in that gray box, the numbers below it change.\n", 45 | "\n", 46 | "Functions can be given *parameters* that can modify their behavior. For instance, the `randint` function returns a *regular* random number between the two numbers given to it. We give it numbers between the parenthesis. If we wanted to pretend that we were rolling a dice, we would do this:" 47 | ] 48 | }, 49 | { 50 | "cell_type": "code", 51 | "collapsed": false, 52 | "input": [ 53 | "randint(1, 6)" 54 | ], 55 | "language": "python", 56 | "metadata": {}, 57 | "outputs": [ 58 | { 59 | "output_type": "pyout", 60 | "prompt_number": 25, 61 | "text": [ 62 | "4" 63 | ] 64 | } 65 | ], 66 | "prompt_number": 25 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "You are probably thinking to yourself, \"I've seen functions before! That `check()` code at the end of every exercise!\"\n", 73 | "\n", 74 | "You are correct. Calling that `check` function and passing it your work is how I can check to see if you did the assignment.\n", 75 | "\n", 76 | "I have function that will show you a dice if you give it a number 1 through 6." 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "collapsed": false, 82 | "input": [ 83 | "side = _\n", 84 | "dice(side)" 85 | ], 86 | "language": "python", 87 | "metadata": {}, 88 | "outputs": [ 89 | { 90 | "output_type": "stream", 91 | "stream": "stdout", 92 | "text": [ 93 | "The number for 'side' must be 1, 2, 3, 4, 5, or 6.\n" 94 | ] 95 | } 96 | ], 97 | "prompt_number": 13 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "metadata": {}, 102 | "source": [ 103 | "In many games that you buy from the store, your random dice rolls are limited to the six sides. This is why some games come with dice with different shapes like this 4 sided and 12 sided dice:\n", 104 | "\n", 105 | "\n", 106 | "\n", 107 | "\n", 108 | "But in computer games we write in Python, we could have a random dice roll with a 7 sided diced: `randint(1,7)`" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "What other functions can we call? Put it this way, Python has so many functions that we have to group them in collections. Soon we will start writing our own functions." 116 | ] 117 | }, 118 | { 119 | "cell_type": "markdown", 120 | "metadata": {}, 121 | "source": [ 122 | "You know that $3^2$ (written as `3**2` in Python) is `9`, but we can get the reverse of this, called a *square root* (in math, this is shown as $\\sqrt{9}$) with the `sqrt()` function. However, it is in the `math` collection, so we have to do this:" 123 | ] 124 | }, 125 | { 126 | "cell_type": "code", 127 | "collapsed": false, 128 | "input": [ 129 | "math.sqrt(9)" 130 | ], 131 | "language": "python", 132 | "metadata": {}, 133 | "outputs": [ 134 | { 135 | "output_type": "pyout", 136 | "prompt_number": 1, 137 | "text": [ 138 | "3.0" 139 | ] 140 | } 141 | ], 142 | "prompt_number": 1 143 | }, 144 | { 145 | "cell_type": "markdown", 146 | "metadata": {}, 147 | "source": [ 148 | "It came back as a decimal number. What if we wanted to get a regular, whole number? We use `int`:" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "collapsed": false, 154 | "input": [ 155 | "int( math.sqrt(9) )" 156 | ], 157 | "language": "python", 158 | "metadata": {}, 159 | "outputs": [ 160 | { 161 | "output_type": "pyout", 162 | "prompt_number": 7, 163 | "text": [ 164 | "3" 165 | ] 166 | } 167 | ], 168 | "prompt_number": 7 169 | }, 170 | { 171 | "cell_type": "markdown", 172 | "metadata": {}, 173 | "source": [ 174 | "Yes, you can call a function *inside* another function call. Just make sure to get the parenthesis right!\n", 175 | "\n", 176 | "Let's make a little game for ourselves. Let's have Python choose a random number, but not tell us. Then is will show us that random numbers square root, and we try to guess it. Sounds like fun, right?" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "collapsed": true, 182 | "input": [ 183 | "random_number = randint(4, _)\n", 184 | "square_root = math.sqrt(random_number)\n", 185 | "\n", 186 | "check(3, 1, square_root, random_number)" 187 | ], 188 | "language": "python", 189 | "metadata": {}, 190 | "outputs": [ 191 | { 192 | "ename": "TypeError", 193 | "evalue": "unsupported operand type(s) for +: 'Image' and 'int'", 194 | "output_type": "pyerr", 195 | "traceback": [ 196 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 197 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mrandom_number\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrandint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m4\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0msquare_root\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mmath\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msqrt\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrandom_number\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mcheck\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msquare_root\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrandom_number\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 198 | "\u001b[0;32m/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.pyc\u001b[0m in \u001b[0;36mrandint\u001b[0;34m(self, a, b)\u001b[0m\n\u001b[1;32m 239\u001b[0m \"\"\"\n\u001b[1;32m 240\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 241\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrandrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mb\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 242\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 243\u001b[0m def _randbelow(self, n, _log=_log, int=int, _maxwidth=1L<\n", 14 | ".rendered_html ol {\n", 15 | " list-style: decimal;\n", 16 | "}\n", 17 | "\n", 18 | "\n", 19 | "Computers are great for doing things over and over again without complaining or needing a coffee break. In this lesson, we'll learn about one way of making our program code loop." 20 | ] 21 | }, 22 | { 23 | "cell_type": "heading", 24 | "level": 2, 25 | "source": [ 26 | "For" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "source": [ 32 | "\n", 33 | "\n", 34 | "Remember our list of `ponies`? Let's print each pony one at a time. Replace the `_` character with your favorite name:" 35 | ] 36 | }, 37 | { 38 | "cell_type": "code", 39 | "collapsed": false, 40 | "input": [ 41 | "ponies = [ \"Applejack\", \"Fluttershy\", \"Scootaloo\", \"Caramel\", \"_\" ]\n", 42 | "\n", 43 | "for pony in ponies: print pony\n", 44 | "# 1 2 3 4 5 6 7" 45 | ], 46 | "language": "python", 47 | "outputs": [ 48 | { 49 | "output_type": "stream", 50 | "stream": "stdout", 51 | "text": [ 52 | "Applejack\n", 53 | "Fluttershy\n", 54 | "Scootaloo\n", 55 | "Caramel\n", 56 | "Rainbow Brite\n" 57 | ] 58 | } 59 | ], 60 | "prompt_number": 3 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "source": [ 65 | "See those numbers after the comment symbol `#`? I put numbers so that I could describe each part of this program:\n", 66 | "\n", 67 | "1. The `for` tells Python that we are going to do a loop.\n", 68 | "2. We create a `pony` variable. Each time around the loop, `pony` will be set to the name of one of the things in our list. In this case, a name of a pony.\n", 69 | "3. The `in` separates the variable from the list name.\n", 70 | "4. Here is our list, `ponies`.\n", 71 | "5. The colon ends the *head* part of the `for` loop start and says that everything else that follows is the *body* part of the loop. The *body* is what will be repeated.\n", 72 | "6. The `print` is what we will do *inside the body* of the loop.\n", 73 | "7. Inside the body, the `pony` variable will be set to each thing in our list.\n", 74 | "\n", 75 | "That is pretty easy once you know about the pieces." 76 | ] 77 | }, 78 | { 79 | "cell_type": "heading", 80 | "level": 2, 81 | "source": [ 82 | "Blocks" 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "source": [ 88 | "But what if you want to do more than one thing in our loop? For instance, we could make up a number for the number of miles a pony ran, like this:\n", 89 | "\n", 90 | " distance = randint(5,20)\n", 91 | " print pony, \"ran\", distance, \"miles\"\n", 92 | "\n", 93 | "While the *body* of a loop must follow the colon symbol, it can go on different lines *as long as those lines are indented*. That is important, so let me show you what I mean. In the program below, change the `_` symbol with a random number:" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "collapsed": false, 99 | "input": [ 100 | "for pony in ponies:\n", 101 | " distance = _\n", 102 | " print pony, \"ran\", distance, \"miles.\"" 103 | ], 104 | "language": "python", 105 | "outputs": [ 106 | { 107 | "output_type": "stream", 108 | "stream": "stdout", 109 | "text": [ 110 | "Applejack ran 15 miles.\n", 111 | "Fluttershy ran 5 miles.\n", 112 | "Scootaloo ran 5 miles.\n", 113 | "Caramel ran 13 miles.\n", 114 | "Rainbow Brite ran 10 miles.\n" 115 | ] 116 | } 117 | ], 118 | "prompt_number": 5 119 | }, 120 | { 121 | "cell_type": "markdown", 122 | "source": [ 123 | "A couple of points to keep in mind:\n", 124 | "\n", 125 | " * Each indented line must be done with spaces (don't use the tab key).\n", 126 | " * Each line must be indented the same amount.\n", 127 | " * End the body of the loop by not indenting it.\n", 128 | "\n", 129 | "Let's do our loop again, but with a starting and finishing line. Replace the first `_` symbol with a text string, `\"\"Ponies run far.\"` and the last `_` symbol with: `\"How far did you run today?\"`" 130 | ] 131 | }, 132 | { 133 | "cell_type": "code", 134 | "collapsed": false, 135 | "input": [ 136 | "print _\n", 137 | "for pony in ponies:\n", 138 | " distance = randint(5,20)\n", 139 | " print pony, \"ran\", distance, \"miles\"\n", 140 | "print _" 141 | ], 142 | "language": "python", 143 | "outputs": [ 144 | { 145 | "output_type": "stream", 146 | "stream": "stdout", 147 | "text": [ 148 | "Ponies run far.\n", 149 | "Applejack ran 16 miles\n", 150 | "Fluttershy ran 18 miles\n", 151 | "Scootaloo ran 14 miles\n", 152 | "Caramel ran 14 miles\n", 153 | "Rainbow Brite ran 10 miles\n", 154 | "How far did you run today?\n" 155 | ] 156 | } 157 | ], 158 | "prompt_number": 6 159 | }, 160 | { 161 | "cell_type": "markdown", 162 | "source": [ 163 | "Alright, enough of the ponies ... let's do some math, since that is why you are here. I wrote a function, `is_prime` that tells you if a number you give it, is something that can only be evenly divided by 1 and itself. For instance:\n", 164 | "\n", 165 | " is_prime(1) # is True\n", 166 | " is_prime(2) # is True\n", 167 | " is_prime(3) # is True\n", 168 | " is_prime(4) # is False\n", 169 | " is_prime(11) # is True\n", 170 | " is_prime(15) # is False\n", 171 | "\n", 172 | "I bet you know how to make a list of all the prime numbers less than 100, right? In the program code below, we need to substitute the `_` with 100 numbers so that the `for` can assign the variable `number` to each one. In the last lesson, we used the `range` function to create lists of numbers, so let's use that." 173 | ] 174 | }, 175 | { 176 | "cell_type": "code", 177 | "collapsed": true, 178 | "input": [ 179 | "for number in _:\n", 180 | " print number, \"is\", is_prime(number)" 181 | ], 182 | "language": "python", 183 | "outputs": [ 184 | { 185 | "output_type": "stream", 186 | "stream": "stdout", 187 | "text": [ 188 | "1 is True\n", 189 | "2 is True\n", 190 | "3 is True\n", 191 | "4 is False\n", 192 | "5 is True\n", 193 | "6 is False\n", 194 | "7 is True\n", 195 | "8 is False\n", 196 | "9 is True\n", 197 | "10 is False\n", 198 | "11 is True\n", 199 | "12 is False\n", 200 | "13 is True\n", 201 | "14 is False\n", 202 | "15 is False\n", 203 | "16 is False\n", 204 | "17 is True\n", 205 | "18 is False\n", 206 | "19 is True\n", 207 | "20 is False\n", 208 | "21 is False\n", 209 | "22 is False\n", 210 | "23 is True\n", 211 | "24 is False\n", 212 | "25 is False\n", 213 | "26 is False\n", 214 | "27 is False\n", 215 | "28 is False\n", 216 | "29 is True\n", 217 | "30 is False\n", 218 | "31 is True\n", 219 | "32 is False\n", 220 | "33 is False\n", 221 | "34 is False\n", 222 | "35 is False\n", 223 | "36 is False\n", 224 | "37 is True\n", 225 | "38 is False\n", 226 | "39 is False\n", 227 | "40 is False\n", 228 | "41 is True\n", 229 | "42 is False\n", 230 | "43 is True\n", 231 | "44 is False\n", 232 | "45 is False\n", 233 | "46 is False\n", 234 | "47 is True\n", 235 | "48 is False\n", 236 | "49 is False\n", 237 | "50 is False\n", 238 | "51 is False\n", 239 | "52 is False\n", 240 | "53 is True\n", 241 | "54 is False\n", 242 | "55 is False\n", 243 | "56 is False\n", 244 | "57 is False\n", 245 | "58 is False\n", 246 | "59 is True\n", 247 | "60 is False\n", 248 | "61 is True\n", 249 | "62 is False\n", 250 | "63 is False\n", 251 | "64 is False\n", 252 | "65 is False\n", 253 | "66 is False\n", 254 | "67 is True\n", 255 | "68 is False\n", 256 | "69 is False\n", 257 | "70 is False\n", 258 | "71 is True\n", 259 | "72 is False\n", 260 | "73 is True\n", 261 | "74 is False\n", 262 | "75 is False\n", 263 | "76 is False\n", 264 | "77 is False\n", 265 | "78 is False\n", 266 | "79 is True\n", 267 | "80 is False\n", 268 | "81 is False\n", 269 | "82 is False\n", 270 | "83 is True\n", 271 | "84 is False\n", 272 | "85 is False\n", 273 | "86 is False\n", 274 | "87 is False\n", 275 | "88 is False\n", 276 | "89 is True\n", 277 | "90 is False\n", 278 | "91 is False\n", 279 | "92 is False\n", 280 | "93 is False\n", 281 | "94 is False\n", 282 | "95 is False\n", 283 | "96 is False\n", 284 | "97 is True\n", 285 | "98 is False\n", 286 | "99 is False\n" 287 | ] 288 | } 289 | ], 290 | "prompt_number": 8 291 | }, 292 | { 293 | "cell_type": "heading", 294 | "level": 2, 295 | "source": [ 296 | "If" 297 | ] 298 | }, 299 | { 300 | "cell_type": "markdown", 301 | "source": [ 302 | "Wow, that's a long list. We really just wanted to see the prime numbers, not all of them. In the program code below, once again, replace the `_` symbol with a list of numbers to check:" 303 | ] 304 | }, 305 | { 306 | "cell_type": "code", 307 | "collapsed": true, 308 | "input": [ 309 | "for number in _:\n", 310 | " if is_prime(number): print number,\n", 311 | "# 1 2 3 4" 312 | ], 313 | "language": "python", 314 | "outputs": [ 315 | { 316 | "output_type": "stream", 317 | "stream": "stdout", 318 | "text": [ 319 | "1 is prime.\n", 320 | "2 is prime.\n", 321 | "3 is prime.\n", 322 | "5 is prime.\n", 323 | "7 is prime.\n", 324 | "9 is prime.\n", 325 | "11 is prime.\n", 326 | "13 is prime.\n", 327 | "17 is prime.\n", 328 | "19 is prime.\n", 329 | "23 is prime.\n", 330 | "29 is prime.\n", 331 | "31 is prime.\n", 332 | "37 is prime.\n", 333 | "41 is prime.\n", 334 | "43 is prime.\n", 335 | "47 is prime.\n", 336 | "53 is prime.\n", 337 | "59 is prime.\n", 338 | "61 is prime.\n", 339 | "67 is prime.\n", 340 | "71 is prime.\n", 341 | "73 is prime.\n", 342 | "79 is prime.\n", 343 | "83 is prime.\n", 344 | "89 is prime.\n", 345 | "97 is prime.\n" 346 | ] 347 | } 348 | ], 349 | "prompt_number": 9 350 | }, 351 | { 352 | "cell_type": "markdown", 353 | "source": [ 354 | "Let me number those parts and describe them:\n", 355 | "\n", 356 | "1. The `if` statement only does something if what follows is `True`\n", 357 | "2. Our function returns either `True` or `False` ... perfect for what the `if` would like to see.\n", 358 | "3. The colon separates the *head* of the `if` from the *body*.\n", 359 | "4. The *body* of the `if` runs if the `if` is `True`. Yeah, say that a few times fast!\n", 360 | "\n", 361 | "**Note:** If the `print` ends with a comma, then it puts everything on one line.\n", 362 | "\n" 363 | ] 364 | }, 365 | { 366 | "cell_type": "heading", 367 | "level": 2, 368 | "source": [ 369 | "If Blocks" 370 | ] 371 | }, 372 | { 373 | "cell_type": "markdown", 374 | "source": [ 375 | "If you were wondering if the `if` statement could take an *indented block* of code, you would guess correctly. We could have written the last program code like:" 376 | ] 377 | }, 378 | { 379 | "cell_type": "code", 380 | "collapsed": false, 381 | "input": [ 382 | "for number in range(100):\n", 383 | " if is_prime(number):\n", 384 | " print number," 385 | ], 386 | "language": "python", 387 | "outputs": [ 388 | { 389 | "output_type": "stream", 390 | "stream": "stdout", 391 | "text": [ 392 | "1 2 3 5 7 9 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97\n" 393 | ] 394 | } 395 | ], 396 | "prompt_number": 10 397 | }, 398 | { 399 | "cell_type": "markdown", 400 | "source": [ 401 | "That's right, the block inside the `if` must be indented *more*, otherwise, Python might think it is part of the `for` block.\n", 402 | "\n", 403 | "If you have understood everything so far, then Python will be a breeze, because we have now covered the *building blocks* of this programming language. Everything else looks like what we've already covered." 404 | ] 405 | }, 406 | { 407 | "cell_type": "heading", 408 | "level": 2, 409 | "source": [ 410 | "While Loops" 411 | ] 412 | }, 413 | { 414 | "cell_type": "markdown", 415 | "source": [ 416 | "Instead of doing for each thing is a list, we can just *repeat stuff*\n", 417 | "until we don't want to. This is done with the `while` loop. We just\n", 418 | "need a reason to stop, otherwise, we'll just keep going forever... and\n", 419 | "that isn't good.\n", 420 | "\n", 421 | "For instance, let's keep doubling a number, like:\n", 422 | "\n", 423 | " 2 4 16 ...\n", 424 | "\n", 425 | "Of course this will keep going forever if we let it, so let's start\n", 426 | "with 2 (and print it out) and then repeat this until we get to 1000." 427 | ] 428 | }, 429 | { 430 | "cell_type": "code", 431 | "collapsed": false, 432 | "input": [ 433 | "d = _ # What number shall we start? How about 2?\n", 434 | "\n", 435 | "while d < _: # We must limit our loop to some value\n", 436 | " print d, # Show us our current value\n", 437 | " d = d * d # Double our number and store it back in d" 438 | ], 439 | "language": "python", 440 | "outputs": [ 441 | { 442 | "output_type": "stream", 443 | "stream": "stdout", 444 | "text": [ 445 | "2 4 16 256\n" 446 | ] 447 | } 448 | ], 449 | "prompt_number": 4 450 | }, 451 | { 452 | "cell_type": "markdown", 453 | "source": [ 454 | "The following program code looks the same, but there is one\n", 455 | "difference. Notice how the print happens *after* we change the `d`\n", 456 | "variable. How will this change the code?" 457 | ] 458 | }, 459 | { 460 | "cell_type": "code", 461 | "collapsed": false, 462 | "input": [ 463 | "d = 2\n", 464 | "\n", 465 | "while d < 1000:\n", 466 | " d = d * d\n", 467 | " print d," 468 | ], 469 | "language": "python", 470 | "outputs": [ 471 | { 472 | "output_type": "stream", 473 | "stream": "stdout", 474 | "text": [ 475 | "4 16 256 65536\n" 476 | ] 477 | } 478 | ], 479 | "prompt_number": 6 480 | }, 481 | { 482 | "cell_type": "markdown", 483 | "source": [ 484 | "First, the `2` isn't printed, since we change `d` before we print it.\n", 485 | "\n", 486 | "Why is `65536` printed when it is larger than `1000`? Let's do a\n", 487 | "*mental exercise* and walk through the code with our brains. When `d`\n", 488 | "is 256, we check to see `if d < 1000`.\n", 489 | "\n", 490 | "Since `d` is less than 1000, Python will run the code that is\n", 491 | "underneath and indented. First step is to change `d` with the value\n", 492 | "from `d * d`. Well, $256 \\times 256 = 65536$ and that is what `d` is\n", 493 | "when we get to the `print` line.\n", 494 | "\n", 495 | "Finally, we loop back to our `while` line, and now `d` is *not* less\n", 496 | "than 1000, so the loop ends, and so does our code. In other words, our\n", 497 | "program did exactly what we told it." 498 | ] 499 | }, 500 | { 501 | "cell_type": "heading", 502 | "level": 3, 503 | "source": [ 504 | "Finding Square Roots" 505 | ] 506 | }, 507 | { 508 | "cell_type": "markdown", 509 | "source": [ 510 | "You know the square root of 16 is 4, right? What is the square root of 600? Let's see if we can figure it out.\n", 511 | "\n", 512 | "We will start with a variable, `r` set to 1, then 2, then 3. Each time we will multiply it together to see when we pass 600:" 513 | ] 514 | }, 515 | { 516 | "cell_type": "code", 517 | "collapsed": false, 518 | "input": [ 519 | "r = 1\n", 520 | "while r * r < 600: # Is the square of r still less than 600?\n", 521 | " r = r + 1 # Add 1 to r and try again\n", 522 | "\n", 523 | "# When we get to this point, our loop is over, and r*r is larger than 600,\n", 524 | "# So the square root must be between it and the number just lower:\n", 525 | "\n", 526 | "print \"The square root is between\", r-1, \"and\", r\n", 527 | "\n", 528 | "# How do we know this? We'll let's tell ourselves what r*r is:\n", 529 | "print \"Because\", r, \"*\", r, \"=\", r*r, \"which is too high\"\n", 530 | "\n", 531 | "# And I wonder what the smaller square number is? \n", 532 | "print \"And\", r-1, \"*\", r-1, \"=\", r-1 * r-1" 533 | ], 534 | "language": "python", 535 | "outputs": [ 536 | { 537 | "output_type": "stream", 538 | "stream": "stdout", 539 | "text": [ 540 | "The square root is between 24 and 25\n", 541 | "Because 25 * 25 = 625 which is too high\n", 542 | "And 24 * 24 = -1\n" 543 | ] 544 | } 545 | ], 546 | "prompt_number": 10 547 | }, 548 | { 549 | "cell_type": "markdown", 550 | "source": [ 551 | "Wait a minute! $24 \\times 24$ is NOT -1? How is our program wrong?\n", 552 | "\n", 553 | "If you have a math equation with both addition or subtraction AND multiplication or division, then multiplication takes place first. So, the first thing to happen is $1 \\times r$ ... which is just `r`, right?\n", 554 | "\n", 555 | " * $r - 1 \\times r - 1$\n", 556 | " * $r - r - 1$\n", 557 | " * $0 - 1$\n", 558 | " * $-1$\n", 559 | "\n", 560 | "If you want to get the subtraction to happen first, we put that in parenthesis:\n" 561 | ] 562 | }, 563 | { 564 | "cell_type": "code", 565 | "collapsed": false, 566 | "input": [ 567 | "(r - 1) * (r - 1)" 568 | ], 569 | "language": "python", 570 | "outputs": [ 571 | { 572 | "output_type": "pyout", 573 | "prompt_number": 12, 574 | "text": [ 575 | "576" 576 | ] 577 | } 578 | ], 579 | "prompt_number": 12 580 | }, 581 | { 582 | "cell_type": "markdown", 583 | "source": [ 584 | "So pop back up to our square root finder and fix it.\n", 585 | "\n", 586 | "Can you think of ways to make it better? I bet you can. Play around\n", 587 | "with it and see what you can do, and we'll come back to it in a later\n", 588 | "lesson." 589 | ] 590 | } 591 | ] 592 | } 593 | ] 594 | } -------------------------------------------------------------------------------- /06- If and Else.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "06-If and Else" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "heading", 12 | "level": 2, 13 | "metadata": {}, 14 | "source": [ 15 | "If and Else" 16 | ] 17 | }, 18 | { 19 | "cell_type": "markdown", 20 | "metadata": {}, 21 | "source": [ 22 | "In the last lesson, I barely talked about the `if`. As you saw, it is really easy to use. In this lesson, we talk about it a bit more since it is really important. First, let's start off with our list. Change the `_` with the name of your favorite pony (or your name if you don't have a favorite):" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": false, 28 | "input": [ 29 | "ponies = [ \"Applejack\", \"Fluttershy\", \"Scootaloo\", \"Caramel\", \"_\" ]" 30 | ], 31 | "language": "python", 32 | "metadata": {}, 33 | "outputs": [], 34 | "prompt_number": 1 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "Next, let's pick a pony at random. To do that, we use our `randint` function set to pick a random number from `0` to the `len(ponies)`. Remember, that `len(ponies)` will return `5`, and if `randint` is set to `5`, it will pick a random number from `0` to `4` (one less than the number you give it)." 41 | ] 42 | }, 43 | { 44 | "cell_type": "code", 45 | "collapsed": false, 46 | "input": [ 47 | "picked = ponies[ randint( len(ponies) ) ]\n", 48 | "\n", 49 | "picked" 50 | ], 51 | "language": "python", 52 | "metadata": {}, 53 | "outputs": [ 54 | { 55 | "output_type": "pyout", 56 | "prompt_number": 6, 57 | "text": [ 58 | "'Scootaloo'" 59 | ] 60 | } 61 | ], 62 | "prompt_number": 6 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "What pony did it pick? Having the last line be *picked* means that it will display the name of the random pony it chose. Click the **Play** button again to get a different pony. Now, let's turn this into a *guessing game*. First, get rid of the last `picked` line in the code cell above, and press the **Play** button again. Now we don't know which pony was picked.\n", 69 | "\n", 70 | "In the line below, change the `_` symbol with the text string, `Scootaloo`, or any other pony that you think Python chose. (Remember the quotes)" 71 | ] 72 | }, 73 | { 74 | "cell_type": "code", 75 | "collapsed": false, 76 | "input": [ 77 | "guess = _" 78 | ], 79 | "language": "python", 80 | "metadata": {}, 81 | "outputs": [], 82 | "prompt_number": 8 83 | }, 84 | { 85 | "cell_type": "markdown", 86 | "metadata": {}, 87 | "source": [ 88 | "Now, let's check if our guess is correct. Press **Play** in the following cell." 89 | ] 90 | }, 91 | { 92 | "cell_type": "code", 93 | "collapsed": false, 94 | "input": [ 95 | "if guess == picked:\n", 96 | " print \"You're right! I picked\", picked\n", 97 | "else:\n", 98 | " print \"Nope. I was thinking of\", picked" 99 | ], 100 | "language": "python", 101 | "metadata": {}, 102 | "outputs": [ 103 | { 104 | "output_type": "stream", 105 | "stream": "stdout", 106 | "text": [ 107 | "You're right! I picked Scootaloo\n" 108 | ] 109 | } 110 | ], 111 | "prompt_number": 10 112 | }, 113 | { 114 | "cell_type": "markdown", 115 | "metadata": {}, 116 | "source": [ 117 | "The first line checks to see if `guess` is the same as `picked` (remember, we aren't *assigning* `picked` to `guess`, we are *comparing*, so we need to use the double `==` equals symbol).\n", 118 | "\n", 119 | "If we didn't guess right, the `else` command on the third line tells Python to run the next code section, which tells us that we didn't guess the answer." 120 | ] 121 | }, 122 | { 123 | "cell_type": "heading", 124 | "level": 2, 125 | "metadata": {}, 126 | "source": [ 127 | "Else and Else If" 128 | ] 129 | }, 130 | { 131 | "cell_type": "markdown", 132 | "metadata": {}, 133 | "source": [ 134 | "I don't know about you, but I think this game is too hard. Perhaps we need a clue to which pony Python picked.\n", 135 | "\n", 136 | "In this next cell, let's give ourselves some clues. Replace the `_` with a clue about *Caramel*:" 137 | ] 138 | }, 139 | { 140 | "cell_type": "code", 141 | "collapsed": false, 142 | "input": [ 143 | "if picked == \"Applejack\": # Line 1\n", 144 | " print \"This pony was named after a cereal.\" # Line 2\n", 145 | "elif picked == \"Fluttershy\": # Line 3\n", 146 | " print \"This pony is very, very shy.\" # Line 4\n", 147 | "elif picked == \"Scootaloo\": # Line 5\n", 148 | " print \"This pony has a funny name.\" # Line 6\n", 149 | "elif picked == \"Caramel\":\n", 150 | " _\n", 151 | "else: # Line 9\n", 152 | " print \"This is my new pony.\" # Line 10" 153 | ], 154 | "language": "python", 155 | "metadata": {}, 156 | "outputs": [ 157 | { 158 | "output_type": "stream", 159 | "stream": "stdout", 160 | "text": [ 161 | "This pony has a funny name.\n" 162 | ] 163 | } 164 | ], 165 | "prompt_number": 7 166 | }, 167 | { 168 | "cell_type": "markdown", 169 | "metadata": {}, 170 | "source": [ 171 | "Let's walk through this code. The first line checks to see if the `picked` variable has `Applejack` and if so, it prints the Applejack clue. The `elif` on the third line, is a Python term that is short for *else if*. So, if the `picked` wasn't Applejack, then we will check to see if `picked` is set to `Fluttershy`. If it is, we print the Fluttershy clue on line 4.\n", 172 | "\n", 173 | "If it wasn't, it goes to the next `elif` (on line 5) and checks to see if `picked` is set to `Scootaloo`. You get the idea. The ninth line is just `else`, and this tells Python that if we didn't match anything before, print the clue, `This is my new pony.`\n", 174 | "\n", 175 | "When you press the **Play** button, can you guess which pony was chosen? Of course you can, the answers are right there. ;-) But soon, we'll hide our code, and we'll just see the words from the `print` commands, and then our friends will have to guess." 176 | ] 177 | }, 178 | { 179 | "cell_type": "heading", 180 | "level": 2, 181 | "metadata": {}, 182 | "source": [ 183 | "Better Guessing Game" 184 | ] 185 | }, 186 | { 187 | "cell_type": "markdown", 188 | "metadata": {}, 189 | "source": [ 190 | "Let's make a better guessing game, that isn't too hard or too easy. First, let's get a secret number:" 191 | ] 192 | }, 193 | { 194 | "cell_type": "code", 195 | "collapsed": false, 196 | "input": [ 197 | "secret = randint(1, 10)" 198 | ], 199 | "language": "python", 200 | "metadata": {}, 201 | "outputs": [], 202 | "prompt_number": 21 203 | }, 204 | { 205 | "cell_type": "markdown", 206 | "metadata": {}, 207 | "source": [ 208 | "Next, we guess the number, and get a message telling us a hint about picking a better number. Replace `_` with your guess. You can keep changing it and pressing the **Play** button to see if you can guess it." 209 | ] 210 | }, 211 | { 212 | "cell_type": "code", 213 | "collapsed": false, 214 | "input": [ 215 | "guess = _\n", 216 | "\n", 217 | "if guess > secret:\n", 218 | " print \"You guessed too high. Try again.\"\n", 219 | "elif guess < secret:\n", 220 | " print \"Your guess is too low. Try again.\"\n", 221 | "elif guess == secret:\n", 222 | " print \"You did it! You guessed right!\"" 223 | ], 224 | "language": "python", 225 | "metadata": {}, 226 | "outputs": [ 227 | { 228 | "output_type": "stream", 229 | "stream": "stdout", 230 | "text": [ 231 | "You guessed too high. Try again.\n" 232 | ] 233 | } 234 | ], 235 | "prompt_number": 15 236 | }, 237 | { 238 | "cell_type": "markdown", 239 | "metadata": {}, 240 | "source": [ 241 | "We could make this game a bit better with a few more clues. We could see if *difference* between the `guess` and the `secret` is more than 4, we could print a better message:" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "collapsed": false, 247 | "input": [ 248 | "guess = _\n", 249 | "\n", 250 | "if guess > secret and guess - secret > 4:\n", 251 | " print \"Your guess is way too high. Try again.\"\n", 252 | "elif guess > secret:\n", 253 | " print \"Your guess is too high. Try again\"\n", 254 | "elif guess < secret and secret - guess > 4:\n", 255 | " print \"Your guess is way too low. Try again.\"\n", 256 | "elif guess < secret:\n", 257 | " print \"Your guess is too low. Try again\"\n", 258 | "elif guess == secret:\n", 259 | " print \"You did it! You guessed right!\"" 260 | ], 261 | "language": "python", 262 | "metadata": {}, 263 | "outputs": [ 264 | { 265 | "output_type": "stream", 266 | "stream": "stdout", 267 | "text": [ 268 | "Your guess is way too high. Try again.\n" 269 | ] 270 | } 271 | ], 272 | "prompt_number": 27 273 | }, 274 | { 275 | "cell_type": "markdown", 276 | "metadata": {}, 277 | "source": [ 278 | "Notice the word `and`? That let's use check two things, but they *both* have to be true before Python will run the indented section.\n", 279 | "\n", 280 | "Let's expand the game to keep track of how many times it takes us to guess right. Let's pick a new random number, and we will make a new variable, `count`, to keep track of our guesses:" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "collapsed": false, 286 | "input": [ 287 | "secret = randint(1, 20)\n", 288 | "count = 0" 289 | ], 290 | "language": "python", 291 | "metadata": {}, 292 | "outputs": [], 293 | "prompt_number": 29 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "Our Python code is pretty similar to what we had before:" 300 | ] 301 | }, 302 | { 303 | "cell_type": "code", 304 | "collapsed": false, 305 | "input": [ 306 | "guess = _\n", 307 | "\n", 308 | "count = count + 1 # Each time this runs, we add 1 to count\n", 309 | "\n", 310 | "if guess > secret and guess - secret > 4:\n", 311 | " print \"Your guess is way too high. Try again.\"\n", 312 | "elif guess > secret:\n", 313 | " print \"Your guess is too high. Try again\"\n", 314 | "elif guess < secret and secret - guess > 4:\n", 315 | " print \"Your guess is way too low. Try again.\"\n", 316 | "elif guess < secret:\n", 317 | " print \"Your guess is too low. Try again\"\n", 318 | "elif guess == secret:\n", 319 | " print \"You did it! You guessed the number in\", count, \"tries.\"\n", 320 | " show_award()" 321 | ], 322 | "language": "python", 323 | "metadata": {}, 324 | "outputs": [ 325 | { 326 | "output_type": "stream", 327 | "stream": "stdout", 328 | "text": [ 329 | "You did it! You guessed the number in 8 tries.\n" 330 | ] 331 | } 332 | ], 333 | "prompt_number": 37 334 | }, 335 | { 336 | "cell_type": "markdown", 337 | "metadata": {}, 338 | "source": [ 339 | "The `show_award` function on the last line is something I wrote to display an award when you win. \n", 340 | "\n", 341 | "I think it is time to teach you how to make your own functions, don't you?" 342 | ] 343 | } 344 | ], 345 | "metadata": {} 346 | } 347 | ] 348 | } -------------------------------------------------------------------------------- /07- Making Functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "07- Making Functions" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "heading", 12 | "level": 2, 13 | "source": [ 14 | "Making Functions" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "As you know now, a function is a way of collecting some Python code and attaching a name to it. Then you can *call* it anytime.\n", 21 | "\n", 22 | "To make a function, you use `def`, like this:" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": false, 28 | "input": [ 29 | "def hello(): print \"Hello there!\"\n", 30 | "# 1 2 3 4 5 6\n", 31 | "\n", 32 | "hello()" 33 | ], 34 | "language": "python", 35 | "outputs": [ 36 | { 37 | "output_type": "stream", 38 | "stream": "stdout", 39 | "text": [ 40 | "Hello there!\n" 41 | ] 42 | } 43 | ], 44 | "prompt_number": 3 45 | }, 46 | { 47 | "cell_type": "markdown", 48 | "source": [ 49 | "The `def` (above the 1) tells Python that we are going to *define a function*, and that the word that follows is its name (above the 2).\n", 50 | "\n", 51 | "Remember how every time you call a function, you put parenthesis after it? Well, we do this when we make the function, too (the parens are above the 3).\n", 52 | "\n", 53 | "Just like with `for` and `if`, the colon (above the 4), separates the *head* of the function from the *body* (above the 5 and 6).\n", 54 | "\n", 55 | "Usually our functions do a lot of things, and if you functions does two or more, you need to put the function body on separate lines, but indented, like this:" 56 | ] 57 | }, 58 | { 59 | "cell_type": "code", 60 | "collapsed": false, 61 | "input": [ 62 | "def hello():\n", 63 | " print \"Hello there!\"" 64 | ], 65 | "language": "python", 66 | "outputs": [] 67 | }, 68 | { 69 | "cell_type": "heading", 70 | "level": 2, 71 | "source": [ 72 | "Parameters" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "source": [ 78 | "A *parameter* (we sometimes call them *arguments*) are things we can pass *into* a function. For instance:" 79 | ] 80 | }, 81 | { 82 | "cell_type": "code", 83 | "collapsed": false, 84 | "input": [ 85 | "def hello(name):\n", 86 | " print \"Hello\", name\n", 87 | "\n", 88 | "hello(\"Charlie\")" 89 | ], 90 | "language": "python", 91 | "outputs": [ 92 | { 93 | "output_type": "stream", 94 | "stream": "stdout", 95 | "text": [ 96 | "Hello Charlie\n" 97 | ] 98 | } 99 | ], 100 | "prompt_number": 5 101 | }, 102 | { 103 | "cell_type": "markdown", 104 | "source": [ 105 | "You can pass in more than one thing into a function if you separate them with commas:" 106 | ] 107 | }, 108 | { 109 | "cell_type": "code", 110 | "collapsed": false, 111 | "input": [ 112 | "def larger(a, b):\n", 113 | " if a < b:\n", 114 | " print a, \"is less than\", b\n", 115 | " elif a > b:\n", 116 | " print a, \"is greater than\", b\n", 117 | " else:\n", 118 | " print a, \"is the same as\", b\n", 119 | "\n", 120 | "larger(3, 5)" 121 | ], 122 | "language": "python", 123 | "outputs": [ 124 | { 125 | "output_type": "stream", 126 | "stream": "stdout", 127 | "text": [ 128 | "3 is less than 5\n" 129 | ] 130 | } 131 | ], 132 | "prompt_number": 7 133 | }, 134 | { 135 | "cell_type": "heading", 136 | "level": 2, 137 | "source": [ 138 | "Returning Values" 139 | ] 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "source": [ 144 | "If you want the function to give you back something, you use `return`:" 145 | ] 146 | }, 147 | { 148 | "cell_type": "code", 149 | "collapsed": false, 150 | "input": [ 151 | "def getSecret():\n", 152 | " return randint(1, 10)\n", 153 | "\n", 154 | "guess = 6\n", 155 | "\n", 156 | "if guess == getSecret():\n", 157 | " print \"You're quite lucky! You guessed it right.\"\n", 158 | "else:\n", 159 | " print \"I didn't think you could guess it on the first try.\"" 160 | ], 161 | "language": "python", 162 | "outputs": [ 163 | { 164 | "output_type": "stream", 165 | "stream": "stdout", 166 | "text": [ 167 | "I didn't think you could guess it on the first try.\n" 168 | ] 169 | } 170 | ], 171 | "prompt_number": 4 172 | }, 173 | { 174 | "cell_type": "markdown", 175 | "source": [ 176 | "You can use more than one `return`, but once Python runs the `return`, it doesn't do anything else. This means that both of these functions are the same:\n" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "collapsed": false, 182 | "input": [ 183 | "def difference1(a, b):\n", 184 | " if a < b:\n", 185 | " return b - a\n", 186 | " else:\n", 187 | " return a - b\n", 188 | "\n", 189 | "def difference2(a, b):\n", 190 | " if a < b:\n", 191 | " return b - a\n", 192 | "\n", 193 | " return a - b\n", 194 | "\n", 195 | "print \"Difference of 3 and 6 is\", difference1(3, 6)\n", 196 | "print \"Difference of 8 and 2 is\", difference2(8, 2)" 197 | ], 198 | "language": "python", 199 | "outputs": [ 200 | { 201 | "output_type": "stream", 202 | "stream": "stdout", 203 | "text": [ 204 | "Difference of 3 and 6 is 3\n", 205 | "Difference of 8 and 2 is 6\n" 206 | ] 207 | } 208 | ], 209 | "prompt_number": 12 210 | }, 211 | { 212 | "cell_type": "markdown", 213 | "source": [ 214 | "Now you know quite a bit about how to make functions. In the next\n", 215 | "lesson, we'll put that to good use to make some functions to help us\n", 216 | "make a list of prime numbers." 217 | ] 218 | } 219 | ] 220 | } 221 | ] 222 | } -------------------------------------------------------------------------------- /08- Finding Primes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "08- Finding Primes" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "heading", 12 | "level": 2, 13 | "source": [ 14 | "Finding Prime Numbers" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "Let's put what we know about functions to make a project to list out\n", 21 | "prime numbers. Remember that `is_prime` function I wrote for you?\n", 22 | "Let's make a version of it. A number is prime if it can only be evenly\n", 23 | "divided by 1 and itself. But we will need some clearer rules for\n", 24 | "Python. Can you think of some? Here is my first list:\n", 25 | "\n", 26 | " * If the number is negative, it isn't prime.\n", 27 | " * If the number is zero, it isn't prime.\n", 28 | " * If the number is one, it is prime.\n", 29 | " * Both two and three are prime numbers.\n", 30 | " * 4 and every other even number is not prime.\n", 31 | "\n", 32 | "These rules are easy to write up, so here is our first attempt:" 33 | ] 34 | }, 35 | { 36 | "cell_type": "code", 37 | "collapsed": false, 38 | "input": [ 39 | "def is_prime(x):\n", 40 | " if x < 1:\n", 41 | " return False\n", 42 | " elif x < 4:\n", 43 | " return True\n", 44 | " elif is_even(x):\n", 45 | " return False\n", 46 | " else:\n", 47 | " return True" 48 | ], 49 | "language": "python", 50 | "outputs": [], 51 | "prompt_number": 12 52 | }, 53 | { 54 | "cell_type": "markdown", 55 | "source": [ 56 | "Except that we need an `is_even` function. Can you write that? I'll start:" 57 | ] 58 | }, 59 | { 60 | "cell_type": "code", 61 | "collapsed": false, 62 | "input": [ 63 | "def is_even(x):\n", 64 | " return x _ 2 == 0 # Return True is evenly divided by 2" 65 | ], 66 | "language": "python", 67 | "outputs": [], 68 | "prompt_number": 3 69 | }, 70 | { 71 | "cell_type": "markdown", 72 | "source": [ 73 | "What should we replace the `_` symbol? That's right the `%` operator, we call *modulus*. We want to make sure that our function is good so far, so we *test it* by writing some more code to see if we got it right:" 74 | ] 75 | }, 76 | { 77 | "cell_type": "code", 78 | "collapsed": false, 79 | "input": [ 80 | "for t in range(5):\n", 81 | " print t, \"is prime?\", is_prime(t)" 82 | ], 83 | "language": "python", 84 | "outputs": [ 85 | { 86 | "output_type": "stream", 87 | "stream": "stdout", 88 | "text": [ 89 | " 0 is prime? False\n", 90 | "1 is prime? True\n", 91 | "2 is prime? True\n", 92 | "3 is prime? True\n", 93 | "4 is prime? False\n" 94 | ] 95 | } 96 | ], 97 | "prompt_number": 5 98 | }, 99 | { 100 | "cell_type": "markdown", 101 | "source": [ 102 | "So far, so good. However, to test higher and higher numbers means we have to keep looking at the output to make sure we are right, and that sounds *tedious*. Let's make Python do it. We will use `assert` which means, *we assert that the following must be true... scream if it isn't*.\n", 103 | "\n", 104 | "The `assert` is a function that must be given something that is *always true*. So to test if `1` is prime, we do this:" 105 | ] 106 | }, 107 | { 108 | "cell_type": "code", 109 | "collapsed": false, 110 | "input": [ 111 | "assert( is_prime(1) )" 112 | ], 113 | "language": "python", 114 | "outputs": [], 115 | "prompt_number": 8 116 | }, 117 | { 118 | "cell_type": "markdown", 119 | "source": [ 120 | "It doesn't give us an error when we click **Play** on that cell, so it must be right. What about our other statements? We use `not` to tell Python that what follows should be false, like 4 or 0:" 121 | ] 122 | }, 123 | { 124 | "cell_type": "code", 125 | "collapsed": false, 126 | "input": [ 127 | "assert( not is_prime(0) )\n", 128 | "assert( is_prime(1) ) # Yeah, I just lined them up pretty to make it easier to read\n", 129 | "assert( is_prime(2) )\n", 130 | "assert( is_prime(3) )\n", 131 | "assert( not is_prime(4) )" 132 | ], 133 | "language": "python", 134 | "outputs": [], 135 | "prompt_number": 9 136 | }, 137 | { 138 | "cell_type": "markdown", 139 | "source": [ 140 | "But what about 9? 9 is not prime, but we don't have a rule in our function for figuring it out, so right now, our function will think that since 9 is odd (not even) and greater than 4, then it must be prime:" 141 | ] 142 | }, 143 | { 144 | "cell_type": "code", 145 | "collapsed": false, 146 | "input": [ 147 | "assert( not is_prime(9) )" 148 | ], 149 | "language": "python", 150 | "outputs": [ 151 | { 152 | "ename": "AssertionError", 153 | "evalue": "", 154 | "output_type": "pyerr", 155 | "traceback": [ 156 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)", 157 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32massert\u001b[0m\u001b[0;34m(\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mis_prime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m9\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 158 | "\u001b[0;31mAssertionError\u001b[0m: " 159 | ] 160 | } 161 | ], 162 | "prompt_number": 14 163 | }, 164 | { 165 | "cell_type": "markdown", 166 | "source": [ 167 | "And sure enough we got ourselves an error. While that isn't what we want, it is what we expect... at least until we come up with another rule in our `is_prime` function. Remember our `is_even` function that did the modulus of 2? We could do a modulus of 3 and that will catch a 9...\n", 168 | "\n", 169 | " elif x % 3 == 0:\n", 170 | " return False\n", 171 | "\n", 172 | "But what about 15? That is dividable by 5...\n", 173 | "\n", 174 | " elif x % 5 == 0:\n", 175 | " return False\n", 176 | "\n", 177 | "This will get *tedious* quick... and by tedious, we should have Python do that sort of work. Do you see the pattern? A number is not prime if we can modulus *any number* and get 0.\n", 178 | "\n", 179 | "This calls for a loop! We'll use a variable `t` to loop through all the possibly numbers that we could use to test the modulus. But what numbers should that be? We need to replace two `_` symbols with our starting number and our ending number. Since we are already checking for 2 (with our `is_even` function), we can simply start checking at 3. That that is the first number in our `range`.\n", 180 | "\n", 181 | "Where should we end? Well, we don't need to test anything higher than the number... in fact, we shouldn't even test our number, since `x % x` will always be true, so we just need to end just before our number, `x`. But the `range` always ends right before the second number we give it, so the second parameter to `range` should be `x`. Get it?" 182 | ] 183 | }, 184 | { 185 | "cell_type": "code", 186 | "collapsed": false, 187 | "input": [ 188 | "def is_prime(x):\n", 189 | " if x < 1:\n", 190 | " return False\n", 191 | " elif x < 4:\n", 192 | " return True\n", 193 | " elif is_even(x):\n", 194 | " return False\n", 195 | " else:\n", 196 | " for t in range(_, _):\n", 197 | " if x % t == 0:\n", 198 | " return False\n", 199 | " return True\n", 200 | "\n", 201 | "assert( not is_prime(0) )\n", 202 | "assert( is_prime(1) ) # Yeah, I just lined them up pretty to make it easier to read\n", 203 | "assert( is_prime(2) )\n", 204 | "assert( is_prime(3) )\n", 205 | "assert( not is_prime(4) )\n", 206 | "assert( is_prime(5) )\n", 207 | "assert( not is_prime(9) )\n", 208 | "assert( is_prime(11) )\n", 209 | "assert( not is_prime(15) )" 210 | ], 211 | "language": "python", 212 | "outputs": [], 213 | "prompt_number": 17 214 | }, 215 | { 216 | "cell_type": "markdown", 217 | "source": [ 218 | "It works! And now, we can make another function that shows all the prime numbers up to a limit:" 219 | ] 220 | }, 221 | { 222 | "cell_type": "code", 223 | "collapsed": false, 224 | "input": [ 225 | "def show_primes(limit):\n", 226 | " for y in range(1, limit + 1):\n", 227 | " if is_prime(y):\n", 228 | " print y,\n", 229 | "\n", 230 | "show_primes(100)" 231 | ], 232 | "language": "python", 233 | "outputs": [ 234 | { 235 | "output_type": "stream", 236 | "stream": "stdout", 237 | "text": [ 238 | "1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97\n" 239 | ] 240 | } 241 | ], 242 | "prompt_number": 20 243 | }, 244 | { 245 | "cell_type": "markdown", 246 | "source": [ 247 | "Do you see how we make lots of little functions to solve big problems? That is how we do everything! And then we *share* our functions with others, so that they can just call our functions to solve even bigger problems.\n", 248 | "\n", 249 | "We haven't finished learning everything about function... I've got more to show you in the next lesson." 250 | ] 251 | } 252 | ] 253 | } 254 | ] 255 | } -------------------------------------------------------------------------------- /09- More Functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "08- More Functions" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "heading", 12 | "level": 2, 13 | "source": [ 14 | "More Functions" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "You'll remember from our previous discussion that a *function* is like magic bucket... you put in something, but then get something different back. You *define* a function with `def` and the function's name. Keep in mind, a function an *indented section* for its body. When your function has something to give back, use the `return` call.\n", 21 | "\n", 22 | "Let's make a `square` function that takes a parameter called `x`, and returns $x \\times x$. Replace the `_` symbol with an expression for $x^2$:" 23 | ] 24 | }, 25 | { 26 | "cell_type": "code", 27 | "collapsed": false, 28 | "input": [ 29 | "def square(x):\n", 30 | " return _\n", 31 | "\n", 32 | "print square(4) # This should return 16\n", 33 | "print square(25) # This should return 625" 34 | ], 35 | "language": "python", 36 | "outputs": [ 37 | { 38 | "output_type": "stream", 39 | "stream": "stdout", 40 | "text": [ 41 | "16\n", 42 | "625\n" 43 | ] 44 | } 45 | ], 46 | "prompt_number": 1 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "source": [ 51 | "Enough review, let's talk about something really cool... A function can actually call another *function*!" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "collapsed": false, 57 | "input": [ 58 | "def cube(x):\n", 59 | " return x * square(x)\n", 60 | "\n", 61 | "print cube(3)" 62 | ], 63 | "language": "python", 64 | "outputs": [ 65 | { 66 | "output_type": "stream", 67 | "stream": "stdout", 68 | "text": [ 69 | "27\n" 70 | ] 71 | } 72 | ], 73 | "prompt_number": 2 74 | }, 75 | { 76 | "cell_type": "heading", 77 | "level": 2, 78 | "source": [ 79 | "Let's make a \"Power\" function" 80 | ] 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "source": [ 85 | "Remember how if you ask this question:\n", 86 | "\n", 87 | "$a + a + a + a$\n", 88 | "\n", 89 | "You could just ask how many $a$'s are there, and then change it to:\n", 90 | "\n", 91 | "$a \\times 4$\n", 92 | "\n", 93 | "We can do the same thing if with this question:\n", 94 | "\n", 95 | "$ a \\times a \\times a \\times a $\n", 96 | "\n", 97 | "This is the same as $a^4$ ... or *a to the power of 4*. Let's create a `power` function." 98 | ] 99 | }, 100 | { 101 | "cell_type": "code", 102 | "collapsed": false, 103 | "input": [ 104 | "def pow1(x, y): # Our first attempt at a power function\n", 105 | " result = 1 # We will \"return\" this result\n", 106 | " for i in range(y):\n", 107 | " result = result * x\n", 108 | " return result" 109 | ], 110 | "language": "python", 111 | "outputs": [], 112 | "prompt_number": 14 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "source": [ 117 | "Remember, `range(5)` returns an array: `[0, 1, 2, 3, 4, 5]` and `for` will make our `i` variable equal each one of these values. So if `x` is 5 and `y` is 4, the result will be each of these in turn:\n", 118 | "\n", 119 | " * $i = 0 , result = 1 \\times 5 = 5$\n", 120 | " * $i = 1 , result = 5 \\times 5 = 25$\n", 121 | " * $i = 2 , result = 25 \\times 5 = 125$\n", 122 | " * $i = 3 , result = 125 \\times 5 = 625$\n", 123 | " * $i = 4 , result = 625 \\times 5 = 3125$\n", 124 | "\n", 125 | "At the end of the loop when `i` is 4, it returns this final result.\n", 126 | "\n", 127 | "Let's check our results:" 128 | ] 129 | }, 130 | { 131 | "cell_type": "code", 132 | "collapsed": false, 133 | "input": [ 134 | "print pow1(5, 0)\n", 135 | "print pow1(5, 1)\n", 136 | "print pow1(5, 2)\n", 137 | "print pow1(5, 3)" 138 | ], 139 | "language": "python", 140 | "outputs": [ 141 | { 142 | "output_type": "stream", 143 | "stream": "stdout", 144 | "text": [ 145 | "1\n", 146 | "5\n", 147 | "25\n", 148 | "125\n" 149 | ] 150 | } 151 | ], 152 | "prompt_number": 15 153 | }, 154 | { 155 | "cell_type": "markdown", 156 | "source": [ 157 | "Let's try a different `power` function. This time we will change the `y`:" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "collapsed": false, 163 | "input": [ 164 | "def pow2(x, y):\n", 165 | " result = 1\n", 166 | " while y > 0:\n", 167 | " result = result * x\n", 168 | " y = y - 1\n", 169 | " return result" 170 | ], 171 | "language": "python", 172 | "outputs": [], 173 | "prompt_number": 6 174 | }, 175 | { 176 | "cell_type": "code", 177 | "collapsed": false, 178 | "input": [ 179 | "print pow2(4, 0)\n", 180 | "print pow2(4, 1)\n", 181 | "print pow2(4, 2)\n", 182 | "print pow2(4, 3)" 183 | ], 184 | "language": "python", 185 | "outputs": [ 186 | { 187 | "output_type": "stream", 188 | "stream": "stdout", 189 | "text": [ 190 | "1\n", 191 | "4\n", 192 | "16\n", 193 | "64\n" 194 | ] 195 | } 196 | ], 197 | "prompt_number": 16 198 | }, 199 | { 200 | "cell_type": "markdown", 201 | "source": [ 202 | "Keep in mind, $x^y$ is really the same as $x \\times x^{y-1}$ ... maybe an example would be good. You know that $6^3 = 6 \\times 6^2$ which is also the same as $6 \\times 6 \\times 6^1$ ... Oh, you know that $6^1 = 6$.\n", 203 | "\n", 204 | "Let's make a new version of our `pow` function, but this time we will have our function call itself with y being 1 smaller:" 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "collapsed": false, 210 | "input": [ 211 | "def pow(x, y):\n", 212 | " \"x is the base number. y is the power to raise x.\"\n", 213 | " if y == 0:\n", 214 | " return 1\n", 215 | " elif y == 1:\n", 216 | " return x\n", 217 | " else:\n", 218 | " return x * pow(x, y-1)" 219 | ], 220 | "language": "python", 221 | "outputs": [], 222 | "prompt_number": 8 223 | }, 224 | { 225 | "cell_type": "code", 226 | "collapsed": false, 227 | "input": [ 228 | "print pow(6, 0)\n", 229 | "print pow(6, 1)\n", 230 | "print pow(6, 2)\n", 231 | "print pow(6, 3)" 232 | ], 233 | "language": "python", 234 | "outputs": [ 235 | { 236 | "output_type": "stream", 237 | "stream": "stdout", 238 | "text": [ 239 | "1\n", 240 | "6\n", 241 | "36\n", 242 | "216\n" 243 | ] 244 | } 245 | ], 246 | "prompt_number": 12 247 | }, 248 | { 249 | "cell_type": "markdown", 250 | "source": [ 251 | "Interesting that you can have a function call itself. The most famous is a *factorial*. We usually write a \n", 252 | "\n", 253 | "$5! = 1 \\times 2 \\times 3 \\times 4 \\times 5 = 120$\n", 254 | "\n", 255 | "In other words,\n", 256 | "\n", 257 | "$5! = 5 \\times 4!$\n", 258 | "\n", 259 | "Does this give you an idea how you could make it?\n", 260 | "\n", 261 | "Of course $1! = 1$ and $2! = 1 \\times 2 = 2$ ..." 262 | ] 263 | }, 264 | { 265 | "cell_type": "code", 266 | "collapsed": false, 267 | "input": [ 268 | "def factorial(x):\n", 269 | " if x == 1:\n", 270 | " return 1\n", 271 | " else:\n", 272 | " return x * factorial(x-1)" 273 | ], 274 | "language": "python", 275 | "outputs": [], 276 | "prompt_number": 9 277 | }, 278 | { 279 | "cell_type": "code", 280 | "collapsed": false, 281 | "input": [ 282 | "print factorial(1)\n", 283 | "print factorial(5)\n", 284 | "print factorial(50)" 285 | ], 286 | "language": "python", 287 | "outputs": [ 288 | { 289 | "output_type": "stream", 290 | "stream": "stdout", 291 | "text": [ 292 | "1\n", 293 | "120\n", 294 | "30414093201713378043612608166064768844377641568960512000000000000\n" 295 | ] 296 | } 297 | ], 298 | "prompt_number": 11 299 | }, 300 | { 301 | "cell_type": "heading", 302 | "level": 2, 303 | "source": [ 304 | "Summary" 305 | ] 306 | }, 307 | { 308 | "cell_type": "markdown", 309 | "source": [ 310 | "To summarized, we now know how to write a function and know how those\n", 311 | "functions can call each other, plus, we have built some pretty hairy\n", 312 | "functions. What shall we do next?" 313 | ] 314 | } 315 | ] 316 | } 317 | ] 318 | } -------------------------------------------------------------------------------- /10- Dictionaries.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "10- Dictionaries" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "heading", 12 | "level": 2, 13 | "source": [ 14 | "Dictionaries" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "source": [ 20 | "A dictionary is a book of terms and a definitions. In Python, we can\n", 21 | "make something similar, but instead of storing definitions, we can\n", 22 | "have it hold anything. Let's make a dictionary to hold information\n", 23 | "about a everyone's favorite Pokemon, Pikachu:" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "collapsed": false, 29 | "input": [ 30 | "pikachu = { \"name\": \"Pikachu\",\n", 31 | " \"level\": 5,\n", 32 | " \"hit points\": 40,\n", 33 | " \"type\": \"electric\",\n", 34 | " \"evolves\": _\n", 35 | " }\n", 36 | "\n", 37 | "pokemon(pikachu)" 38 | ], 39 | "language": "python", 40 | "outputs": [], 41 | "prompt_number": 4 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "source": [ 46 | "We begin with a variable called, `pikachu` and it is set to some data\n", 47 | "in *curly braces*. Inside those braces are *pairs* of information with\n", 48 | "a comma separating each pair.\n", 49 | "\n", 50 | "The information pair has two parts, separated by a colon. The first is\n", 51 | "usually a string in quotes, and the second can be any other data type.\n", 52 | "\n", 53 | "Notice the first pair is `\"name\"` and it is set to the string\n", 54 | "`\"Pikachu\"`, and the next pair is `\"level\"`, but it is set to the\n", 55 | "number, 5.\n", 56 | "\n", 57 | "Of course, we have a problem. The `\"evolves\"` entry isn't set. Replace\n", 58 | "the `_` symbol with a string of his evolved form. You know what that\n", 59 | "is, right? Yes, it is `\"Raichu\"`.\n", 60 | "\n", 61 | "Let's do another:" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "collapsed": false, 67 | "input": [ 68 | "bulbasaur = { \"name\": \"Bulbasaur\",\n", 69 | " \"level\": 5,\n", 70 | " \"hit points\": 45,\n", 71 | " \"type\": [ \"grass\", \"poison\" ],\n", 72 | " \"evolves\": _,\n", 73 | " \"friends\": pikachu\n", 74 | " }\n", 75 | "\n", 76 | "pokemon(bulbasaur)" 77 | ], 78 | "language": "python", 79 | "outputs": [], 80 | "prompt_number": 5 81 | }, 82 | { 83 | "cell_type": "markdown", 84 | "source": [ 85 | "The variable, `bulbasaur` has a dictionary that is very similar to\n", 86 | "`pikachu`, but with some differences. First, the `\"type\"` isn't set to\n", 87 | "a string, but to a list with two strings.\n", 88 | "\n", 89 | "Also, the `\"friends\"` is set to the variable, `pikachu`.\n", 90 | "\n", 91 | "But you also need to change the `_` symbol with a string containing\n", 92 | "his evolved form. What does he evolve into? *Tyrannosaur*? *Sinosaur*?\n", 93 | "Oh, that's right, `\"Ivysaur\"`. **Remember** don't delete the comma that follows it, or Python won't know to separate the `\"evolves\"` from the `\"friends\"`!" 94 | ] 95 | }, 96 | { 97 | "cell_type": "heading", 98 | "level": 2, 99 | "source": [ 100 | "Getting the Data" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "source": [ 106 | "We've made the information, but how do we get it? Very similar to how\n", 107 | "we got information from a list, using square brackets:" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "collapsed": false, 113 | "input": [ 114 | "pikachu[\"type\"]" 115 | ], 116 | "language": "python", 117 | "outputs": [ 118 | { 119 | "output_type": "pyout", 120 | "prompt_number": 12, 121 | "text": [ 122 | "'electric'" 123 | ] 124 | } 125 | ], 126 | "prompt_number": 12 127 | }, 128 | { 129 | "cell_type": "markdown", 130 | "source": [ 131 | "Here is an interesting idea. Can we figure out how to get the name of\n", 132 | "Bulbasaur's friend?" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "collapsed": false, 138 | "input": [ 139 | "bulbasaur[\"friends\"][\"name\"]" 140 | ], 141 | "language": "python", 142 | "outputs": [ 143 | { 144 | "output_type": "pyout", 145 | "prompt_number": 14, 146 | "text": [ 147 | "'Pikachu'" 148 | ] 149 | } 150 | ], 151 | "prompt_number": 14 152 | }, 153 | { 154 | "cell_type": "markdown", 155 | "source": [ 156 | "Think of it in two parts. First, we ask for `bulbasaur[\"friends\"]`\n", 157 | "which will give us the `pikachu` variable. We can then ask that\n", 158 | "variable for its `[\"name\"]` to give us the string, `\"Pikachu\"`." 159 | ] 160 | }, 161 | { 162 | "cell_type": "heading", 163 | "level": 2, 164 | "source": [ 165 | "Setting some Data" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "source": [ 171 | "But what if we forgot something? While Bulbasaur has a friend in\n", 172 | "Pikachu, the relationship isn't mutual, since Pikachu doesn't seem to\n", 173 | "be friends with Bulbasaur:" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "collapsed": false, 179 | "input": [ 180 | "pikachu[\"friends\"][\"name\"]" 181 | ], 182 | "language": "python", 183 | "outputs": [ 184 | { 185 | "ename": "KeyError", 186 | "evalue": "'friends'", 187 | "output_type": "pyerr", 188 | "traceback": [ 189 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mKeyError\u001b[0m Traceback (most recent call last)", 190 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpikachu\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"friends\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"name\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 191 | "\u001b[0;31mKeyError\u001b[0m: 'friends'" 192 | ] 193 | } 194 | ], 195 | "prompt_number": 15 196 | }, 197 | { 198 | "cell_type": "markdown", 199 | "source": [ 200 | "How would you set it? By this time, you could probably guess. Replace the `_` symbol lin the code below with a string containing Pikachu's owner. What was his name again? *Ash Ketchup*? Perhaps it was *Ash Ketchum*..." 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "collapsed": false, 206 | "input": [ 207 | "pikachu[\"owner\"] = _\n", 208 | "pikachu[\"friends\"] = bulbasaur" 209 | ], 210 | "language": "python", 211 | "outputs": [], 212 | "prompt_number": 17 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "source": [ 217 | "Now, we can ask for Pikachu's friends:" 218 | ] 219 | }, 220 | { 221 | "cell_type": "code", 222 | "collapsed": false, 223 | "input": [ 224 | "pikachu[\"friends\"][\"name\"]" 225 | ], 226 | "language": "python", 227 | "outputs": [ 228 | { 229 | "output_type": "pyout", 230 | "prompt_number": 18, 231 | "text": [ 232 | "'Bulbasaur'" 233 | ] 234 | } 235 | ], 236 | "prompt_number": 18 237 | }, 238 | { 239 | "cell_type": "markdown", 240 | "source": [ 241 | "Let's make one more so that we can play around. What is Charmander's\n", 242 | "type? Replace the `_` symbol with a string containing his type:" 243 | ] 244 | }, 245 | { 246 | "cell_type": "code", 247 | "collapsed": false, 248 | "input": [ 249 | "charmander = { \"name\": \"Charmander\",\n", 250 | " \"level\": 6,\n", 251 | " \"hit points\": 39,\n", 252 | " \"type\": _,\n", 253 | " \"evolves\": \"Charmeleon\",\n", 254 | " \"friends\": [ pikachu, bulbasaur ]\n", 255 | " }\n", 256 | "\n", 257 | "pokemon(charmander)" 258 | ], 259 | "language": "python", 260 | "outputs": [], 261 | "prompt_number": 6 262 | }, 263 | { 264 | "cell_type": "markdown", 265 | "source": [ 266 | "How will we show Charmander's friends? If we use the same code that we\n", 267 | "did before, we will get an error:" 268 | ] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "collapsed": false, 273 | "input": [ 274 | "charmander[\"friends\"][\"name\"]" 275 | ], 276 | "language": "python", 277 | "outputs": [ 278 | { 279 | "ename": "TypeError", 280 | "evalue": "list indices must be integers, not str", 281 | "output_type": "pyerr", 282 | "traceback": [ 283 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 284 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcharmander\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"friends\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"name\"\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 285 | "\u001b[0;31mTypeError\u001b[0m: list indices must be integers, not str" 286 | ] 287 | } 288 | ], 289 | "prompt_number": 20 290 | }, 291 | { 292 | "cell_type": "markdown", 293 | "source": [ 294 | "We really need to ask for the name of either his first or second friend:" 295 | ] 296 | }, 297 | { 298 | "cell_type": "code", 299 | "collapsed": false, 300 | "input": [ 301 | "charmander[\"friends\"][1][\"name\"]" 302 | ], 303 | "language": "python", 304 | "outputs": [ 305 | { 306 | "output_type": "pyout", 307 | "prompt_number": 21, 308 | "text": [ 309 | "'Bulbasaur'" 310 | ] 311 | } 312 | ], 313 | "prompt_number": 21 314 | }, 315 | { 316 | "cell_type": "markdown", 317 | "source": [ 318 | "Let's create a function that will print the name of any of our Pokemon's friends.\n", 319 | "\n", 320 | "We want to have a test to see if a pokemon has one friend or more than one friend.\n", 321 | "So what should the `_` be?" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "collapsed": true, 327 | "input": [ 328 | "def friends(pokemon):\n", 329 | " if _:\n", 330 | " for friend in pokemon[\"friends\"]:\n", 331 | " print friend[\"name\"]\n", 332 | " else:\n", 333 | " print pokemon[\"friends\"][\"name\"]\n", 334 | "\n", 335 | "print \"Pikachu is friends with:\"\n", 336 | "friends(pikachu)\n", 337 | "\n", 338 | "print \"Charmander is friends with:\"\n", 339 | "friends(charmander)" 340 | ], 341 | "language": "python", 342 | "outputs": [ 343 | { 344 | "output_type": "stream", 345 | "stream": "stdout", 346 | "text": [ 347 | "Pikachu is friends with:\n", 348 | "Bulbasaur\n", 349 | "Charmander is friends with:\n", 350 | "Pikachu\n", 351 | "Bulbasaur\n" 352 | ] 353 | } 354 | ], 355 | "prompt_number": 23 356 | }, 357 | { 358 | "cell_type": "markdown", 359 | "source": [ 360 | "We could use the `len` function:\n", 361 | "\n", 362 | " len( pokemon[\"friends\"] ) > 1\n", 363 | "\n", 364 | "Since when we ask for Charmander's friends, we get 2:" 365 | ] 366 | }, 367 | { 368 | "cell_type": "code", 369 | "collapsed": false, 370 | "input": [ 371 | "len( charmander[\"friends\"] )" 372 | ], 373 | "language": "python", 374 | "outputs": [ 375 | { 376 | "output_type": "pyout", 377 | "prompt_number": 25, 378 | "text": [ 379 | "2" 380 | ] 381 | } 382 | ], 383 | "prompt_number": 25 384 | }, 385 | { 386 | "cell_type": "markdown", 387 | "source": [ 388 | "But this isn't *quite* what we want. Run this code to see how many\n", 389 | "friends Pikachu has, and it won't be 1:" 390 | ] 391 | }, 392 | { 393 | "cell_type": "code", 394 | "collapsed": false, 395 | "input": [ 396 | "len( pikachu[\"friends\"] )" 397 | ], 398 | "language": "python", 399 | "outputs": [ 400 | { 401 | "output_type": "pyout", 402 | "prompt_number": 24, 403 | "text": [ 404 | "6" 405 | ] 406 | } 407 | ], 408 | "prompt_number": 24 409 | }, 410 | { 411 | "cell_type": "markdown", 412 | "source": [ 413 | "Wait!? How does Pikachu have 6 friends? His only friend (at least according to the data we set above) is Bulbasaur.\n", 414 | "\n", 415 | "Put on your engineer hat, and let's see if we can solve this problem.\n", 416 | "\n", 417 | "What is `pikachu[\"friends\"]`? It points to our `bulbasaur` dictionary.\n", 418 | "Try printing out the `bulbasaur` dictionary:" 419 | ] 420 | }, 421 | { 422 | "cell_type": "code", 423 | "collapsed": false, 424 | "input": [ 425 | "bulbasaur" 426 | ], 427 | "language": "python", 428 | "outputs": [ 429 | { 430 | "output_type": "pyout", 431 | "prompt_number": 27, 432 | "text": [ 433 | "{'evolves': '',\n", 434 | " 'friends': {'evolves': '',\n", 435 | " 'friends': {...},\n", 436 | " 'hit points': 40,\n", 437 | " 'level': 5,\n", 438 | " 'name': 'Pikachu',\n", 439 | " 'owner': 'Ash',\n", 440 | " 'type': 'electric'},\n", 441 | " 'hit points': 45,\n", 442 | " 'level': 5,\n", 443 | " 'name': 'Bulbasaur',\n", 444 | " 'type': ['grass', 'poison']}" 445 | ] 446 | } 447 | ], 448 | "prompt_number": 27 449 | }, 450 | { 451 | "cell_type": "markdown", 452 | "source": [ 453 | "Hrm. Wait a minute. How many entries does Bulbasaur have?\n", 454 | "\n", 455 | " * 'evolves'\n", 456 | " * 'friends'\n", 457 | " * 'hit points'\n", 458 | " * 'level'\n", 459 | " * 'name'\n", 460 | " * 'type'\n", 461 | "\n", 462 | "It has 6! That is where that number is coming from. The `len` function\n", 463 | "will try to count anything. For instance:" 464 | ] 465 | }, 466 | { 467 | "cell_type": "code", 468 | "collapsed": false, 469 | "input": [ 470 | "print len( \"hello\")\n", 471 | "print len( [ 1, 2, 3 ])\n", 472 | "print len( { \"a\": 1, \"b\": 2 } )" 473 | ], 474 | "language": "python", 475 | "outputs": [ 476 | { 477 | "output_type": "stream", 478 | "stream": "stdout", 479 | "text": [ 480 | "5\n", 481 | "3\n", 482 | "2\n" 483 | ] 484 | } 485 | ], 486 | "prompt_number": 29 487 | }, 488 | { 489 | "cell_type": "markdown", 490 | "source": [ 491 | "Instead of greater than 1, we could actually check for 2 friends:\n", 492 | "\n", 493 | " if len( pokemon[\"friends\"] ) == 2:\n", 494 | "\n", 495 | "But that means that our Pokemon can only have 1 or 2 friends. That\n", 496 | "wouldn't really work for really popular Pokemon that everyone invites\n", 497 | "to their Pokeball Parties (like Ghastly).\n", 498 | "\n", 499 | "We need a better way.\n", 500 | "\n", 501 | "We use the `isinstance` function. It works like this:" 502 | ] 503 | }, 504 | { 505 | "cell_type": "code", 506 | "collapsed": false, 507 | "input": [ 508 | "isinstance( [ 1, 2, 3 ], list )" 509 | ], 510 | "language": "python", 511 | "outputs": [ 512 | { 513 | "output_type": "pyout", 514 | "prompt_number": 30, 515 | "text": [ 516 | "True" 517 | ] 518 | } 519 | ], 520 | "prompt_number": 30 521 | }, 522 | { 523 | "cell_type": "markdown", 524 | "source": [ 525 | "In the cell below, change the `_` symbol with `list`:" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "collapsed": false, 531 | "input": [ 532 | "def friends(pokemon):\n", 533 | " if isinstance(pokemon[\"friends\"], _):\n", 534 | " for friend in pokemon[\"friends\"]:\n", 535 | " print friend[\"name\"]\n", 536 | " else:\n", 537 | " print pokemon[\"friends\"][\"name\"]\n", 538 | "\n", 539 | "print \"Pikachu is friends with:\"\n", 540 | "friends(pikachu)\n", 541 | "\n", 542 | "print \"Charmander is friends with:\"\n", 543 | "friends(charmander)" 544 | ], 545 | "language": "python", 546 | "outputs": [ 547 | { 548 | "output_type": "stream", 549 | "stream": "stdout", 550 | "text": [ 551 | "Pikachu is friends with:\n", 552 | "Bulbasaur\n", 553 | "Charmander is friends with:\n", 554 | "Pikachu\n", 555 | "Bulbasaur\n" 556 | ] 557 | } 558 | ], 559 | "prompt_number": 31 560 | }, 561 | { 562 | "cell_type": "markdown", 563 | "source": [ 564 | "I have two points in showing you all of this.\n", 565 | "\n", 566 | "First, a dictionary can store anything, but you need to be sure what\n", 567 | "kind of data will come back.\n", 568 | "\n", 569 | "Second, I wanted to show you how an engineer thinks when he or she\n", 570 | "runs into a problem. We solve problems all day long. If you think\n", 571 | "solving problems is a game, then maybe you might consider a career as\n", 572 | "a professional geek.\n", 573 | "\n", 574 | "In our next lesson, we'll use dictionaries and lists to make our games\n", 575 | "a bit more interesting." 576 | ] 577 | } 578 | ] 579 | } 580 | ] 581 | } -------------------------------------------------------------------------------- /Animal Guessing Game.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "metadata": { 3 | "name": "Animal Guessing Game" 4 | }, 5 | "nbformat": 3, 6 | "nbformat_minor": 0, 7 | "worksheets": [ 8 | { 9 | "cells": [ 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "This notebook is special because it contains a complete game... at\n", 15 | "least, it will when you've finished it. This will use all of the Python you've learned in lessons 1 - 10." 16 | ] 17 | }, 18 | { 19 | "cell_type": "heading", 20 | "level": 2, 21 | "metadata": {}, 22 | "source": [ 23 | "Introduction" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "But what does this game do? This is a game where you, as a player,\n", 31 | "think of an animal, and the computer will ask questions to try and\n", 32 | "guess what you are thinking. It will look something like:" 33 | ] 34 | }, 35 | { 36 | "cell_type": "raw", 37 | "metadata": {}, 38 | "source": [ 39 | "Think of an animal. Would you like me to guess it? Yes\n", 40 | "Does the animal you are thinking have four legs? y\n", 41 | "Is your animal large and gray? no\n", 42 | "Is your animal an a cow? yeah\n", 43 | "Yay! I guessed it!" 44 | ] 45 | }, 46 | { 47 | "cell_type": "heading", 48 | "level": 2, 49 | "metadata": {}, 50 | "source": [ 51 | "Initial Data" 52 | ] 53 | }, 54 | { 55 | "cell_type": "markdown", 56 | "metadata": {}, 57 | "source": [ 58 | "Before we can go anywhere, we need to set up the initial questions for\n", 59 | "our animals. We will use a dictionary that forms a *tree* of\n", 60 | "questions. What do I mean by that?\n", 61 | "\n", 62 | "Maybe it would be good for me to draw a picture:\n", 63 | "\n", 64 | "![Initial Data Structure](/files/animal-guesser-tree-1.png)" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "Did I call this a tree? Looks more like an upside-down tree, huh?\n", 72 | "Whatever we call it, we can start at the top, and work our way down\n", 73 | "the arrows to the bottom.\n", 74 | "\n", 75 | "Let's suppose we are thinking of Bessy, our favorite cow on Grandpa's\n", 76 | "farm. We start at the top and answer the question in the square, \"Does\n", 77 | "our animal have 4 legs?\"\n", 78 | "Bessy does have 4 legs, so we follow the arrow labeled *Yes* and get\n", 79 | "to another square, and ask the question, \"Is our animal large and\n", 80 | "gray?\"\n", 81 | "\n", 82 | "Bessie seems large, but she is black and white, so we follow the arrow\n", 83 | "that says, \"No\". This brings us to an oval shape with the name of an\n", 84 | "animal, \"Cow\". This is the answer, so we end the game.\n", 85 | "\n", 86 | "---------------------------------------------------------------------------\n", 87 | "\n", 88 | "Let's play this game again, but this time, we are thinking of an\n", 89 | "octopus. At the top, we answer the question of \"4 Legs?\" by following\n", 90 | "the \"No\" arrow down to the oval that reads \"Fish\".\n", 91 | "\n", 92 | "But we weren't thinking of a fish. This means, we need a *new branch*\n", 93 | "that has a question to distinguish a fish and an octopus.\n", 94 | "\n", 95 | "![Initial Data Structure](/files/animal-guesser-tree-2.png)" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "This new branch needs to *replace* the `Fish` oval, so that our new\n", 103 | "tree... er, upside-down tree now looks more like a pyramid:\n", 104 | "\n", 105 | "![Initial Data Structure](/files/animal-guesser-tree-3.png)" 106 | ] 107 | }, 108 | { 109 | "cell_type": "markdown", 110 | "metadata": {}, 111 | "source": [ 112 | "Does this make sense? Let's try to make our initial tree using a\n", 113 | "dictionary called `animals`.\n", 114 | "\n", 115 | "Each \"square\" (in our diagrams above) will have three parts:\n", 116 | "\n", 117 | " * **question** will hold the question we can ask.\n", 118 | " * **yes** will either point to an animal or another branch\n", 119 | " * **no** will either point to an animal or another branch" 120 | ] 121 | }, 122 | { 123 | "cell_type": "code", 124 | "collapsed": false, 125 | "input": [ 126 | "animals = {\n", 127 | " \"question\": \"Does the animal you are thinking have four legs?\",\n", 128 | " \"no\": \"fish\",\n", 129 | " \"yes\": {\n", 130 | " \"question\": \"Is your animal large and gray?\",\n", 131 | " \"yes\": \"elephant\",\n", 132 | " \"no\": \"cow\"\n", 133 | " }\n", 134 | "}" 135 | ], 136 | "language": "python", 137 | "metadata": {}, 138 | "outputs": [], 139 | "prompt_number": 1 140 | }, 141 | { 142 | "cell_type": "markdown", 143 | "metadata": {}, 144 | "source": [ 145 | "If the player says *no* to our first question, we end up with a\n", 146 | "`fish`. If the `fish` isn't correct, we will replace it with a new\n", 147 | "branch. That branch will have a question, the new animal, and the\n", 148 | "`fish`.\n", 149 | "\n", 150 | "You can see this \"sub branch\" with `\"yes\"`, as it contains another\n", 151 | "dictionary. Now that you know how we will keep track of our questions, let's get on with the game." 152 | ] 153 | }, 154 | { 155 | "cell_type": "heading", 156 | "level": 2, 157 | "metadata": {}, 158 | "source": [ 159 | "Play the Game!" 160 | ] 161 | }, 162 | { 163 | "cell_type": "markdown", 164 | "metadata": {}, 165 | "source": [ 166 | "We will play our game by calling the `playGame` function.\n", 167 | "\n", 168 | "This function has two jobs:\n", 169 | "\n", 170 | " * First, it will begin with some instructions. Feel free to help\n", 171 | " your player know how to use our program.\n", 172 | "\n", 173 | " * Second, we ask the player if they want to play another round in\n", 174 | " our game." 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "collapsed": false, 180 | "input": [ 181 | "def playGame():\n", 182 | " print \"\"\"Hi! I'm an animal guesser. \n", 183 | " \n", 184 | "I will ask questions and try to guess what animal you are thinking.\n", 185 | "Think of an animal. Got it in your head? Good!\n", 186 | "\"\"\"\n", 187 | " \n", 188 | " while askYesNo(\"Would you like me to guess?\"):\n", 189 | " walkTree(animals) # playRound(animals)" 190 | ], 191 | "language": "python", 192 | "metadata": {}, 193 | "outputs": [], 194 | "prompt_number": 2 195 | }, 196 | { 197 | "cell_type": "markdown", 198 | "metadata": {}, 199 | "source": [ 200 | "The `playGame` function calls two other functions that we'll need to\n", 201 | "make, `askYesNo` and `walkTree`. The `askYesNo` function returns\n", 202 | "`True` if our player types in \"Yes\", and as long as they keep typing\n", 203 | "in \"Yes\" to this question, we'll keep calling `walkTree`." 204 | ] 205 | }, 206 | { 207 | "cell_type": "heading", 208 | "level": 2, 209 | "metadata": {}, 210 | "source": [ 211 | "Play a Round by Walking the Tree" 212 | ] 213 | }, 214 | { 215 | "cell_type": "markdown", 216 | "metadata": {}, 217 | "source": [ 218 | "Playing a round means we start at the top of our dictionary, and walk\n", 219 | "down the tree to the bottom when we get to an animal.\n", 220 | "\n", 221 | "Since the tree is really just a lot of little branches, we could start\n", 222 | "at any branch, ask its question, and then move down from there. And if\n", 223 | "we pass in `animals` as the branch (that is, the top of the tree), we\n", 224 | "will play an entire game round. So, this function takes a `branch` as\n", 225 | "a parameter.\n", 226 | "\n", 227 | "Given a branch, we use the `askYesNo` function with the question pinned to that branch. That gives us the *direction* (the lower branch) we need to follow. We store this new branch in the `newBranch` variable.\n", 228 | "\n", 229 | "If this branch ends on an animal, we call `endGame`, otherwise, we call the\n", 230 | "`walkTree` function again, with the lower branch. Makes sense, right?" 231 | ] 232 | }, 233 | { 234 | "cell_type": "code", 235 | "collapsed": false, 236 | "input": [ 237 | "def walkTree(branch):\n", 238 | " # Since we are currently at a branch, we can ask its question.\n", 239 | " direction = askYesNo( branch[\"question\"] )\n", 240 | " newBranch = lowerBranch(branch, direction)\n", 241 | "\n", 242 | " # If answer to our question is not an animal, then we have another\n", 243 | " # branch, and we just recall this function with the new branch:\n", 244 | " # Otherwise, we end the game.\n", 245 | "\n", 246 | " if foundAnimal(newBranch):\n", 247 | " endGame(newBranch, branch, direction)\n", 248 | " else:\n", 249 | " walkTree(newBranch)" 250 | ], 251 | "language": "python", 252 | "metadata": {}, 253 | "outputs": [], 254 | "prompt_number": 3 255 | }, 256 | { 257 | "cell_type": "markdown", 258 | "metadata": {}, 259 | "source": [ 260 | "The `walkTree` needs some new functions to help it out. We need:\n", 261 | "\n", 262 | " * `lowerBranch` to look at the lower branch\n", 263 | " * `foundAnimal` to see if we have found an animal\n", 264 | " * `endGame` to end the round\n", 265 | "\n", 266 | "We'll do these in order." 267 | ] 268 | }, 269 | { 270 | "cell_type": "heading", 271 | "level": 2, 272 | "metadata": {}, 273 | "source": [ 274 | "Looking at a Lower Branch" 275 | ] 276 | }, 277 | { 278 | "cell_type": "markdown", 279 | "metadata": {}, 280 | "source": [ 281 | "Moving from branch to branch is called *walking the tree*, so moving\n", 282 | "from one branch to another must be *a step*, right?\n", 283 | "\n", 284 | "If the player answers *yes* to a question, we need to follow the\n", 285 | "`\"yes\"` branch. Which direction we follow is given by the `direction`\n", 286 | "parameter. If `direction` is `True`, we return the branch on the\n", 287 | "`\"yes\"`, and `direction` is `False`, we return the branch on the\n", 288 | "`\"no\"`." 289 | ] 290 | }, 291 | { 292 | "cell_type": "code", 293 | "collapsed": false, 294 | "input": [ 295 | "def lowerBranch(branch, direction):\n", 296 | " if direction:\n", 297 | " return branch[\"yes\"]\n", 298 | " else:\n", 299 | " return branch[\"no\"]" 300 | ], 301 | "language": "python", 302 | "metadata": {}, 303 | "outputs": [], 304 | "prompt_number": 4 305 | }, 306 | { 307 | "cell_type": "markdown", 308 | "metadata": {}, 309 | "source": [ 310 | "To test this function, we can use the top of our `animals` as a\n", 311 | "branch, and see what we end up when we give it a `True` or `False`\n", 312 | "for the `direction`.\n", 313 | "\n", 314 | "Of course, when we start, the `False` direction gives us a\n", 315 | "subbranch. Let's create a variable to this, and then test that to see\n", 316 | "if it ends with either `\"cow\"` or `\"elephant\"`. What this means is\n", 317 | "that if the `lowerBranch` gives us something wrong, then our tests\n", 318 | "will not be right, and we'll be able to fix it." 319 | ] 320 | }, 321 | { 322 | "cell_type": "code", 323 | "collapsed": false, 324 | "input": [ 325 | "assert( lowerBranch(animals, False) == \"fish\" )\n", 326 | " \n", 327 | "subbranch = lowerBranch(animals, True) \n", 328 | "assert( lowerBranch(subbranch, False) == \"cow\")\n", 329 | "assert( lowerBranch(subbranch, True) == \"elephant\")" 330 | ], 331 | "language": "python", 332 | "metadata": {}, 333 | "outputs": [], 334 | "prompt_number": 5 335 | }, 336 | { 337 | "cell_type": "heading", 338 | "level": 3, 339 | "metadata": {}, 340 | "source": [ 341 | "Found an Animal?" 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": {}, 347 | "source": [ 348 | "This little function will make it more clear that we have reached the\n", 349 | "end of the tree and we have bagged ourselves an animal.\n", 350 | "\n", 351 | "This function returns `True` if we have an animal (that is a string\n", 352 | "that has the name of the animal) and `False` if we have another branch\n", 353 | "with a question.\n", 354 | "\n", 355 | "We know we have an animal if the `branch` that we pass in is a\n", 356 | "*string*, and we are on a branch if we have a *dictionary*. \n", 357 | "We use the `isinstance` function that we've seen before to check what we have.\n", 358 | "To check if we have a *dictionary*, we give it the word, `dict`." 359 | ] 360 | }, 361 | { 362 | "cell_type": "code", 363 | "collapsed": false, 364 | "input": [ 365 | "def foundAnimal(branch):\n", 366 | " return not isinstance(branch, dict)" 367 | ], 368 | "language": "python", 369 | "metadata": {}, 370 | "outputs": [], 371 | "prompt_number": 6 372 | }, 373 | { 374 | "cell_type": "markdown", 375 | "metadata": {}, 376 | "source": [ 377 | "To test this function, we really need just need to pass in both types\n", 378 | "of data. Our `animals` variable is a good example of a dictionary we\n", 379 | "can use." 380 | ] 381 | }, 382 | { 383 | "cell_type": "code", 384 | "collapsed": false, 385 | "input": [ 386 | "assert( foundAnimal(\"dog\") )\n", 387 | "assert( not foundAnimal(animals) )" 388 | ], 389 | "language": "python", 390 | "metadata": {}, 391 | "outputs": [], 392 | "prompt_number": 7 393 | }, 394 | { 395 | "cell_type": "heading", 396 | "level": 2, 397 | "metadata": {}, 398 | "source": [ 399 | "Ending a Game Round" 400 | ] 401 | }, 402 | { 403 | "cell_type": "markdown", 404 | "metadata": {}, 405 | "source": [ 406 | "When we call the `endGame` function, we've walk down to the bottom and\n", 407 | "found ourselves with an animal. This animal *may be* what our player\n", 408 | "is thinking, in which case, we've won. Or, the player has a new animal\n", 409 | "for us to learn about." 410 | ] 411 | }, 412 | { 413 | "cell_type": "code", 414 | "collapsed": false, 415 | "input": [ 416 | "def endGame(branch, parent, direction):\n", 417 | " if askYesNo( \"Is your animal \" + showAnimal(branch) + \"?\" ):\n", 418 | " print \"Yay! I guessed it!\"\n", 419 | " else:\n", 420 | " storeNewAnimal(parent, whichSide(direction), branch)" 421 | ], 422 | "language": "python", 423 | "metadata": {}, 424 | "outputs": [], 425 | "prompt_number": 8 426 | }, 427 | { 428 | "cell_type": "markdown", 429 | "metadata": {}, 430 | "source": [ 431 | "This function calls two other functions:\n", 432 | "\n", 433 | " * `showAnimal` will show an animal properly. I'll tell you what I mean in just a minute.\n", 434 | " * `storeNewAnimal` will replace the position of an animal with a new subbranch.\n", 435 | " * `whichSide` will convert a `True` direction into a `\"yes\"` so that we know where to store our new animal.\n", 436 | "\n", 437 | "Let's talk about the `whichSide` function first." 438 | ] 439 | }, 440 | { 441 | "cell_type": "heading", 442 | "level": 2, 443 | "metadata": {}, 444 | "source": [ 445 | "Which Side is it On?" 446 | ] 447 | }, 448 | { 449 | "cell_type": "markdown", 450 | "metadata": {}, 451 | "source": [ 452 | "A helper function changes `True` to the string `\"yes\"` and `False`\n", 453 | "to `\"no\"` string, so that we can we know where to store our new animal." 454 | ] 455 | }, 456 | { 457 | "cell_type": "code", 458 | "collapsed": false, 459 | "input": [ 460 | "def whichSide(yes):\n", 461 | " if yes:\n", 462 | " return \"yes\"\n", 463 | " else:\n", 464 | " return \"no\"" 465 | ], 466 | "language": "python", 467 | "metadata": {}, 468 | "outputs": [] 469 | }, 470 | { 471 | "cell_type": "markdown", 472 | "metadata": {}, 473 | "source": [ 474 | "Let's test our little `whichSide` function:" 475 | ] 476 | }, 477 | { 478 | "cell_type": "code", 479 | "collapsed": false, 480 | "input": [ 481 | "assert( whichSide(True) == \"yes\" )\n", 482 | "assert( whichSide(False) == \"no\" )" 483 | ], 484 | "language": "python", 485 | "metadata": {}, 486 | "outputs": [] 487 | }, 488 | { 489 | "cell_type": "heading", 490 | "level": 2, 491 | "metadata": {}, 492 | "source": [ 493 | "Showing an Animal" 494 | ] 495 | }, 496 | { 497 | "cell_type": "markdown", 498 | "metadata": {}, 499 | "source": [ 500 | "What is the difference between a cow and an octopus? One starts\n", 501 | "with an \"A\" and the other starts with an \"N\" ... get it? \"a cow\"\n", 502 | "and \"aN octopus\"? I guess that is a really bad joke, but if you are\n", 503 | "going to print a sentence in English with the animal word, we need\n", 504 | "to know if we should put a string \"a\" or \"an\" in front of it.\n", 505 | "\n", 506 | "We make a `showAnimal` function that decides which to print." 507 | ] 508 | }, 509 | { 510 | "cell_type": "code", 511 | "collapsed": false, 512 | "input": [ 513 | "def showAnimal(animal):\n", 514 | " t = animal.lower()\n", 515 | " if t.startswith('a') or t.startswith('e') or t.startswith('i') or t.startswith('o') or t.startswith('u'):\n", 516 | " return \"an \" + animal\n", 517 | " else:\n", 518 | " return \"a \" + animal" 519 | ], 520 | "language": "python", 521 | "metadata": {}, 522 | "outputs": [], 523 | "prompt_number": 9 524 | }, 525 | { 526 | "cell_type": "markdown", 527 | "metadata": {}, 528 | "source": [ 529 | "Let's make sure that our function works the way we expect:" 530 | ] 531 | }, 532 | { 533 | "cell_type": "code", 534 | "collapsed": false, 535 | "input": [ 536 | "assert( showAnimal(\"dog\").startswith(\"a \") )\n", 537 | "assert( showAnimal(\"aardvark\").startswith(\"an \") )\n", 538 | "assert( showAnimal(\"elephant\").startswith(\"an \") )\n", 539 | "assert( showAnimal(\"Ichthyosaur\").startswith(\"an \") )\n", 540 | "assert( showAnimal(\"yak\").startswith(\"a \") )\n", 541 | "assert( showAnimal(\"horse\").startswith(\"a \") )" 542 | ], 543 | "language": "python", 544 | "metadata": {}, 545 | "outputs": [], 546 | "prompt_number": 10 547 | }, 548 | { 549 | "cell_type": "heading", 550 | "level": 2, 551 | "metadata": {}, 552 | "source": [ 553 | "Storing a New Animal" 554 | ] 555 | }, 556 | { 557 | "cell_type": "markdown", 558 | "metadata": {}, 559 | "source": [ 560 | "The player was thinking of something that our program doesn't know\n", 561 | "about. No problem. We just need to know the name of this animal,\n", 562 | "and a *question* that the program can ask to distinguish it.\n", 563 | "\n", 564 | "In order to store it back in our `animals` tree... er, pyramid, we\n", 565 | "need to know three things:\n", 566 | "\n", 567 | " * **higherBranch** is the point at the end of the branch where we will store\n", 568 | " * **side** is either \"yes\" or \"no\" and gives us the spot in the\n", 569 | " higher branch to store our *new* branch\n", 570 | " * **oldAnimal** is the text string with the name of the animal we\n", 571 | " thought it might be. We need to move this animal down into our\n", 572 | " new branch." 573 | ] 574 | }, 575 | { 576 | "cell_type": "code", 577 | "collapsed": false, 578 | "input": [ 579 | "def storeNewAnimal(higherBranch, side, oldAnimal):\n", 580 | " print \"Shoot. What animal were you thinking?\"\n", 581 | " newAnimal = raw_input().lower()\n", 582 | " \n", 583 | " print \"What question could I ask to distinguish between\", showAnimal(oldAnimal), \"and\", showAnimal(newAnimal), \"?\"\n", 584 | " newQuestion = raw_input()\n", 585 | " \n", 586 | " higherBranch[side] = {\n", 587 | " \"question\": turnIntoAQuestion(newQuestion),\n", 588 | " \"yes\": newAnimal,\n", 589 | " \"no\": oldAnimal\n", 590 | " }" 591 | ], 592 | "language": "python", 593 | "metadata": {}, 594 | "outputs": [], 595 | "prompt_number": 11 596 | }, 597 | { 598 | "cell_type": "markdown", 599 | "metadata": {}, 600 | "source": [ 601 | "After complaining that we lost, we have to ask our player the name of\n", 602 | "the animal he or she was thinking of. To get let our player type\n", 603 | "something that and then store it, we use the `raw_input`\n", 604 | "function. Whatever is typed, comes back, and we convert it to lower\n", 605 | "case, so `\"Porcupine\"` is assigned to `newAnimal` as `\"porcupine\"`.\n", 606 | "\n", 607 | "Next we ned to get a question that we will store in our new branch to\n", 608 | "decided between the old animal and the new one we are just learning\n", 609 | "about.\n", 610 | "\n", 611 | "To store our new branch, we just set either the `\"yes\"` or `\"no\"` in\n", 612 | "the `higherBranch` to our new dictionary that has the question and\n", 613 | "both animals.\n", 614 | "\n", 615 | "You've seen the `showAnimal` function above, but we need to write a\n", 616 | "helper function called, `turnIntoAQuestion`." 617 | ] 618 | }, 619 | { 620 | "cell_type": "heading", 621 | "level": 3, 622 | "metadata": {}, 623 | "source": [ 624 | "Turning a Statement into a Question" 625 | ] 626 | }, 627 | { 628 | "cell_type": "markdown", 629 | "metadata": {}, 630 | "source": [ 631 | "When we ask the player for a new question, we need to make sure that\n", 632 | "what is given to us, doesn't end with a question mark, we need to add it.\n", 633 | "\n", 634 | "To do this, we use the `endswith` function (which is similar to\n", 635 | "`startswith`, but checks the end of the text string." 636 | ] 637 | }, 638 | { 639 | "cell_type": "code", 640 | "collapsed": false, 641 | "input": [ 642 | "def turnIntoAQuestion(words):\n", 643 | " if words.endswith(\"?\"):\n", 644 | " return words\n", 645 | " else:\n", 646 | " return words + \"?\"\n" 647 | ], 648 | "language": "python", 649 | "metadata": {}, 650 | "outputs": [], 651 | "prompt_number": 12 652 | }, 653 | { 654 | "cell_type": "markdown", 655 | "metadata": {}, 656 | "source": [ 657 | "We can easily test this, right? We just have to make sure that every\n", 658 | "string of text letters we give it, gives us back a string of text that\n", 659 | "ends with a question mark." 660 | ] 661 | }, 662 | { 663 | "cell_type": "code", 664 | "collapsed": false, 665 | "input": [ 666 | "assert( turnIntoAQuestion(\"This isn't a question\").endswith(\"?\") )\n", 667 | "assert( turnIntoAQuestion(\"Is this a question?\").endswith(\"?\") )" 668 | ], 669 | "language": "python", 670 | "metadata": {}, 671 | "outputs": [], 672 | "prompt_number": 13 673 | }, 674 | { 675 | "cell_type": "heading", 676 | "level": 3, 677 | "metadata": {}, 678 | "source": [ 679 | "Yes and No Questions" 680 | ] 681 | }, 682 | { 683 | "cell_type": "markdown", 684 | "metadata": {}, 685 | "source": [ 686 | "Almost all of the questions we ask the player of our game are\n", 687 | "*yes* and *no* questions. However, we want to make sure that if the\n", 688 | "player types \"yes\" or \"y\", or even \"Yes\" (notice the capital) to all\n", 689 | "mean *yes*.\n", 690 | "\n", 691 | "In this `isYes` function, we take the player's `answer` and first\n", 692 | "convert it to lower-case. This turns \"Yes\" into \"yes\" and \"N\" into\n", 693 | "\"n\". We do this to make the comparison easier.\n", 694 | "\n", 695 | "Since \"Yes\" and \"y\" will be the same to our program, we really just\n", 696 | "need to look at the first letter. To do this, we use the `startswith`\n", 697 | "*method*. A method is like a function, but it only works by being\n", 698 | "*attached* to something.\n", 699 | "\n", 700 | "In this function, we can a string of text characters, and attach this\n", 701 | "`lower` method to to, and then attach a `startswith` function to\n", 702 | "that. We end up with `True` if our player types \"Yes\" or \"y\"." 703 | ] 704 | }, 705 | { 706 | "cell_type": "code", 707 | "collapsed": false, 708 | "input": [ 709 | "def isYes(answer):\n", 710 | " if answer.lower().startswith(\"y\"):\n", 711 | " return True\n", 712 | " else:\n", 713 | " return False" 714 | ], 715 | "language": "python", 716 | "metadata": {}, 717 | "outputs": [], 718 | "prompt_number": 14 719 | }, 720 | { 721 | "cell_type": "markdown", 722 | "metadata": {}, 723 | "source": [ 724 | "We can make sure this function works, by making a few calls to `assert`:" 725 | ] 726 | }, 727 | { 728 | "cell_type": "code", 729 | "collapsed": false, 730 | "input": [ 731 | "assert( isYes(\"Yes\") )\n", 732 | "assert( isYes(\"Y\") )\n", 733 | "assert( isYes(\"yes\") )\n", 734 | "assert( isYes(\"y\") )\n", 735 | "assert( not isYes(\"No\") )\n", 736 | "assert( not isYes(\"n\") )" 737 | ], 738 | "language": "python", 739 | "metadata": {}, 740 | "outputs": [], 741 | "prompt_number": 15 742 | }, 743 | { 744 | "cell_type": "markdown", 745 | "metadata": {}, 746 | "source": [ 747 | "We need a function that lets us give it a question that it will show\n", 748 | "to the player, and then allow our player to type in something. Showing\n", 749 | "things are easy, we just use `print`, but how do we get *something*?\n", 750 | "\n", 751 | "Python has a function, `raw_input` that when called, Python stops,\n", 752 | "lets the player type something, and whatever the player types is given\n", 753 | "back to us. We will take that, and give it to our `isYes` function.\n", 754 | "\n", 755 | "This means that the `askYesNo` function will take a string as a\n", 756 | "question, and return either `True` for *yes* and `False` for *No*." 757 | ] 758 | }, 759 | { 760 | "cell_type": "code", 761 | "collapsed": false, 762 | "input": [ 763 | "def askYesNo(question):\n", 764 | " print question,\n", 765 | " return isYes( raw_input() )" 766 | ], 767 | "language": "python", 768 | "metadata": {}, 769 | "outputs": [], 770 | "prompt_number": 16 771 | }, 772 | { 773 | "cell_type": "heading", 774 | "level": 2, 775 | "metadata": {}, 776 | "source": [ 777 | "Finishing Touches" 778 | ] 779 | }, 780 | { 781 | "cell_type": "markdown", 782 | "metadata": {}, 783 | "source": [ 784 | "We have now written all of the functions, including our big function, `playGame`. In fact, all we need to do is just call it:" 785 | ] 786 | }, 787 | { 788 | "cell_type": "code", 789 | "collapsed": true, 790 | "input": [ 791 | "playGame()" 792 | ], 793 | "language": "python", 794 | "metadata": {}, 795 | "outputs": [ 796 | { 797 | "ename": "StdinNotImplementedError", 798 | "evalue": "raw_input was called, but this frontend does not support stdin.", 799 | "output_type": "pyerr", 800 | "traceback": [ 801 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[0;31mStdinNotImplementedError\u001b[0m Traceback (most recent call last)", 802 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mplayGame\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 803 | "\u001b[0;32m\u001b[0m in \u001b[0;36mplayGame\u001b[0;34m()\u001b[0m\n\u001b[1;32m 6\u001b[0m \"\"\"\n\u001b[1;32m 7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 8\u001b[0;31m \u001b[0;32mwhile\u001b[0m \u001b[0maskYesNo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Would you like me to guess?\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 9\u001b[0m \u001b[0mwalkTree\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0manimals\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# playRound(animals)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 804 | "\u001b[0;32m\u001b[0m in \u001b[0;36maskYesNo\u001b[0;34m(question)\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0maskYesNo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mquestion\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mprint\u001b[0m \u001b[0mquestion\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0misYes\u001b[0m\u001b[0;34m(\u001b[0m \u001b[0mraw_input\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 805 | "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/zmq/ipkernel.pyc\u001b[0m in \u001b[0;36m\u001b[0;34m(prompt)\u001b[0m\n\u001b[1;32m 343\u001b[0m \u001b[0mraw_input\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mlambda\u001b[0m \u001b[0mprompt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m''\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_raw_input\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mprompt\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mident\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparent\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 344\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 345\u001b[0;31m \u001b[0mraw_input\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mlambda\u001b[0m \u001b[0mprompt\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m''\u001b[0m \u001b[0;34m:\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0m_no_raw_input\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 346\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 347\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mpy3compat\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mPY3\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 806 | "\u001b[0;32m/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/IPython/zmq/ipkernel.pyc\u001b[0m in \u001b[0;36m_no_raw_input\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 698\u001b[0m \"\"\"Raise StdinNotImplentedError if active frontend doesn't support\n\u001b[1;32m 699\u001b[0m stdin.\"\"\"\n\u001b[0;32m--> 700\u001b[0;31m raise StdinNotImplementedError(\"raw_input was called, but this \"\n\u001b[0m\u001b[1;32m 701\u001b[0m \"frontend does not support stdin.\") \n\u001b[1;32m 702\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 807 | "\u001b[0;31mStdinNotImplementedError\u001b[0m: raw_input was called, but this frontend does not support stdin." 808 | ] 809 | }, 810 | { 811 | "output_type": "stream", 812 | "stream": "stdout", 813 | "text": [ 814 | "Hi! I'm an animal guesser. \n", 815 | " \n", 816 | "I will ask questions and try to guess what animal you are thinking.\n", 817 | "Think of an animal. Got it in your head? Good!\n", 818 | "\n", 819 | "Would you like me to guess?" 820 | ] 821 | } 822 | ], 823 | "prompt_number": 17 824 | }, 825 | { 826 | "cell_type": "markdown", 827 | "metadata": {}, 828 | "source": [ 829 | "If you **Play** that cell, we'll get an error, because in the Notebook, the `raw_input` function doesn't work. What we need to do is make a **Python Program**. Here's what you do:\n", 830 | "\n", 831 | " * Click the **File** menu above.\n", 832 | " * Select **Download As...**\n", 833 | " * Select **Python**.\n", 834 | "\n", 835 | "This will put a file in your `Downloads` folder that you can\n", 836 | "double-click and play! If double-clicking on the file doesn't work, you can open up **Terminal** and run it from there:" 837 | ] 838 | }, 839 | { 840 | "cell_type": "raw", 841 | "metadata": {}, 842 | "source": [ 843 | "$ python \"Animal Guessing Game.py\" \n", 844 | "Hi! I'm an animal guesser. \n", 845 | " \n", 846 | "I will ask questions and try to guess what animal you are thinking.\n", 847 | "Think of an animal. Got it in your head? Good!\n", 848 | "\n", 849 | "Would you like me to guess? You bet!\n", 850 | "Does the animal you are thinking have four legs? yes\n", 851 | "Is your animal large and gray? no\n", 852 | "Is your animal a cow? y\n", 853 | "Yay! I guessed it!\n", 854 | "Would you like me to guess? Yes\n", 855 | "Does the animal you are thinking have four legs? no\n", 856 | "Is your animal a fish? nope\n", 857 | "Shoot. What animal were you thinking?\n", 858 | "Octopus\n", 859 | "What question could I ask to distinguish between a fish and an octopus ?\n", 860 | "Does it have eight legs\n", 861 | "Would you like me to guess? yes\n", 862 | "Does the animal you are thinking have four legs? no\n", 863 | "Does it have eight legs? y\n", 864 | "Is your animal an octopus? y\n", 865 | "Yay! I guessed it!\n", 866 | "Would you like me to guess? no" 867 | ] 868 | } 869 | ], 870 | "metadata": {} 871 | } 872 | ] 873 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Cookies for Python 2 | ================== 3 | 4 | If you are a Geek Parent wanting to teach your kids to program in 5 | [Python][1], then have we got a project for you. **Cookies for 6 | Python** is a project you can use to start the ball rolling (as well 7 | as add to it). 8 | 9 | Once upon a time, [Rob][rob] and [Howard][howard] were talking about 10 | teaching their kids to follow in their footsteps and learn to program. 11 | After [Scratch][1], a scripting language should be next on the list 12 | for kids to learn, but most ways of teaching languages like Python are 13 | geared towards young adults. 14 | 15 | Specifically, we thought the following were important: 16 | 17 | * Instructive but still fun to read 18 | * Interactive 19 | * Gamified (do something right, get a badge... or a cookie) 20 | 21 | This project is our attempt. It is based on the wonderful 22 | [notebook extension][3] to [iPython][4]. You can fork, extend and even 23 | contribute this project to share with others. 24 | 25 | What's it Like? 26 | -------------- 27 | 28 | The easiest way to explain what it looks like is to show a screenshot 29 | from the browser (or download the [first lesson as a PDF](misc/01-output.pdf)): 30 | 31 | ![Cookie Python Screenshot](misc/screenshot.png) 32 | 33 | Installation 34 | ------------ 35 | 36 | Installation is pretty simple. First, get a complete copy of 37 | Python. If the kids are on your iMac upstairs and your a geek, chances 38 | are good you've already installed [Homebrew][5]: 39 | 40 | brew install python 41 | 42 | If you've got a difficult environment, see [these instructions][6]. 43 | 44 | Now that you have either [Pip][7] or [easy_install][8], use one of 45 | them to grab `ipython`: 46 | 47 | pip install pyzmq 48 | pip install tornado 49 | pip install --upgrade ipython 50 | pip install numpy 51 | 52 | Or 53 | 54 | easy_install ipython[zmq,notebook] 55 | 56 | Finally, clone this project, and you're ready. 57 | 58 | Starting 59 | ----- 60 | 61 | The `start-me-up` script can be used to set up the iPython notebook 62 | server and bring up a browser. If it is run a second time, it attempts 63 | to re-connect to the same server (this seemed to be fairly important 64 | as my kids could start it, but didn't stop it, and I had 50 65 | interpreters running once). 66 | 67 | If you create a symbolic link from the Desktop to this script, set the 68 | `COOKIE_PYTHON_HOME` to the directory where the project has been 69 | checked out, and put this in your start up script, 70 | e.g. `.profile`. For example: 71 | 72 | export COOKIE_PYTHON_HOME=$HOME/Documents/cookie-python 73 | 74 | Using 75 | ----- 76 | 77 | Once things are started, it should be clear how to use it. Click on a 78 | lesson, answer the questions and solve the problems, and get a cookie 79 | reward. 80 | 81 | Contributing 82 | ------------ 83 | 84 | This project is intended as a collaborative project between many Geek 85 | Parents, so feel free to fork and submit patches. If you don't have a 86 | lot of time, but would like to contribute, we specifically need help 87 | in the following: 88 | 89 | * Editing of our lessons... we're programmers not writers, and it shows. 90 | * Freely licensed clipart images to use as rewards. 91 | * Python unit tests for our validation code, `check()` 92 | 93 | 94 | [1]: http://www.python.org 95 | [2]: http://scratch.mit.edu/ 96 | [3]: http://ipython.org/notebook.html‎ 97 | [4]: http://ipython.org 98 | [5]: http://www.homebrew.org 99 | [6]: http://ipython.org/ipython-doc/stable/install/install.html 100 | [7]: http://www.pip-installer.org 101 | [8]: http://pythonhosted.org/distribute/easy_install.html 102 | 103 | [howard]: https://github.com/howardabrams 104 | [rob]: https://github.com/robbednark 105 | -------------------------------------------------------------------------------- /animal-guesser-tree-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/cookie-python/e5892bc346a4731f8c5165b27e2fe6cd48b6a2e2/animal-guesser-tree-1.png -------------------------------------------------------------------------------- /animal-guesser-tree-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/cookie-python/e5892bc346a4731f8c5165b27e2fe6cd48b6a2e2/animal-guesser-tree-2.png -------------------------------------------------------------------------------- /animal-guesser-tree-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/cookie-python/e5892bc346a4731f8c5165b27e2fe6cd48b6a2e2/animal-guesser-tree-3.png -------------------------------------------------------------------------------- /animal-guesser.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3.0 3 | 4 | # 5 | 6 | # This notebook is special because it contains a complete game... at 7 | # least, it will when you've finished it. This will use all of the Python you've learned in lessons 1 - 10. 8 | 9 | # 10 | 11 | # Introduction 12 | 13 | # 14 | 15 | # But what does this game do? This is a game where you, as a player, 16 | # think of an animal, and the computer will ask questions to try and 17 | # guess what you are thinking. It will look something like: 18 | 19 | # 20 | 21 | # Think of an animal. Would you like me to guess it? Yes 22 | # Does the animal you are thinking have four legs? y 23 | # Is your animal large and gray? no 24 | # Is your animal an a cow? yeah 25 | # Yay! I guessed it! 26 | 27 | # 28 | 29 | # Initial Data 30 | 31 | # 32 | 33 | # Before we can go anywhere, we need to set up the initial questions for 34 | # our animals. We will use a dictionary that forms a *tree* of 35 | # questions. What do I mean by that? 36 | # 37 | # Maybe it would be good for me to draw a picture: 38 | # 39 | # ![Initial Data Structure](files/animal-guesser-tree-1.png) 40 | 41 | # 42 | 43 | # Did I call this a tree? Looks more like an upside-down tree, huh? 44 | # Whatever we call it, we can start at the top, and work our way down 45 | # the arrows to the bottom. 46 | # 47 | # Let's suppose we are thinking of Bessy, our favorite cow on Grandpa's 48 | # farm. We start at the top and answer the question in the square, "Does 49 | # our animal have 4 legs?" 50 | # Bessy does have 4 legs, so we follow the arrow labeled *Yes* and get 51 | # to another square, and ask the question, "Is our animal large and 52 | # gray?" 53 | # 54 | # Bessie seems large, but she is black and white, so we follow the arrow 55 | # that says, "No". This brings us to an oval shape with the name of an 56 | # animal, "Cow". This is the answer, so we end the game. 57 | # 58 | # --------------------------------------------------------------------------- 59 | # 60 | # Let's play this game again, but this time, we are thinking of an 61 | # octopus. At the top, we answer the question of "4 Legs?" by following 62 | # the "No" arrow down to the oval that reads "Fish". 63 | # 64 | # But we weren't thinking of a fish. This means, we need a *new branch* 65 | # that has a question to distinguish a fish and an octopus. 66 | # 67 | # ![Initial Data Structure](files/animal-guesser-tree-2.png) 68 | 69 | # 70 | 71 | # This new branch needs to *replace* the `Fish` oval, so that our new 72 | # tree... er, upside-down tree now looks more like a pyramid: 73 | # 74 | # ![Initial Data Structure](files/animal-guesser-tree-3.png) 75 | 76 | # 77 | 78 | # Does this make sense? Let's try to make our initial tree using a 79 | # dictionary called `animals`. 80 | # 81 | # Each "square" (in our diagrams above) will have three parts: 82 | # 83 | # * **question** will hold the question we can ask. 84 | # * **yes** will either point to an animal or another branch 85 | # * **no** will either point to an animal or another branch 86 | 87 | # 88 | 89 | animals = { 90 | "question": "Does the animal you are thinking have four legs?", 91 | "no": "fish", 92 | "yes": { 93 | "question": "Is your animal large and gray?", 94 | "yes": "elephant", 95 | "no": "cow" 96 | } 97 | } 98 | 99 | # 100 | 101 | # If the player says *no* to our first question, we end up with a 102 | # `fish`. If the `fish` isn't correct, we will replace it with a new 103 | # branch. That branch will have a question, the new animal, and the 104 | # `fish`. 105 | # 106 | # You can see this "sub branch" with `"yes"`, as it contains another 107 | # dictionary. Now that you know how we will keep track of our questions, let's get on with the game. 108 | 109 | # 110 | 111 | # Play the Game! 112 | 113 | # 114 | 115 | # We will play our game by calling the `playGame` function. 116 | # 117 | # This function has two jobs: 118 | # 119 | # * First, it will begin with some instructions. Feel free to help 120 | # your player know how to use our program. 121 | # 122 | # * Second, we ask the player if they want to play another round in 123 | # our game. 124 | 125 | # 126 | 127 | def playGame(): 128 | print """Hi! I'm an animal guesser. 129 | 130 | I will ask questions and try to guess what animal you are thinking. 131 | Think of an animal. Got it in your head? Good! 132 | """ 133 | 134 | prompt = "Would you like me to guess your animal?" 135 | while askYesNo(prompt): 136 | walkTree(animals) # playRound(animals) 137 | prompt = "Would you like to play again and I'll guess another animal?" 138 | 139 | # 140 | 141 | # The `playGame` function calls two other functions that we'll need to 142 | # make, `askYesNo` and `walkTree`. The `askYesNo` function returns 143 | # `True` if our player types in "Yes", and as long as they keep typing 144 | # in "Yes" to this question, we'll keep calling `walkTree`. 145 | 146 | # 147 | 148 | # Play a Round by Walking the Tree 149 | 150 | # 151 | 152 | # Playing a round means we start at the top of our dictionary, and walk 153 | # down the tree to the bottom when we get to an animal. 154 | # 155 | # Since the tree is really just a lot of little branches, we could start 156 | # at any branch, ask its question, and then move down from there. And if 157 | # we pass in `animals` as the branch (that is, the top of the tree), we 158 | # will play an entire game round. So, this function takes a `branch` as 159 | # a parameter. 160 | # 161 | # Given a branch, we use the `askYesNo` function with the question pinned to that branch. That gives us the *direction* (the lower branch) we need to follow. We store this new branch in the `newBranch` variable. 162 | # 163 | # If this branch ends on an animal, we call `endGame`, otherwise, we call the 164 | # `walkTree` function again, with the lower branch. Makes sense, right? 165 | 166 | # 167 | 168 | def walkTree(branch): 169 | # Since we are currently at a branch, we can ask its question. 170 | direction = askYesNo( branch["question"] ) 171 | newBranch = lowerBranch(branch, direction) 172 | 173 | # If answer to our question is not an animal, then we have another 174 | # branch, and we just recall this function with the new branch: 175 | # Otherwise, we end the game. 176 | 177 | if foundAnimal(newBranch): 178 | endGame(newBranch, branch, direction) 179 | else: 180 | walkTree(newBranch) 181 | 182 | # 183 | 184 | # The `walkTree` needs some new functions to help it out. We need: 185 | # 186 | # * `lowerBranch` to look at the lower branch 187 | # * `foundAnimal` to see if we have found an animal 188 | # * `endGame` to end the round 189 | # 190 | # We'll do these in order. 191 | 192 | # 193 | 194 | # Looking at a Lower Branch 195 | 196 | # 197 | 198 | # Moving from branch to branch is called *walking the tree*, so moving 199 | # from one branch to another must be *a step*, right? 200 | # 201 | # If the player answers *yes* to a question, we need to follow the 202 | # `"yes"` branch. Which direction we follow is given by the `direction` 203 | # parameter. If `direction` is `True`, we return the branch on the 204 | # `"yes"`, and `direction` is `False`, we return the branch on the 205 | # `"no"`. 206 | 207 | # 208 | 209 | def lowerBranch(branch, direction): 210 | if direction: 211 | return branch["yes"] 212 | else: 213 | return branch["no"] 214 | 215 | # 216 | 217 | # To test this function, we can use the top of our `animals` as a 218 | # branch, and see what we end up when we give it a `True` or `False` 219 | # for the `direction`. 220 | # 221 | # Of course, when we start, the `False` direction gives us a 222 | # subbranch. Let's create a variable to this, and then test that to see 223 | # if it ends with either `"cow"` or `"elephant"`. What this means is 224 | # that if the `lowerBranch` gives us something wrong, then our tests 225 | # will not be right, and we'll be able to fix it. 226 | 227 | # 228 | 229 | assert( lowerBranch(animals, False) == "fish" ) 230 | 231 | subbranch = lowerBranch(animals, True) 232 | assert( lowerBranch(subbranch, False) == "cow") 233 | assert( lowerBranch(subbranch, True) == "elephant") 234 | 235 | # 236 | 237 | # Found an Animal? 238 | 239 | # 240 | 241 | # This little function will make it more clear that we have reached the 242 | # end of the tree and we have bagged ourselves an animal. 243 | # 244 | # This function returns `True` if we have an animal (that is a string 245 | # that has the name of the animal) and `False` if we have another branch 246 | # with a question. 247 | # 248 | # We know we have an animal if the `branch` that we pass in is a 249 | # *string*, and we are on a branch if we have a *dictionary*. 250 | # We use the `isinstance` function that we've seen before to check what we have. 251 | # To check if we have a *dictionary*, we give it the word, `dict`. 252 | 253 | # 254 | 255 | def foundAnimal(branch): 256 | return not isinstance(branch, dict) 257 | 258 | # 259 | 260 | # To test this function, we really need just need to pass in both types 261 | # of data. Our `animals` variable is a good example of a dictionary we 262 | # can use. 263 | 264 | # 265 | 266 | assert( foundAnimal("dog") ) 267 | assert( not foundAnimal(animals) ) 268 | 269 | # 270 | 271 | # Ending a Game Round 272 | 273 | # 274 | 275 | # When we call the `endGame` function, we've walk down to the bottom and 276 | # found ourselves with an animal. This animal *may be* what our player 277 | # is thinking, in which case, we've won. Or, the player has a new animal 278 | # for us to learn about. 279 | 280 | # 281 | 282 | def endGame(branch, parent, direction): 283 | if askYesNo( "Is your animal " + showAnimal(branch) + "?" ): 284 | print "Yay! I guessed it!" 285 | else: 286 | storeNewAnimal(parent, whichSide(direction), branch) 287 | 288 | # 289 | 290 | # This function calls two other functions: 291 | # 292 | # * `showAnimal` will show an animal properly. I'll tell you what I mean in just a minute. 293 | # * `storeNewAnimal` will replace the position of an animal with a new subbranch. 294 | # * `whichSide` will convert a `True` direction into a `"yes"` so that we know where to store our new animal. 295 | # 296 | # Let's talk about the `whichSide` function first. 297 | 298 | # 299 | 300 | # Which Side is it On? 301 | 302 | # 303 | 304 | # A helper function changes `True` to the string `"yes"` and `False` 305 | # to `"no"` string, so that we can we know where to store our new animal. 306 | 307 | # 308 | 309 | def whichSide(yes): 310 | if yes: 311 | return "yes" 312 | else: 313 | return "no" 314 | 315 | # 316 | 317 | # Let's test our little `whichSide` function: 318 | 319 | # 320 | 321 | assert( whichSide(True) == "yes" ) 322 | assert( whichSide(False) == "no" ) 323 | 324 | # 325 | 326 | # Showing an Animal 327 | 328 | # 329 | 330 | # What is the difference between a cow and an octopus? One starts 331 | # with an "A" and the other starts with an "N" ... get it? "a cow" 332 | # and "aN octopus"? I guess that is a really bad joke, but if you are 333 | # going to print a sentence in English with the animal word, we need 334 | # to know if we should put a string "a" or "an" in front of it. 335 | # 336 | # We make a `showAnimal` function that decides which to print. 337 | 338 | # 339 | 340 | def showAnimal(animal): 341 | t = animal.lower() 342 | if t.startswith('a') or t.startswith('e') or t.startswith('i') or t.startswith('o') or t.startswith('u'): 343 | return "an " + animal 344 | else: 345 | return "a " + animal 346 | 347 | # 348 | 349 | # Let's make sure that our function works the way we expect: 350 | 351 | # 352 | 353 | assert( showAnimal("dog").startswith("a ") ) 354 | assert( showAnimal("aardvark").startswith("an ") ) 355 | assert( showAnimal("elephant").startswith("an ") ) 356 | assert( showAnimal("Ichthyosaur").startswith("an ") ) 357 | assert( showAnimal("yak").startswith("a ") ) 358 | assert( showAnimal("horse").startswith("a ") ) 359 | 360 | # 361 | 362 | # Storing a New Animal 363 | 364 | # 365 | 366 | # The player was thinking of something that our program doesn't know 367 | # about. No problem. We just need to know the name of this animal, 368 | # and a *question* that the program can ask to distinguish it. 369 | # 370 | # In order to store it back in our `animals` tree... er, pyramid, we 371 | # need to know three things: 372 | # 373 | # * **higherBranch** is the point at the end of the branch where we will store 374 | # * **side** is either "yes" or "no" and gives us the spot in the 375 | # higher branch to store our *new* branch 376 | # * **oldAnimal** is the text string with the name of the animal we 377 | # thought it might be. We need to move this animal down into our 378 | # new branch. 379 | 380 | # 381 | 382 | def storeNewAnimal(higherBranch, side, oldAnimal): 383 | print "Shoot. What animal were you thinking?" 384 | newAnimal = raw_input().lower() 385 | 386 | print "What question could I ask to distinguish between", showAnimal(oldAnimal), "and", showAnimal(newAnimal), "?" 387 | newQuestion = raw_input() 388 | 389 | higherBranch[side] = { 390 | "question": turnIntoAQuestion(newQuestion), 391 | "yes": newAnimal, 392 | "no": oldAnimal 393 | } 394 | 395 | # 396 | 397 | # After complaining that we lost, we have to ask our player the name of 398 | # the animal he or she was thinking of. To get let our player type 399 | # something that and then store it, we use the `raw_input` 400 | # function. Whatever is typed, comes back, and we convert it to lower 401 | # case, so `"Porcupine"` is assigned to `newAnimal` as `"porcupine"`. 402 | # 403 | # Next we ned to get a question that we will store in our new branch to 404 | # decided between the old animal and the new one we are just learning 405 | # about. 406 | # 407 | # To store our new branch, we just set either the `"yes"` or `"no"` in 408 | # the `higherBranch` to our new dictionary that has the question and 409 | # both animals. 410 | # 411 | # You've seen the `showAnimal` function above, but we need to write a 412 | # helper function called, `turnIntoAQuestion`. 413 | 414 | # 415 | 416 | # Turning a Statement into a Question 417 | 418 | # 419 | 420 | # When we ask the player for a new question, we need to make sure that 421 | # what is given to us, doesn't end with a question mark, we need to add it. 422 | # 423 | # To do this, we use the `endswith` function (which is similar to 424 | # `startswith`, but checks the end of the text string. 425 | 426 | # 427 | 428 | def turnIntoAQuestion(words): 429 | if words.endswith("?"): 430 | return words 431 | else: 432 | return words + "?" 433 | 434 | # 435 | 436 | # We can easily test this, right? We just have to make sure that every 437 | # string of text letters we give it, gives us back a string of text that 438 | # ends with a question mark. 439 | 440 | # 441 | 442 | assert( turnIntoAQuestion("This isn't a question").endswith("?") ) 443 | assert( turnIntoAQuestion("Is this a question?").endswith("?") ) 444 | 445 | # 446 | 447 | # Yes and No Questions 448 | 449 | # 450 | 451 | # Almost all of the questions we ask the player of our game are 452 | # *yes* and *no* questions. However, we want to make sure that if the 453 | # player types "yes" or "y", or even "Yes" (notice the capital) to all 454 | # mean *yes*. 455 | # 456 | # In this `isYes` function, we take the player's `answer` and first 457 | # convert it to lower-case. This turns "Yes" into "yes" and "N" into 458 | # "n". We do this to make the comparison easier. 459 | # 460 | # Since "Yes" and "y" will be the same to our program, we really just 461 | # need to look at the first letter. To do this, we use the `startswith` 462 | # *method*. A method is like a function, but it only works by being 463 | # *attached* to something. 464 | # 465 | # In this function, we can a string of text characters, and attach this 466 | # `lower` method to to, and then attach a `startswith` function to 467 | # that. We end up with `True` if our player types "Yes" or "y". 468 | 469 | # 470 | 471 | def isYes(answer): 472 | if answer.lower().startswith("y"): 473 | return True 474 | else: 475 | return False 476 | 477 | # 478 | 479 | # We can make sure this function works, by making a few calls to `assert`: 480 | 481 | # 482 | 483 | assert( isYes("Yes") ) 484 | assert( isYes("Y") ) 485 | assert( isYes("yes") ) 486 | assert( isYes("y") ) 487 | assert( not isYes("No") ) 488 | assert( not isYes("n") ) 489 | 490 | # 491 | 492 | # We need a function that lets us give it a question that it will show 493 | # to the player, and then allow our player to type in something. Showing 494 | # things are easy, we just use `print`, but how do we get *something*? 495 | # 496 | # Python has a function, `raw_input` that when called, Python stops, 497 | # lets the player type something, and whatever the player types is given 498 | # back to us. We will take that, and give it to our `isYes` function. 499 | # 500 | # This means that the `askYesNo` function will take a string as a 501 | # question, and return either `True` for *yes* and `False` for *No*. 502 | 503 | # 504 | 505 | def askYesNo(question): 506 | print question, 507 | return isYes( raw_input() ) 508 | 509 | # 510 | 511 | # Finishing Touches 512 | 513 | # 514 | 515 | # We have now written all of the functions, including our big function, `playGame`. In fact, all we need to do is just call it: 516 | 517 | # 518 | 519 | playGame() 520 | 521 | # 522 | 523 | # If you **Play** that cell, we'll get an error, because in the Notebook, the `raw_input` function doesn't work. What we need to do is make a **Python Program**. Here's what you do: 524 | # 525 | # * Click the **File** menu above. 526 | # * Select **Download As...** 527 | # * Select **Python**. 528 | # 529 | # This will put a file in your `Downloads` folder that you can 530 | # double-click and play! 531 | 532 | -------------------------------------------------------------------------------- /cookie-python/Check/__init__.py: -------------------------------------------------------------------------------- 1 | from IPython.display import display, Image 2 | import string 3 | 4 | -------------------------------------------------------------------------------- /cookie-python/Check/check.py: -------------------------------------------------------------------------------- 1 | from IPython.display import display, Image 2 | from random import random, randint 3 | import string 4 | import math 5 | 6 | def check(number, exercise, *arguments): 7 | """Checks each exercise in the assignments of the Cookie Python Notebook. 8 | 9 | - `number` is the assignment notebook number, or name. 10 | - `exercise` the exercise number, starting with 1. 11 | - Other parameters are values specific to the exercise.""" 12 | 13 | value = None 14 | if len(arguments) > 0: 15 | value = arguments[0] 16 | 17 | if number == 1: 18 | return check1(exercise, value) 19 | elif number == 2: 20 | return check2(exercise, value) 21 | elif number == 3: 22 | return check3(exercise, arguments[0], arguments[1]) 23 | else: 24 | print "Assignment", number, "Exercise", exercise, "is not completed." 25 | 26 | def check1(exercise, value): 27 | """Check the exercises for Assignment 01-Buckets and Variables. 28 | 29 | Parameters: 30 | * `exercise` - The exercise number from 1 to 5 31 | * `value` - The parameter value for the exercise number.""" 32 | 33 | if exercise == 1: 34 | if value == 42: 35 | print "You did it! Have a cookie." 36 | return Image(url='http://openclipart.org/image/250px/svg_to_png/130009/cookie.png') 37 | else: 38 | print "You need to change the _ symbol to the number 42." 39 | 40 | elif exercise == 2: 41 | if value == 2.5: 42 | print "You did it! Have another cookie." 43 | return Image(url='http://openclipart.org/image/250px/svg_to_png/130009/cookie.png') 44 | else: 45 | print "You need to change the _ symbol to the number 2.5" 46 | 47 | elif exercise == 3: 48 | if value != None and len(value) > 2: 49 | print "Hello, " + value + ", it is nice to meet you." 50 | return Image(url='http://openclipart.org/image/250px/svg_to_png/167186/Hello.png') 51 | else: 52 | print 'You need to change the _ symbol to the number you name inside quotes, like "David"' 53 | 54 | 55 | elif exercise == 4: 56 | if value != None and value.find("at's ball") > -1: 57 | print "Good job! Here is Pat's shiny ball:" 58 | return Image(url='http://openclipart.org/image/250px/svg_to_png/1413/molumen_blue_cristal_ball.png') 59 | else: 60 | print "The sentence should say something about Pat's ball." 61 | 62 | elif exercise == 5: 63 | if value != None and value.find("\n") > -1: 64 | print "Good job! This deserves an award." 65 | show_award() 66 | else: 67 | print 'You need to change the _ symbol to a string with more than one line.' 68 | 69 | def show_award(): 70 | return Image(url='http://openclipart.org/image/250px/svg_to_png/151087/logo_mogo.png') 71 | 72 | def check2(exercise, value): 73 | """Check the exercises for Assignment 02-Operators. 74 | 75 | Parameters: 76 | * `exercise` - The exercise number from 1 to 2 77 | * `value` - The parameter value for the exercise number.""" 78 | 79 | if exercise == 1: 80 | pi = str(value) 81 | if pi.startswith("3.14"): 82 | l = len(pi)-2 83 | print "Good job! You know pi to", l, "places. Have some pie on me...." 84 | return Image(url='http://25.media.tumblr.com/tumblr_mc7g0fQWLF1qlu5vyo1_500.jpg') 85 | else: 86 | print "Just like our previous assignments, you need to replace the _ symbol above with the answer. In this case, the answer begins with 3. something something." 87 | 88 | elif exercise == 2: 89 | pi1 = str(value) 90 | pi2 = str(math.pi) 91 | 92 | print pi2 93 | print 94 | 95 | if pi1.startswith("3.14"): 96 | d = len(pi2) - len(pi1) 97 | if d <= 0: 98 | print "Wow! Your version of pi is great! You are amazing. However, math.pi may be a little quicker to type." 99 | elif d > 0: 100 | print "Python stores", d, "more digits to pi. So maybe you should use that variable in the next exercise." 101 | 102 | elif exercise == 3: 103 | if value > 28 and value < 29: 104 | print "Good job! The area is", value, " since the radius is half the diameter, r must be 3." 105 | else: 106 | print "Hint: The diameter is 6, but the formula uses `r` which is the radius." 107 | 108 | # This function is used in assignment/lesson 03- Calling Functions 109 | def dice(side): 110 | "This function takes a number from 1 to 6, and it returns a picture of a six-sided die with that number on it." 111 | if side == 1: 112 | return Image('http://openclipart.org/image/250px/svg_to_png/96079/dado_1.png') 113 | elif side == 2: 114 | return Image('http://openclipart.org/image/250px/svg_to_png/96085/dado_2.png') 115 | elif side == 3: 116 | return Image('http://openclipart.org/image/250px/svg_to_png/96091/dado_3.png') 117 | elif side == 4: 118 | return Image('http://openclipart.org/image/250px/svg_to_png/96097/dado_4.png') 119 | elif side == 5: 120 | return Image('http://openclipart.org/image/250px/svg_to_png/96103/dado_5.png') 121 | elif side == 6: 122 | return Image('http://openclipart.org/image/250px/svg_to_png/96109/dado_6.png') 123 | else: 124 | print "The number for 'side' must be 1, 2, 3, 4, 5, or 6." 125 | 126 | def check3(exercise, first, second): 127 | """Check the exercises for Assignment 03-Calling Functions. 128 | 129 | Parameters: 130 | * `exercise` - The exercise number from 1 to 2 131 | * `first` - The parameter value for the exercise number.""" 132 | 133 | if exercise == 1: 134 | if first and first > 0: 135 | print "The square root of your random number is", first 136 | 137 | elif exercise == 2: 138 | if first == second: 139 | print "Yes, you guessed right. Have a cookie shaped like a multiplication sign." 140 | return Image('http://openclipart.org/image/250px/svg_to_png/68365/x-cookie.png') 141 | else: 142 | print "Nope. Your random number was", second, "since", math.sqrt(second), "x", math.sqrt(second), "is", second 143 | 144 | def show_pony(name): 145 | """Shows a picture of a pony based on its name.""" 146 | if name == "Applejack": 147 | return Image("http://images2.wikia.nocookie.net/__cb20130419182238/mlp/images/thumb/d/d8/Applejack_S01E13_cropped.png/250px-Applejack_S01E13_cropped.png") 148 | elif name == "Fluttershy": 149 | return Image("http://images3.wikia.nocookie.net/__cb20130317084227/mlp/images/thumb/3/3a/Fluttershy_trotting_CROPPED_S2E7.png/250px-Fluttershy_trotting_CROPPED_S2E7.png") 150 | elif name == "Scootaloo": 151 | return Image("http://images2.wikia.nocookie.net/__cb20130109015850/mlp/images/thumb/d/de/Scootaloo_offering_help_crop_S1E24.png/250px-Scootaloo_offering_help_crop_S1E24.png") 152 | elif name == "Caramel": 153 | return Image("http://images4.wikia.nocookie.net/__cb20110706134227/mlp/images/thumb/0/09/Caramel.png/250px-Caramel.png") 154 | elif name == "Rainbow Dash": 155 | return Image("http://images1.wikia.nocookie.net/__cb20130307050703/mlp/images/thumb/4/4b/Rainbow_Dash_Wonderbolt_fantasy_cropped_S1E3.png/250px-Rainbow_Dash_Wonderbolt_fantasy_cropped_S1E3.png") 156 | elif name == "Big McIntosh": 157 | return Image("http://images3.wikia.nocookie.net/__cb20111110054616/mlp/images/thumb/2/2e/Big_McIntosh_onstage_S2E05.png/250px-Big_McIntosh_onstage_S2E05.png") 158 | elif name == "Braeburn": 159 | return Image("http://images2.wikia.nocookie.net/__cb20120715144761/mlp/images/thumb/3/36/Braeburn_S1E21_thumb.png/250px-Braeburn_S1E21_thumb.png") 160 | elif name == "Cheerilee": 161 | return Image("http://images2.wikia.nocookie.net/__cb20111015001440/mlp/images/a/a3/Cheerilee_next_to_easel_cropped_S1E12.png") 162 | else: 163 | print "I don't have a picture of a pony named,", name 164 | 165 | def is_prime(number): 166 | if number < 1: 167 | return False 168 | elif number < 4: 169 | return True 170 | elif number % 2 == 0: 171 | return False 172 | else: 173 | for i in range(5, number / 2, 2): 174 | if number % i == 0: 175 | return False 176 | return True 177 | 178 | def pokemon(monster): 179 | if monster["name"] == "Charmander": 180 | return Image("http://cdn.bulbagarden.net/upload/thumb/7/73/004Charmander.png/185px-004Charmander.png") 181 | elif monster["name"] == "Pikachu": 182 | return Image("http://cdn.bulbagarden.net/upload/thumb/0/0d/025Pikachu.png/205px-025Pikachu.png") 183 | elif monster["name"] == "Bulbasaur": 184 | return Image("http://cdn.bulbagarden.net/upload/thumb/2/21/001Bulbasaur.png/170px-001Bulbasaur.png") 185 | else: 186 | print "Sorry, I don't know anything about that Pokemon." 187 | -------------------------------------------------------------------------------- /misc/01-output.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/cookie-python/e5892bc346a4731f8c5165b27e2fe6cd48b6a2e2/misc/01-output.pdf -------------------------------------------------------------------------------- /misc/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/howardabrams/cookie-python/e5892bc346a4731f8c5165b27e2fe6cd48b6a2e2/misc/screenshot.png -------------------------------------------------------------------------------- /start-me-up: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | COOKIE_PYTHON_HOME=${COOKIE_PYTHON_HOME:-`dirname $0`} 4 | 5 | if echo $PYTHONPATH | grep 'cookie-python' 6 | then 7 | : 8 | else 9 | export PYTHONPATH=$COOKIE_PYTHON_HOME/cookie-python:$PYTHONPATH 10 | fi 11 | 12 | OUTPUT=.ipynb.output 13 | 14 | cd "$COOKIE_PYTHON_HOME" 15 | 16 | if [ -n "$1" -a \( "$1" = "-k" -o "$1" = "kill" \) ] 17 | then 18 | echo "Killing running iPython Notebook..." 19 | PS=$(ps | grep "ipython notebook" | grep -v grep | cut -c1-6) 20 | kill $PS 21 | exit 0 22 | fi 23 | 24 | if ps | grep "ipython notebook" | grep -v grep >/dev/null 25 | then 26 | echo "iPython Notebook is already running. Attempting to connect to it." 27 | URL=$(grep "running at: http" $OUTPUT | sed 's/.*http:/http:/') 28 | open $URL 29 | else 30 | echo "Starting iPython Notebook with Cookie Python project." 31 | nohup ipython notebook -c 'from Check.check import *' --pylab inline 2>&1 > $OUTPUT & 32 | fi 33 | --------------------------------------------------------------------------------