├── .gitignore ├── 0. Python_Intro.ipynb ├── 01_02 Calculator Sandbox.ipynb ├── 03a. Environment Test.ipynb ├── 03b. CalculatorWithR.ipynb ├── 04 Optimize.ipynb ├── 05_ScrubbingExample.ipynb ├── 06_Scrubbing in R.ipynb ├── HelloWorld.ipynb ├── PDF_Slides ├── AllUnitsCombined.pdf ├── Unit1.pdf ├── Unit2.pdf ├── Unit3.pdf ├── Unit4.pdf ├── Unit5.pdf └── Unit6.pdf ├── README.md ├── calculator_example1.py ├── calculators.py ├── hello_world.py ├── operators.json └── some_file.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | __pychache__ 3 | .DS* 4 | . 5 | .. 6 | .ipynb* 7 | 8 | -------------------------------------------------------------------------------- /0. Python_Intro.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "slideshow": { 7 | "slide_type": "slide" 8 | } 9 | }, 10 | "source": [ 11 | "# Python Introduction\n", 12 | "##### Created by Professor Eric Larson, contact at eclarson@smu.edu for errors or questions\n", 13 | "\n", 14 | "In this notebook, we will introduce the basics of programming in python as well as the installation of different modules and libraries. Debugging in python can be a pain, but there are many different ways of debugging depending on what you are most comfortable with. \n", 15 | "\n", 16 | "We will go over:\n", 17 | "+ Analysing and debugging errors \n", 18 | "+ Setting breakpoints with pdb \n", 19 | "+ Using an IDE with python that can look at memory, set breakpoints, etc.\n", 20 | "\n", 21 | "\n" 22 | ] 23 | }, 24 | { 25 | "cell_type": "markdown", 26 | "metadata": { 27 | "slideshow": { 28 | "slide_type": "subslide" 29 | } 30 | }, 31 | "source": [ 32 | "![Guido Von Rossum](https://raw.githubusercontent.com/eclarson/DataMiningNotebooks/master/data/guido.png)\n", 33 | "\n", 34 | "Python was founded by a guy named Guido Von Rossum in 1989. I will let him explain his motivations.\n", 35 | "From wikipedia:\n", 36 | ">Over six years ago, in December 1989, I was looking for a \"hobby\" programming project that would keep me occupied during the week around Christmas. My office ... would be closed, but I had a home computer, and not much else on my hands. I decided to write an interpreter for the new scripting language I had been thinking about lately: a descendant of ABC that would appeal to Unix/C hackers. I chose Python as a working title for the project, being in a slightly irreverent mood (and a big fan of Monty Python's Flying Circus).\n", 37 | "\n", 38 | " -Guido van Rossum in 1996\n", 39 | "\n", 40 | "So let that be a lesson! Python is not named after the snake, it is after Monty Python. However, even though the language is a bit quirky, do not let that fool you. It is absolutely made for people to use as a serious programming language and tool. Whether you have novice programming skills or are a sesoned veteran at OOP. \n", 41 | "\n", 42 | "For example, take a look at the most popular programming languages as identified by the number of projects in GitHub, and the number of related questions on stack overflow. Notice the other langauges next to python, like java, php, c++, ruby, and all the heavy hitters. Its also on every top ten list of programming languages needed to get a job in programming. Check it out. Graphic credit given to RedMonk.\n", 43 | "![Python](https://raw.githubusercontent.com/eclarson/DataMiningNotebooks/master/data/python_ranking.png)\n", 44 | "\n", 45 | "Moreover, python is one of the fastest growing languages used in scientific computing and data science. According to a recent survey, the three most helpful languages or packages for doing data science are R, SAS, and python. You will likely make use of all three for a given project or set of projects. See http://www.r-bloggers.com/data-science-toolbox-survey-results-surprise-r-and-python-win/ for a high level description of the survey.\n", 46 | "\n", 47 | "# Running Python\n", 48 | "Python can be run in various ways. We will cover how to run it from the interpreter prompt, command line scripts, and from iPython notebook." 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": 2, 54 | "metadata": { 55 | "collapsed": false 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "# this is a comment\n", 60 | "\n", 61 | "# place this at the top of python file to enable running as >>./filename.py\n", 62 | "#! /usr/bin/python\n", 63 | "\n", 64 | "# otherwise you can run with >>python filename.py {or} >>python27 filename.py\n", 65 | "\n", 66 | "# those commands can be run from a terminal window" 67 | ] 68 | }, 69 | { 70 | "cell_type": "code", 71 | "execution_count": 3, 72 | "metadata": { 73 | "collapsed": false 74 | }, 75 | "outputs": [ 76 | { 77 | "name": "stdout", 78 | "output_type": "stream", 79 | "text": [ 80 | "hello world\n" 81 | ] 82 | } 83 | ], 84 | "source": [ 85 | "# hello world from iPython Notebook\n", 86 | "print (\"hello world\")" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "# Syntax\n", 94 | "Okay, so lets first dive into some of the syntax in python programming." 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 4, 100 | "metadata": { 101 | "collapsed": false 102 | }, 103 | "outputs": [ 104 | { 105 | "name": "stdout", 106 | "output_type": "stream", 107 | "text": [ 108 | "Variable type examples:\n", 109 | "\n", 110 | "\n", 111 | "\n", 112 | "\n", 113 | "True\n", 114 | "False\n" 115 | ] 116 | } 117 | ], 118 | "source": [ 119 | "# ============================================\n", 120 | "# Variables Example\n", 121 | "int_val = 8\n", 122 | "long_val = 23423423235 # in python 3 longs are integers!!\n", 123 | "float_val = 2.546923764237654239\n", 124 | "bool_val = False\n", 125 | "\n", 126 | "print (\"Variable type examples:\")\n", 127 | "print (type(int_val))\n", 128 | "print (type(long_val))\n", 129 | "print (type(float_val))\n", 130 | "print (type(bool_val))\n", 131 | "\n", 132 | "# testing for the type of a variable\n", 133 | "temp = isinstance(float_val,float)\n", 134 | "print (temp)\n", 135 | "print (isinstance(float_val,int))" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": 5, 141 | "metadata": { 142 | "collapsed": false 143 | }, 144 | "outputs": [ 145 | { 146 | "name": "stdout", 147 | "output_type": "stream", 148 | "text": [ 149 | "\n", 150 | "Arithmetic examples:\n", 151 | "2.6666666666666665\n", 152 | "2.6666666666666665\n", 153 | "2.6666666666666665\n", 154 | "False\n", 155 | "False\n", 156 | "True\n", 157 | "8.0\n", 158 | "5\n", 159 | "81\n" 160 | ] 161 | } 162 | ], 163 | "source": [ 164 | "#============================================\n", 165 | "# Arithmetic and casting\n", 166 | "print (\"\\nArithmetic examples:\")\n", 167 | "print (8 / 3)\n", 168 | "print (float(8) / 3)\n", 169 | "print (float(8) / float(3))\n", 170 | "\n", 171 | "print (True and False) # logicals\n", 172 | "print (8 == 3 ) # logical equallty\n", 173 | "print (5 <= 6 ) # logical comparison\n", 174 | "\n", 175 | "print (2.0*4.0) # multiplication\n", 176 | "print (65%6 ) # remainder, modulus\n", 177 | "print (3**4 ) # 3 to the fourth power" 178 | ] 179 | }, 180 | { 181 | "cell_type": "code", 182 | "execution_count": 6, 183 | "metadata": { 184 | "collapsed": false 185 | }, 186 | "outputs": [ 187 | { 188 | "name": "stdout", 189 | "output_type": "stream", 190 | "text": [ 191 | "\n", 192 | "String example:\n", 193 | "A string is double or single quotes\n", 194 | "Three quote means that the string goes over\n", 195 | "multiple lines\n", 196 | "This also spans multiple lines but has no newline\n" 197 | ] 198 | } 199 | ], 200 | "source": [ 201 | "#============================================\n", 202 | "# strings example\n", 203 | "print (\"\\nString example:\")\n", 204 | "str_val = \"A string is double or single quotes\"\n", 205 | "str_val_long = '''Three quote means that the string goes over\n", 206 | "multiple lines'''\n", 207 | "str_val_no_newline = '''This also spans multiple lines \\\n", 208 | "but has no newline'''\n", 209 | "\n", 210 | "print (str_val)\n", 211 | "print (str_val_long)\n", 212 | "print (str_val_no_newline)" 213 | ] 214 | }, 215 | { 216 | "cell_type": "code", 217 | "execution_count": 7, 218 | "metadata": { 219 | "collapsed": false 220 | }, 221 | "outputs": [ 222 | { 223 | "name": "stdout", 224 | "output_type": "stream", 225 | "text": [ 226 | "A\n", 227 | "tr\n", 228 | "s\n", 229 | "uotes\n", 230 | "A string is double or single quotes\n" 231 | ] 232 | }, 233 | { 234 | "ename": "TypeError", 235 | "evalue": "'str' object does not support item assignment", 236 | "output_type": "error", 237 | "traceback": [ 238 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 239 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 240 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mprint\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mstr_val\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mstr_val\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# print the first five elements, then from the fifth and on\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m \u001b[0mstr_val\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'G'\u001b[0m \u001b[0;31m# this is an error, strings are immutable once they are set\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 241 | "\u001b[0;31mTypeError\u001b[0m: 'str' object does not support item assignment" 242 | ] 243 | } 244 | ], 245 | "source": [ 246 | "# string can be accessed in a variety of different ways\n", 247 | "\n", 248 | "print (str_val[0] ) # initial element \"0th\" element\n", 249 | "print (str_val[3:5]) # elements 3 and 4, but not 5\n", 250 | "print (str_val[-1] ) # the last element in the string\n", 251 | "print (str_val[-5:]) # the last five elements\n", 252 | "print (str_val[0:5] + str_val[5:]) # print the first five elements, then from the fifth and on\n", 253 | "\n", 254 | "str_val[5] = 'G' # this is an error, strings are immutable once they are set" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": 8, 260 | "metadata": { 261 | "collapsed": false 262 | }, 263 | "outputs": [ 264 | { 265 | "name": "stdout", 266 | "output_type": "stream", 267 | "text": [ 268 | "A string is double or single quotesA string is double or single quotes\n", 269 | "True\n", 270 | "Eric\n", 271 | "a string is double or single quotes\n", 272 | "A STRING IS DOUBLE OR SINGLE QUOTES\n", 273 | "['this', ' is', ' separated', ' by', ' commas']\n" 274 | ] 275 | } 276 | ], 277 | "source": [ 278 | "# some common operations for strings\n", 279 | "print (str_val*2) # mutliply is like adding the number of times, here it repeats the string twice\n", 280 | "print ('Python' > 'Java') # compare the strings alphabetically \n", 281 | "\n", 282 | "print (\"eric\".capitalize()) # the dot operator works like it does in most other OOP languages\n", 283 | "print (str_val.lower())\n", 284 | "print (str_val.upper())\n", 285 | "print (\"this, is, separated, by, commas\".split(',')) # this results is returned as a list, which we need to talk about!" 286 | ] 287 | }, 288 | { 289 | "cell_type": "markdown", 290 | "metadata": {}, 291 | "source": [ 292 | "# Tuples, Lists, Sets, and Dictionaries " 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 9, 298 | "metadata": { 299 | "collapsed": false 300 | }, 301 | "outputs": [ 302 | { 303 | "name": "stdout", 304 | "output_type": "stream", 305 | "text": [ 306 | "[45, 67, 'not a number', 'A string, appended as a new element in the list']\n", 307 | "[45, 67, 'not a number', 'A string, appended as a new element in the list', ['a list', 'within another list', 442]]\n", 308 | "['a list', 'within another list', 442]\n", 309 | "['A string, appended as a new element in the list', ['a list', 'within another list', 442]]\n" 310 | ] 311 | } 312 | ], 313 | "source": [ 314 | "# A List is one of the most powerful tools in python from which\n", 315 | "# most abstract types get created and implemented\n", 316 | "\n", 317 | "# a list is very much like the mutable version of a tuple\n", 318 | "# it can hold any type of information\n", 319 | "a_list = [45, 67, \"not a number\"]\n", 320 | "\n", 321 | "# we can add to a list through the append function\n", 322 | "a_list.append(\"A string, appended as a new element in the list\")\n", 323 | "\n", 324 | "print (a_list)\n", 325 | "\n", 326 | "# Lists can have other lists in them\n", 327 | "tmp_list = [\"a list\", \"within another list\", 442]\n", 328 | "a_list.append(tmp_list)\n", 329 | "\n", 330 | "print (a_list)\n", 331 | "\n", 332 | "# all of the indexing we learned from before still works with lists\n", 333 | "print (a_list[-1])\n", 334 | "print (a_list[-2:])\n" 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": 10, 340 | "metadata": { 341 | "collapsed": false 342 | }, 343 | "outputs": [ 344 | { 345 | "name": "stdout", 346 | "output_type": "stream", 347 | "text": [ 348 | "(45, 67, 'not a number')\n", 349 | "not a number\n" 350 | ] 351 | }, 352 | { 353 | "ename": "TypeError", 354 | "evalue": "'tuple' object does not support item assignment", 355 | "output_type": "error", 356 | "traceback": [ 357 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 358 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 359 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;31m# but you cannot change a tuple, its immutable!!\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 10\u001b[0;31m \u001b[0ma_tuple\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m2\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'hey'\u001b[0m \u001b[0;31m# this will give you an error!!\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 360 | "\u001b[0;31mTypeError\u001b[0m: 'tuple' object does not support item assignment" 361 | ] 362 | } 363 | ], 364 | "source": [ 365 | "# tuples are immutable lists and are designated by commas\n", 366 | "# you can store ANYTHING in side a tuple, its basically a complex object container\n", 367 | "a_tuple = 45, 67, \"not a number\" \n", 368 | "print (a_tuple)\n", 369 | "\n", 370 | "# you can access a tuple with square brackets\n", 371 | "print (a_tuple[2])\n", 372 | "\n", 373 | "# but you cannot change a tuple, its immutable!!\n", 374 | "a_tuple[2] = 'hey' # this will give you an error!!" 375 | ] 376 | }, 377 | { 378 | "cell_type": "code", 379 | "execution_count": 11, 380 | "metadata": { 381 | "collapsed": false 382 | }, 383 | "outputs": [ 384 | { 385 | "name": "stdout", 386 | "output_type": "stream", 387 | "text": [ 388 | "{'pear', 'banana', 'orange', 'apple'}\n", 389 | "True\n", 390 | "False\n", 391 | "{'r', 'a', '!', 'b', 'd', 'c'}\n", 392 | "{'d', '!', 'b', 'r'}\n", 393 | "{'r', 'a', '!', 'm', 'b', 'd', 'c', 'z', 'l'}\n", 394 | "{'a', 'c'}\n", 395 | "{'r', '!', 'm', 'b', 'd', 'z', 'l'}\n" 396 | ] 397 | }, 398 | { 399 | "ename": "AttributeError", 400 | "evalue": "'frozenset' object has no attribute 'add'", 401 | "output_type": "error", 402 | "traceback": [ 403 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 404 | "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)", 405 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0ma_immutable\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mfrozenset\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0ma\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 22\u001b[0;31m \u001b[0ma_immutable\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m'e'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;31m# the set is immutable, so we cannot add to it, this will give an error!\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", 406 | "\u001b[0;31mAttributeError\u001b[0m: 'frozenset' object has no attribute 'add'" 407 | ] 408 | } 409 | ], 410 | "source": [ 411 | "# Sets, taken from the Python sets tutorial\n", 412 | "# https://docs.python.org/2/tutorial/datastructures.html#sets\n", 413 | "basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']\n", 414 | "fruit = set(basket) # create a set without duplicates\n", 415 | "print (fruit)\n", 416 | "print ('orange' in fruit )# fast membership testing\n", 417 | "print ('crabgrass' in fruit)\n", 418 | "\n", 419 | "# Demonstrate set operations on unique letters from two words\n", 420 | "a = set('abracadabra')\n", 421 | "b = set('alacazam')\n", 422 | "a.add('!') # also add the some punctuation\n", 423 | "\n", 424 | "# set operations\n", 425 | "print (a ) # unique letters in a\n", 426 | "print (a - b ) # letters in a but not in b\n", 427 | "print (a | b ) # letters in either a or b\n", 428 | "print (a & b ) # letters in both a and b\n", 429 | "print (a ^ b ) # letters in a or b but not both\n", 430 | "\n", 431 | "a_immutable = frozenset(a)\n", 432 | "a_immutable.add('e') # the set is immutable, so we cannot add to it, this will give an error!" 433 | ] 434 | }, 435 | { 436 | "cell_type": "code", 437 | "execution_count": 12, 438 | "metadata": { 439 | "collapsed": false 440 | }, 441 | "outputs": [ 442 | { 443 | "name": "stdout", 444 | "output_type": "stream", 445 | "text": [ 446 | "{'dog': 4, 'human': 2, 'cat': 4}\n", 447 | "4\n", 448 | "2\n", 449 | "===============\n", 450 | "{'dog': 4, 'human': 'two', 'bird': 'two and some wings', 45: 'a key that is not a string'}\n" 451 | ] 452 | } 453 | ], 454 | "source": [ 455 | "# Dictionaries map keys to values.\n", 456 | "\n", 457 | "# Here we setup a key as a string and the value as a number\n", 458 | "num_legs = { 'dog': 4, 'cat': 4, 'human': 2 }\n", 459 | "\n", 460 | "# You access Subscripts via the \"key\"\n", 461 | "print (num_legs)\n", 462 | "print (num_legs['dog'])\n", 463 | "print (num_legs['human'])\n", 464 | "\n", 465 | "print ('===============')\n", 466 | "# Entries can be added, updated, or deleted.\n", 467 | "# Again, these are just containers for any memory type\n", 468 | "num_legs['human'] = 'two'\n", 469 | "num_legs['bird'] = 'two and some wings'\n", 470 | "num_legs[45] = 'a key that is not a string' # notice that the key does not need to be a string\n", 471 | "# the key just needs to be some immutable memory\n", 472 | "\n", 473 | "del num_legs['cat']\n", 474 | "print (num_legs)" 475 | ] 476 | }, 477 | { 478 | "cell_type": "markdown", 479 | "metadata": {}, 480 | "source": [ 481 | "# ADTs, Loops, and Conditionals" 482 | ] 483 | }, 484 | { 485 | "cell_type": "code", 486 | "execution_count": 13, 487 | "metadata": { 488 | "collapsed": false 489 | }, 490 | "outputs": [ 491 | { 492 | "name": "stdout", 493 | "output_type": "stream", 494 | "text": [ 495 | "\n", 496 | "for loop output:\n", 497 | "DataMining \n", 498 | "This statement is in the loop\n", 499 | "8 \n", 500 | "This statement is in the loop\n", 501 | "23423423235 \n", 502 | "This statement is in the loop\n", 503 | "2.546923764237654 \n", 504 | "This statement is in the loop\n", 505 | "False \n", 506 | "This statement is in the loop\n", 507 | "This statement is outside the loop\n" 508 | ] 509 | } 510 | ], 511 | "source": [ 512 | "\n", 513 | "#============================================\n", 514 | "# for loop example with list\n", 515 | "print (\"\\nfor loop output:\")\n", 516 | "\n", 517 | "list_example = [int_val, long_val, float_val, bool_val]\n", 518 | "list_example.insert(0, \"DataMining\")\n", 519 | "\n", 520 | "# notice that the loop ends with a colon and \n", 521 | "# is designated by the tab alignment\n", 522 | "for val in list_example:\n", 523 | " print (str(val) + ' ' + str(type(val)))\n", 524 | " print (\"This statement is in the loop\")\n", 525 | " \n", 526 | "print (\"This statement is outside the loop\")\n", 527 | " " 528 | ] 529 | }, 530 | { 531 | "cell_type": "code", 532 | "execution_count": 14, 533 | "metadata": { 534 | "collapsed": false 535 | }, 536 | "outputs": [ 537 | { 538 | "name": "stdout", 539 | "output_type": "stream", 540 | "text": [ 541 | "0\n", 542 | "B. exiting for loop without break\n" 543 | ] 544 | } 545 | ], 546 | "source": [ 547 | "import random\n", 548 | "val = 0\n", 549 | "for i in range(0, random.randint(1, 10) ):\n", 550 | " val += i\n", 551 | " print (val)\n", 552 | " if val>20:\n", 553 | " print (' A. leaving the loop on break')\n", 554 | " break # break out of loop\n", 555 | "else: # this else belongs to the for loop\n", 556 | " print ('B. exiting for loop without break')" 557 | ] 558 | }, 559 | { 560 | "cell_type": "code", 561 | "execution_count": 15, 562 | "metadata": { 563 | "collapsed": false 564 | }, 565 | "outputs": [ 566 | { 567 | "name": "stdout", 568 | "output_type": "stream", 569 | "text": [ 570 | "DataMining \t is at index \t 0\n", 571 | "8 \t is at index \t 1\n", 572 | "23423423235 \t is at index \t 2\n", 573 | "2.546923764237654 \t is at index \t 3\n", 574 | "False \t is at index \t 4\n" 575 | ] 576 | } 577 | ], 578 | "source": [ 579 | "# more for loop examples\n", 580 | "\n", 581 | "# you can also get the index using the enumerate example\n", 582 | "for index, val in enumerate(list_example):\n", 583 | " print (str(val), '\\t is at index \\t', index)\n" 584 | ] 585 | }, 586 | { 587 | "cell_type": "code", 588 | "execution_count": 16, 589 | "metadata": { 590 | "collapsed": false 591 | }, 592 | "outputs": [ 593 | { 594 | "name": "stdout", 595 | "output_type": "stream", 596 | "text": [ 597 | "What is your name? It is lancelot.\n", 598 | "What is your quest? It is the holy grail.\n", 599 | "What is your favorite color? It is blue.\n" 600 | ] 601 | } 602 | ], 603 | "source": [ 604 | "\n", 605 | "# this is a classic example for zipping, provided by the official python tutorial\n", 606 | "# notice the references to Monty Python\n", 607 | "\n", 608 | "# say you have two lists of equal size, that you would like to \n", 609 | "# loop through without indexing, you can use the \"zip\" function\n", 610 | "questions = ['name', 'quest', 'favorite color']\n", 611 | "answers = ['lancelot', 'the holy grail', 'blue']\n", 612 | "for q, a in zip(questions, answers):\n", 613 | " print ('What is your %s? It is %s.' % (q, a))" 614 | ] 615 | }, 616 | { 617 | "cell_type": "code", 618 | "execution_count": 17, 619 | "metadata": { 620 | "collapsed": false 621 | }, 622 | "outputs": [ 623 | { 624 | "name": "stdout", 625 | "output_type": "stream", 626 | "text": [ 627 | "dict_keys(['dog', 'human', 'bird', 45])\n", 628 | "dog => 4\n", 629 | "human => two\n", 630 | "bird => two and some wings\n", 631 | "45 => a key that is not a string\n", 632 | "===============\n", 633 | "dog => 4\n", 634 | "human => two\n", 635 | "bird => two and some wings\n", 636 | "45 => a key that is not a string\n", 637 | "===============\n", 638 | "human => two\n", 639 | "beast is not present.\n", 640 | "cat is not present.\n", 641 | "dog => 4\n", 642 | "45 => a key that is not a string\n" 643 | ] 644 | } 645 | ], 646 | "source": [ 647 | "# Looping through dictionaries\n", 648 | "# Get all the keys.\n", 649 | "print (num_legs.keys())\n", 650 | "for k in num_legs.keys():\n", 651 | " print (k, \"=>\", num_legs[k])\n", 652 | "\n", 653 | "print ('===============')\n", 654 | "# you can also use the iter_items function\n", 655 | "for k, v in num_legs.items():\n", 656 | " print (k, \"=>\", v)\n", 657 | "\n", 658 | "print ('===============')\n", 659 | "# Test for presence of a key.\n", 660 | "for t in [ 'human', 'beast', 'cat', 'dog', 45 ]:\n", 661 | " print (t,end=' ')\n", 662 | " if t in num_legs:\n", 663 | " print ('=>', num_legs[t])\n", 664 | " else:\n", 665 | " print ('is not present.')" 666 | ] 667 | }, 668 | { 669 | "cell_type": "code", 670 | "execution_count": 18, 671 | "metadata": { 672 | "collapsed": false 673 | }, 674 | "outputs": [ 675 | { 676 | "name": "stdout", 677 | "output_type": "stream", 678 | "text": [ 679 | "[0, 1, 16, 81, 256, 625, 1296, 2401, 4096, 6561]\n", 680 | "['NAME', 'QUEST', 'FAVORITE COLOR']\n", 681 | "{0: 0, 1: 1, 2: 16, 3: 81, 4: 256, 5: 625, 6: 1296, 7: 2401, 8: 4096, 9: 6561}\n", 682 | "260\n" 683 | ] 684 | } 685 | ], 686 | "source": [ 687 | "# list comprehensions and dictionary comprehensions\n", 688 | "\n", 689 | "# comprehensions are like shorthand for loops where each\n", 690 | "# pass through the loop saves the result in a list or dictionary\n", 691 | "\n", 692 | "# for example, imagine we want to take every element in a range to the fourth power\n", 693 | "times_four = [x**4 for x in range(10)]\n", 694 | "print (times_four)\n", 695 | "# this save the fourth power of the numbers 0 through 9\n", 696 | "# the result of each pass through the loop saves a value\n", 697 | "# in other languages this is also known as \"lambda functions\"\n", 698 | "\n", 699 | "# you can also call functions inside a comprehension, and take \n", 700 | "# advantage of the data type. For example, if each element is a string\n", 701 | "# we can use the string member methods\n", 702 | "questions = ['name', 'quest', 'favorite color']\n", 703 | "quest_upper = [x.upper() for x in questions]\n", 704 | "print (quest_upper)\n", 705 | "\n", 706 | "# you can also do comprehensions with dictionaries\n", 707 | "times_four = {x:x**4 for x in range(10)}\n", 708 | "# notice that the comprehension is wrapped in curly braces and the key for the value \n", 709 | "# is given inside the code itself, followed by a colon\n", 710 | "print (times_four)\n", 711 | "\n", 712 | "# you can also nest comprehensions inside each other, but this is not always good coding practice\n", 713 | "# especially if it makes the code less readable\n", 714 | "\n", 715 | "# Finally, all of the enumerate, zipping, and slicing we performed also applies to \n", 716 | "# list comprehensions\n", 717 | "x_array = [10, 20, 30]\n", 718 | "y_array = [7, 5, 3]\n", 719 | "# this prints the sum of the multiplication of the arrays\n", 720 | "print (sum(x*y for x,y in zip(x_array, y_array)) ) \n" 721 | ] 722 | }, 723 | { 724 | "cell_type": "code", 725 | "execution_count": 19, 726 | "metadata": { 727 | "collapsed": false 728 | }, 729 | "outputs": [ 730 | { 731 | "name": "stdout", 732 | "output_type": "stream", 733 | "text": [ 734 | "\n", 735 | "Stack Example:\n", 736 | "['LIFO', 0, 1, 2, 3, 4]\n", 737 | "=============\n", 738 | "4\n", 739 | "=============\n", 740 | "['LIFO', 0, 1, 2, 3]\n", 741 | "=============\n" 742 | ] 743 | } 744 | ], 745 | "source": [ 746 | "#============================================\n", 747 | "# array as a stack\n", 748 | "print (\"\\nStack Example:\")\n", 749 | "list_example = []\n", 750 | "list_example.append('LIFO')\n", 751 | "\n", 752 | "for i in range(0, 5):\n", 753 | " list_example.append(i)\n", 754 | "\n", 755 | "print (list_example)\n", 756 | "print (\"=============\")\n", 757 | "val = list_example.pop()\n", 758 | "print (val)\n", 759 | "print (\"=============\")\n", 760 | "print (list_example)\n", 761 | "print (\"=============\")" 762 | ] 763 | }, 764 | { 765 | "cell_type": "code", 766 | "execution_count": 20, 767 | "metadata": { 768 | "collapsed": false 769 | }, 770 | "outputs": [ 771 | { 772 | "name": "stdout", 773 | "output_type": "stream", 774 | "text": [ 775 | "\n", 776 | "Queue Example:\n", 777 | "deque([9, 8, 7, 6, 5, 'FIFO'])\n", 778 | "=============\n", 779 | "FIFO\n", 780 | "=============\n", 781 | "deque([9, 8, 7, 6, 5])\n", 782 | "=============\n", 783 | "5\n", 784 | "6\n", 785 | "7\n", 786 | "8\n", 787 | "9\n" 788 | ] 789 | } 790 | ], 791 | "source": [ 792 | "#============================================\n", 793 | "# array as a queue\n", 794 | "print (\"\\nQueue Example:\")\n", 795 | "from collections import deque # this is an import, we will get back to that later\n", 796 | "# essentially this is a set of utility functions shipped with python\n", 797 | "\n", 798 | "q_example = deque()\n", 799 | "q_example.appendleft(\"FIFO\")\n", 800 | "for i in range(5, 10):\n", 801 | " q_example.appendleft(i)\n", 802 | "\n", 803 | "print (q_example)\n", 804 | "print (\"=============\")\n", 805 | "val = q_example.pop()\n", 806 | "print (val)\n", 807 | "print (\"=============\")\n", 808 | "print (q_example)\n", 809 | "print (\"=============\")\n", 810 | "\n", 811 | "# pop and print each element\n", 812 | "while len(q_example) > 0:\n", 813 | " print (q_example.pop())" 814 | ] 815 | }, 816 | { 817 | "cell_type": "code", 818 | "execution_count": 21, 819 | "metadata": { 820 | "collapsed": false 821 | }, 822 | "outputs": [ 823 | { 824 | "name": "stdout", 825 | "output_type": "stream", 826 | "text": [ 827 | "\n", 828 | "Conditional Example:\n", 829 | "a is true\n", 830 | "b is false\n" 831 | ] 832 | } 833 | ], 834 | "source": [ 835 | "#============================================\n", 836 | "# conditional example\n", 837 | "print (\"\\nConditional Example:\")\n", 838 | "\n", 839 | "a, b = True, False\n", 840 | "\n", 841 | "if a:\n", 842 | " print (\"a is true\")\n", 843 | "elif a or b:\n", 844 | " print (\"b is true\")\n", 845 | "else:\n", 846 | " print (\"neither a or b are true\")\n", 847 | "\n", 848 | "# conditional assignment\n", 849 | "val = \"b is true\" if b else \"b is false\"\n", 850 | "print (val)" 851 | ] 852 | }, 853 | { 854 | "cell_type": "code", 855 | "execution_count": 22, 856 | "metadata": { 857 | "collapsed": false 858 | }, 859 | "outputs": [ 860 | { 861 | "name": "stdout", 862 | "output_type": "stream", 863 | "text": [ 864 | "I. Everybody is a five!\n", 865 | "II. These are the same object!\n", 866 | "III. Wish we had the same objects...\n", 867 | "IV. Everybody is a five!\n", 868 | "V. Wish we had fives...\n", 869 | "VI. Got through nested conditional\n" 870 | ] 871 | } 872 | ], 873 | "source": [ 874 | "# more on conditionals, \"is\" versus ==\n", 875 | "\n", 876 | "# I. the traditional == works as expected\n", 877 | "a=5\n", 878 | "b=5\n", 879 | "if a==b:\n", 880 | " print (\"I. Everybody is a five!\")\n", 881 | "else:\n", 882 | " print (\"I. Wish we had fives…\" )\n", 883 | " \n", 884 | "# II. the \"is\" function is for object comparison, much like comparing pointers\n", 885 | "a=327676\n", 886 | "b=a\n", 887 | "if a is b:\n", 888 | " print (\"II. These are the same object!\")\n", 889 | "else:\n", 890 | " print (\"II. Wish we had the same objects...\" )\n", 891 | " \n", 892 | "# III. while these have the same value, they are not the same memory\n", 893 | "a=327676\n", 894 | "b=327675+1\n", 895 | "if a is b:\n", 896 | " print (\"III. These are the same object!\")\n", 897 | "else:\n", 898 | " print (\"III. Wish we had the same objects...\" )\n", 899 | "\n", 900 | "# IV. you would expect this to say wish we had fives,\n", 901 | "# but small integers like this are cached so right now they do point to the same memory\n", 902 | "a=5\n", 903 | "b=4+1\n", 904 | "if a is b:\n", 905 | " print (\"IV. Everybody is a five!\")\n", 906 | "else:\n", 907 | " print (\"IV. Wish we had fives...\" )\n", 908 | " \n", 909 | "# V. but if we change the memory, that caching gets released\n", 910 | "b = b*2.0\n", 911 | "b = b/2.0\n", 912 | "if a is b:\n", 913 | " print (\"V. Everybody is a five!\")\n", 914 | "else:\n", 915 | " print (\"V. Wish we had fives...\")\n", 916 | " \n", 917 | "# you can also perform nested conditionals, like bounding\n", 918 | "if 5 < 8 < 6: # not true because 8 is not less than 6\n", 919 | " print ('VI. How did we get here')\n", 920 | "elif 4 < 18 < 22:\n", 921 | " print (\"VI. Got through nested conditional\")" 922 | ] 923 | }, 924 | { 925 | "cell_type": "markdown", 926 | "metadata": {}, 927 | "source": [ 928 | "# Pythonic\n", 929 | "Now that we have gone through a consierable number of examples and data types, we need to talk about what it means to write code in python that is \"pythonic\". In a nutshell, there are many ways to implement something in python. The \"best\" method is one that is readable, simple, and brief. \n", 930 | "\n", 931 | "There many different coding “styles”\n", 932 | "+ “best” styles get the distinction of “pythonic”\n", 933 | " + ill formed definition\n", 934 | " + changes as the language matures\n", 935 | "+ pythonic code is:\n", 936 | " + simple and readable\n", 937 | " + uses dynamic typing when possible\n", 938 | " + uses underscores to separate names\n", 939 | " + names of variables are distinctive\n", 940 | "+ …or to quote Tim Peters…, run the next cell\n" 941 | ] 942 | }, 943 | { 944 | "cell_type": "code", 945 | "execution_count": 23, 946 | "metadata": { 947 | "collapsed": false 948 | }, 949 | "outputs": [ 950 | { 951 | "name": "stdout", 952 | "output_type": "stream", 953 | "text": [ 954 | "The Zen of Python, by Tim Peters\n", 955 | "\n", 956 | "Beautiful is better than ugly.\n", 957 | "Explicit is better than implicit.\n", 958 | "Simple is better than complex.\n", 959 | "Complex is better than complicated.\n", 960 | "Flat is better than nested.\n", 961 | "Sparse is better than dense.\n", 962 | "Readability counts.\n", 963 | "Special cases aren't special enough to break the rules.\n", 964 | "Although practicality beats purity.\n", 965 | "Errors should never pass silently.\n", 966 | "Unless explicitly silenced.\n", 967 | "In the face of ambiguity, refuse the temptation to guess.\n", 968 | "There should be one-- and preferably only one --obvious way to do it.\n", 969 | "Although that way may not be obvious at first unless you're Dutch.\n", 970 | "Now is better than never.\n", 971 | "Although never is often better than *right* now.\n", 972 | "If the implementation is hard to explain, it's a bad idea.\n", 973 | "If the implementation is easy to explain, it may be a good idea.\n", 974 | "Namespaces are one honking great idea -- let's do more of those!\n" 975 | ] 976 | } 977 | ], 978 | "source": [ 979 | "import this # the zen of python" 980 | ] 981 | }, 982 | { 983 | "cell_type": "markdown", 984 | "metadata": {}, 985 | "source": [ 986 | "## Pop Quiz!!!\n", 987 | "Which of these is more pythonic: You want to add the numbers between zero and N. \n" 988 | ] 989 | }, 990 | { 991 | "cell_type": "code", 992 | "execution_count": 24, 993 | "metadata": { 994 | "collapsed": false 995 | }, 996 | "outputs": [ 997 | { 998 | "name": "stdout", 999 | "output_type": "stream", 1000 | "text": [ 1001 | "8128\n", 1002 | "8128\n", 1003 | "8128.0\n" 1004 | ] 1005 | } 1006 | ], 1007 | "source": [ 1008 | "N = 128\n", 1009 | "\n", 1010 | "sum_value = 0\n", 1011 | "for i in range(N):\n", 1012 | " sum_value += i\n", 1013 | "print (sum_value)\n", 1014 | "\n", 1015 | "# OR\n", 1016 | "print (sum(range(N)))\n", 1017 | "\n", 1018 | "# OR\n", 1019 | "print (N*(N-1)/2 )" 1020 | ] 1021 | }, 1022 | { 1023 | "cell_type": "markdown", 1024 | "metadata": {}, 1025 | "source": [ 1026 | "# Functions and Classes" 1027 | ] 1028 | }, 1029 | { 1030 | "cell_type": "code", 1031 | "execution_count": 25, 1032 | "metadata": { 1033 | "collapsed": false 1034 | }, 1035 | "outputs": [ 1036 | { 1037 | "name": "stdout", 1038 | "output_type": "stream", 1039 | "text": [ 1040 | "\n", 1041 | "Function Example:\n", 1042 | "upper case\n", 1043 | "data mining\n" 1044 | ] 1045 | } 1046 | ], 1047 | "source": [ 1048 | "#============================================\n", 1049 | "print (\"\\nFunction Example:\")\n", 1050 | "\n", 1051 | "# create and call a function\n", 1052 | "# the function can be defined almost anywhere in file, as long as it is defined before it gets used\n", 1053 | "def make_strings_lowercase(str_input):\n", 1054 | " assert isinstance(str_input, str) # test the type of input\n", 1055 | " return str_input.lower()\n", 1056 | "\n", 1057 | "# now we are back on the main execution\n", 1058 | "print (make_strings_lowercase(\"UPPER CASE\"))\n", 1059 | "print (make_strings_lowercase(\"Data Mining\"))\n" 1060 | ] 1061 | }, 1062 | { 1063 | "cell_type": "code", 1064 | "execution_count": 26, 1065 | "metadata": { 1066 | "collapsed": false 1067 | }, 1068 | "outputs": [ 1069 | { 1070 | "name": "stdout", 1071 | "output_type": "stream", 1072 | "text": [ 1073 | "[1, 2, 3, 4, 5]\n", 1074 | "====================\n", 1075 | "[1, 2, 3, 4, 5]\n", 1076 | "[1, 2, 3, 4, 5]\n", 1077 | "a cool X value\n", 1078 | "[1, 2, 3, 4, 5]\n", 1079 | "a cool X value\n", 1080 | "a cool Y value\n", 1081 | "====================\n", 1082 | "(4, 1024)\n" 1083 | ] 1084 | } 1085 | ], 1086 | "source": [ 1087 | "# more functions examples\n", 1088 | "def show_data(data):\n", 1089 | " # print the data\n", 1090 | " print (data)\n", 1091 | "\n", 1092 | "some_data = [1,2,3,4,5]\n", 1093 | "show_data(some_data)\n", 1094 | "\n", 1095 | "# you can also define default values for the functions\n", 1096 | "print ('====================')\n", 1097 | "def show_data(data,x=None,y=None):\n", 1098 | " # print the data\n", 1099 | " print (data)\n", 1100 | " if x is not None:\n", 1101 | " print (x)\n", 1102 | " if y is not None:\n", 1103 | " print (y)\n", 1104 | "\n", 1105 | "some_data = [1,2,3,4,5]\n", 1106 | "show_data(some_data);\n", 1107 | "show_data(some_data,x='a cool X value')\n", 1108 | "show_data(some_data,y='a cool Y value',x='a cool X value') \n", 1109 | "\n", 1110 | "# as well as have multiple return types in the function\n", 1111 | "print ('====================')\n", 1112 | "def get_square_and_tenth_power(x):\n", 1113 | " return x**2,x**10\n", 1114 | "\n", 1115 | "print (get_square_and_tenth_power(2) )\n" 1116 | ] 1117 | }, 1118 | { 1119 | "cell_type": "code", 1120 | "execution_count": null, 1121 | "metadata": { 1122 | "collapsed": false 1123 | }, 1124 | "outputs": [], 1125 | "source": [] 1126 | }, 1127 | { 1128 | "cell_type": "code", 1129 | "execution_count": 42, 1130 | "metadata": { 1131 | "collapsed": false 1132 | }, 1133 | "outputs": [ 1134 | { 1135 | "name": "stdout", 1136 | "output_type": "stream", 1137 | "text": [ 1138 | "name: Heart has 1 beats per second\n", 1139 | "This is a long string meant to be so long that the memory for it is not cached by python\n", 1140 | "True\n", 1141 | "False\n" 1142 | ] 1143 | } 1144 | ], 1145 | "source": [ 1146 | "# This is a class that inherits from a generic object\n", 1147 | "class BodyPart(object):\n", 1148 | " kind = \"This is a long string meant to be so long that the memory for it is not cached by python\"\n", 1149 | " # this is a class variable, shared across all instances\n", 1150 | " def __init__(self,name):\n", 1151 | " self.name = name # the name attribute is unique to each instance of the BodyPart class\n", 1152 | "\n", 1153 | "# now define a class that sub classes from the defined BodyPart CLass\n", 1154 | "class Heart(BodyPart):\n", 1155 | " def __init__(self,rate=60,units=\"minute\"):\n", 1156 | " self.rate = rate\n", 1157 | " self.units= units\n", 1158 | " super().__init__(\"Heart\")\n", 1159 | " \n", 1160 | "\n", 1161 | " def print_rate(self):\n", 1162 | " print (\"name: \" + str(self.name) + \" has \" + str(self.rate) + \" beats per \" + self.units) \n", 1163 | " \n", 1164 | "\n", 1165 | "my_heart = Heart(1,\"second\")\n", 1166 | "my_heart.print_rate()\n", 1167 | "\n", 1168 | "generic_part = BodyPart(\"Foot\")\n", 1169 | "print (my_heart.kind)\n", 1170 | "print (my_heart.kind is generic_part.kind) # true, these are the same memory location\n", 1171 | "\n", 1172 | "# take the following for example, these are not the same object\n", 1173 | "a = \"This is a long string meant to be so long that the memory for it is not cached by python\"\n", 1174 | "b = \"This is a long string meant to be so long that the memory for it is not cached by python\"\n", 1175 | "print (a is b) # not the same memory location" 1176 | ] 1177 | }, 1178 | { 1179 | "cell_type": "code", 1180 | "execution_count": 28, 1181 | "metadata": { 1182 | "collapsed": false 1183 | }, 1184 | "outputs": [ 1185 | { 1186 | "name": "stdout", 1187 | "output_type": "stream", 1188 | "text": [ 1189 | "2 5\n", 1190 | "\n", 1191 | "Some value is out of range: list index out of range\n" 1192 | ] 1193 | } 1194 | ], 1195 | "source": [ 1196 | "# error handling and exceptions\n", 1197 | "# Python exception handling.\n", 1198 | "\n", 1199 | "# example reissued from: http://sandbox.mc.edu/~bennet/python/code/exc_py.html\n", 1200 | "\n", 1201 | "# Choose two random integers.\n", 1202 | "import random\n", 1203 | "i = random.randrange(0, 8)\n", 1204 | "j = random.randrange(-1, 6)\n", 1205 | "print (i, j)\n", 1206 | "\n", 1207 | "# Get a nice little array, then try a bunch of dangerous stuff.\n", 1208 | "some = [3, 10, 0, 8, 18];\n", 1209 | "try:\n", 1210 | " # We try to execute this block.\n", 1211 | " den = some[j] / i\n", 1212 | " print (\"A:\", den)\n", 1213 | " frac = (i + j) / den\n", 1214 | " print (\"B:\", frac)\n", 1215 | " if frac < 2:\n", 1216 | " k = 3\n", 1217 | " else:\n", 1218 | " k = 'mike'\n", 1219 | " print (\"C:\", k)\n", 1220 | " print (\"D:\", some[k])\n", 1221 | " # This is the catch block.\n", 1222 | "except ZeroDivisionError:\n", 1223 | " print( \"\\nDivision by zero.\")\n", 1224 | "except TypeError as err:\n", 1225 | " # The detail provides extra information about the exception.\n", 1226 | " print( \"\\nSome type mismatch:\", err)\n", 1227 | "except IndexError as err:\n", 1228 | " print (\"\\nSome value is out of range:\", err)\n", 1229 | "except:\n", 1230 | " # Except without an exception name catches any exception.\n", 1231 | " print( \"\\nSomething else went wrong.\")\n", 1232 | "\n", 1233 | "# An else attached to an except block is run if no exception occurrs.\n", 1234 | "else:\n", 1235 | " print (\"\\nThat's odd, nothing went wrong.\")" 1236 | ] 1237 | }, 1238 | { 1239 | "cell_type": "code", 1240 | "execution_count": 29, 1241 | "metadata": { 1242 | "collapsed": true 1243 | }, 1244 | "outputs": [], 1245 | "source": [ 1246 | "# create a file to read from\n", 1247 | "!echo \"Some File\" > some_file.txt" 1248 | ] 1249 | }, 1250 | { 1251 | "cell_type": "code", 1252 | "execution_count": 30, 1253 | "metadata": { 1254 | "collapsed": false 1255 | }, 1256 | "outputs": [ 1257 | { 1258 | "name": "stdout", 1259 | "output_type": "stream", 1260 | "text": [ 1261 | "Read successfully, file contents:\n", 1262 | "Some File\n", 1263 | "\n" 1264 | ] 1265 | } 1266 | ], 1267 | "source": [ 1268 | "# the with command and opening a file\n", 1269 | "\n", 1270 | "# the regular way of opening a file, lots of error checking\n", 1271 | "try:\n", 1272 | " file = open(\"some_file.txt\")\n", 1273 | " data = file.read()\n", 1274 | "except IOError as err:\n", 1275 | " print (\"\\nCould not read file:\", err)\n", 1276 | "else:\n", 1277 | " print (\"Read successfully, file contents:\")\n", 1278 | " print (data)\n", 1279 | "finally:\n", 1280 | " # this always gets called, close the file if its open\n", 1281 | " if not file.closed:\n", 1282 | " file.close()\n", 1283 | "\n" 1284 | ] 1285 | }, 1286 | { 1287 | "cell_type": "code", 1288 | "execution_count": 31, 1289 | "metadata": { 1290 | "collapsed": false 1291 | }, 1292 | "outputs": [ 1293 | { 1294 | "name": "stdout", 1295 | "output_type": "stream", 1296 | "text": [ 1297 | "Read successfully, file contents:\n", 1298 | "Some File\n", 1299 | "\n", 1300 | "True\n" 1301 | ] 1302 | } 1303 | ], 1304 | "source": [ 1305 | "# the \"file\" class actually has a built in __init__ and __exit__\n", 1306 | "# so we can really on their class implemntation to close the file propoerly\n", 1307 | "# and handle any exceptions gracefully\n", 1308 | "\n", 1309 | "# in that respect, the \"with\" statement is a protocol that the \"file class\" adopts\n", 1310 | "\n", 1311 | "with open(\"some_file.txt\") as file:\n", 1312 | " data = file.read()\n", 1313 | " print (\"Read successfully, file contents:\")\n", 1314 | " print (data)\n", 1315 | "\n", 1316 | "# is the file closed? Let's check\n", 1317 | "print (file.closed)" 1318 | ] 1319 | }, 1320 | { 1321 | "cell_type": "code", 1322 | "execution_count": 32, 1323 | "metadata": { 1324 | "collapsed": false 1325 | }, 1326 | "outputs": [ 1327 | { 1328 | "name": "stdout", 1329 | "output_type": "stream", 1330 | "text": [ 1331 | "1. Just initialized body part with name Lungs\n", 1332 | "2. Building up from \"with\" command\n", 1333 | "3. Hi, my name is: Lungs\n", 1334 | "4. Exit was called, no errors\n" 1335 | ] 1336 | } 1337 | ], 1338 | "source": [ 1339 | "# you can also define your own classes that adopt the \"with\" protocol,\n", 1340 | "# if you are interested check out the example \n", 1341 | "class BodyPart(object):\n", 1342 | " def __init__(self,name):\n", 1343 | " self.name = name\n", 1344 | " print ('1. Just initialized body part with name', name)\n", 1345 | " \n", 1346 | " def __enter__(self):\n", 1347 | " print ('2. Building up from \"with\" command' )\n", 1348 | " return self\n", 1349 | " \n", 1350 | " def __exit__(self, type, value, traceback):\n", 1351 | " if value is not None:\n", 1352 | " print ('4. An error occurred,', value)\n", 1353 | " else:\n", 1354 | " print ('4. Exit was called, no errors')\n", 1355 | " \n", 1356 | " def print_self(self):\n", 1357 | " # 5/0 # uncomment to raise an error\n", 1358 | " print ('3. Hi, my name is:', self.name)\n", 1359 | "\n", 1360 | "with BodyPart(\"Lungs\") as bp:\n", 1361 | " bp.print_self()" 1362 | ] 1363 | }, 1364 | { 1365 | "cell_type": "markdown", 1366 | "metadata": {}, 1367 | "source": [ 1368 | "# Importing Libraries\n", 1369 | "Python shipd with many libraries already packaged. You simply import them using the \"import\" command. However, you can also install many third party libraries, of which there are many for data wrangling. In the next examples we will use some built in libraries, as well as ones that are third party.\n", 1370 | "\n", 1371 | "For installing the third party libraries, you will need to install a package mananger. There are three main ones that you may want to use on your system:\n", 1372 | "+ Anaconda's system (`conda`), https://www.continuum.io/downloads\n", 1373 | "+ Pip, https://pypi.python.org/pypi/pip\n", 1374 | "+ Homebrew, http://brew.sh\n", 1375 | "+ Macports, https://www.macports.org\n", 1376 | " \n", 1377 | "I have had the best luck using anaconda. But you will need to explore the options and decide which one is right for your system. If you are using windows, anaconda or pip is the way to go. If you do not want the setup to affect other libraries installed on your system, consider setting up a virtual environment (which is built into anaconda).\n", 1378 | "\n", 1379 | "Now go our and install the Numpy and Matplotlib systems on your system! It might be as simple as:\n", 1380 | " > conda install numpy\n", 1381 | " > conda install matplotlib" 1382 | ] 1383 | }, 1384 | { 1385 | "cell_type": "code", 1386 | "execution_count": 33, 1387 | "metadata": { 1388 | "collapsed": false 1389 | }, 1390 | "outputs": [ 1391 | { 1392 | "name": "stdout", 1393 | "output_type": "stream", 1394 | "text": [ 1395 | "0.999874127674\n", 1396 | "-1.22464679915e-16\n" 1397 | ] 1398 | } 1399 | ], 1400 | "source": [ 1401 | "# with the package installed, we can import the libraries and use them.\n", 1402 | "\n", 1403 | "# The numpy package is great for working with groups of numbers as matrices\n", 1404 | "# and has many functionalities that are comparable to Matlab and Octave\n", 1405 | "import numpy as np\n", 1406 | "t = np.linspace(0, 1, 100) # 100 equally spaced array of numbers from 0.0 to 1\n", 1407 | "y = np.sin(2 * np.pi * t) # take sine of the value\n", 1408 | "\n", 1409 | "print (np.max(y))\n", 1410 | "print (np.median(y))\n" 1411 | ] 1412 | }, 1413 | { 1414 | "cell_type": "code", 1415 | "execution_count": 34, 1416 | "metadata": { 1417 | "collapsed": false 1418 | }, 1419 | "outputs": [ 1420 | { 1421 | "data": { 1422 | "image/png": "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\n", 1423 | "text/plain": [ 1424 | "" 1425 | ] 1426 | }, 1427 | "metadata": {}, 1428 | "output_type": "display_data" 1429 | } 1430 | ], 1431 | "source": [ 1432 | "# Matplotlib has a number of plotting tools that are extremely powerful for\n", 1433 | "# exploring data. The plotting functionality is simliar to R, but many times\n", 1434 | "# it is easier of more customizable. \n", 1435 | "# Note: everthying you know in \"R\" will come back full circle. Python and R play very \n", 1436 | "# nicely with one another and python can call R code, share memory with it, and use its plotting functions\n", 1437 | "# ...with the correct libraries installed! Check out Rpy2, http://rpy.sourceforge.net \n", 1438 | "\n", 1439 | "%matplotlib inline\n", 1440 | "\n", 1441 | "#============================================\n", 1442 | "# plotting example\n", 1443 | "from matplotlib import pyplot as plt\n", 1444 | "\n", 1445 | "plt.plot(t, y) # plot them\n", 1446 | "plt.show()" 1447 | ] 1448 | }, 1449 | { 1450 | "cell_type": "code", 1451 | "execution_count": 35, 1452 | "metadata": { 1453 | "collapsed": false 1454 | }, 1455 | "outputs": [ 1456 | { 1457 | "name": "stdout", 1458 | "output_type": "stream", 1459 | "text": [ 1460 | "2.6.0\n" 1461 | ] 1462 | } 1463 | ], 1464 | "source": [ 1465 | "# this library ships with python and is for accessing SQL\n", 1466 | "# You will learn how to use the module more extensively in the future!\n", 1467 | "# here, we will just import it and get its version\n", 1468 | "import sqlite3\n", 1469 | "\n", 1470 | "print (sqlite3.version)" 1471 | ] 1472 | }, 1473 | { 1474 | "cell_type": "code", 1475 | "execution_count": 36, 1476 | "metadata": { 1477 | "collapsed": false 1478 | }, 1479 | "outputs": [], 1480 | "source": [ 1481 | "# this is \n", 1482 | "%matplotlib inline" 1483 | ] 1484 | }, 1485 | { 1486 | "cell_type": "markdown", 1487 | "metadata": {}, 1488 | "source": [ 1489 | "# Debugging\n", 1490 | "\n", 1491 | "Debugging in python is much like any other programming language. If you use the command line to run programs, you need to be able to catch and interpret runtime errors. There is no compilation process (that we have talked about), so all errors will occur at runtime--that includes things like spelling errors. Because of this, it is critical to run your code in varying contexts. That also means exploring ways that it could fail by changing the values of different variables.\n", 1492 | "\n", 1493 | "One easy way to do this is by the using the pdb package. You can run it from the iPython notebook, but it gets quite long on the output trace. You will likely want to copy this test over to another document (for example, debugging.py) and run it from the command line (for example, >python debugging.py). The pdb library allows you to set break points in the files and also step through the program, changing the variable values. \n", 1494 | "\n", 1495 | "+ import pdb\n", 1496 | " + pdb.set_trace()\n", 1497 | "+ command line arguments\n", 1498 | " + s(tep), c(ontinue), n(ext), w(here), l(ist), r(eturn), j(ump)\n", 1499 | "+ and much more… like print, p, pp\n", 1500 | "+ can set numbered break points by running from python window\n", 1501 | " + python -m pdb your_function.py " 1502 | ] 1503 | }, 1504 | { 1505 | "cell_type": "code", 1506 | "execution_count": 37, 1507 | "metadata": { 1508 | "collapsed": false 1509 | }, 1510 | "outputs": [ 1511 | { 1512 | "name": "stdout", 1513 | "output_type": "stream", 1514 | "text": [ 1515 | "> (4)()\n", 1516 | "-> for i in range(0,5):\n", 1517 | "(Pdb) c\n", 1518 | "> (4)()\n", 1519 | "-> for i in range(0,5):\n", 1520 | "(Pdb) c\n", 1521 | "> (4)()\n", 1522 | "-> for i in range(0,5):\n", 1523 | "(Pdb) c\n", 1524 | "> (4)()\n", 1525 | "-> for i in range(0,5):\n", 1526 | "(Pdb) c\n", 1527 | "> (4)()\n", 1528 | "-> for i in range(0,5):\n", 1529 | "(Pdb) \n", 1530 | "(Pdb) c\n", 1531 | "50\n" 1532 | ] 1533 | } 1534 | ], 1535 | "source": [ 1536 | "import pdb\n", 1537 | "\n", 1538 | "j = 0\n", 1539 | "for i in range(0,5):\n", 1540 | " j += 5*i\n", 1541 | " pdb.set_trace()\n", 1542 | " \n", 1543 | "print (j)" 1544 | ] 1545 | }, 1546 | { 1547 | "cell_type": "markdown", 1548 | "metadata": {}, 1549 | "source": [ 1550 | "There is still plenty more to learn about python, but now you have the basics. One topic that may be intersting to you is the concept of decorators, discussed here:\n", 1551 | " http://simeonfranklin.com/blog/2012/jul/1/python-decorators-in-12-steps/\n", 1552 | " \n", 1553 | "Essentially, decorators are ways of manipulating functions with other functions. Mostly, this means recycling the functionality of one function to create a new function. \n", 1554 | "\n", 1555 | "There is also much to be learned about iterators, yield, etc. Python is an active language and it is still evolving!" 1556 | ] 1557 | }, 1558 | { 1559 | "cell_type": "code", 1560 | "execution_count": null, 1561 | "metadata": { 1562 | "collapsed": false 1563 | }, 1564 | "outputs": [], 1565 | "source": [] 1566 | } 1567 | ], 1568 | "metadata": { 1569 | "anaconda-cloud": {}, 1570 | "kernelspec": { 1571 | "display_name": "Python [MLEnv]", 1572 | "language": "python", 1573 | "name": "Python [MLEnv]" 1574 | }, 1575 | "language_info": { 1576 | "codemirror_mode": { 1577 | "name": "ipython", 1578 | "version": 3 1579 | }, 1580 | "file_extension": ".py", 1581 | "mimetype": "text/x-python", 1582 | "name": "python", 1583 | "nbconvert_exporter": "python", 1584 | "pygments_lexer": "ipython3", 1585 | "version": "3.5.2" 1586 | } 1587 | }, 1588 | "nbformat": 4, 1589 | "nbformat_minor": 0 1590 | } 1591 | -------------------------------------------------------------------------------- /01_02 Calculator Sandbox.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Start Example III-2" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": { 14 | "collapsed": false, 15 | "slideshow": { 16 | "slide_type": "slide" 17 | } 18 | }, 19 | "outputs": [], 20 | "source": [ 21 | "from __future__ import print_function\n", 22 | "from os import sys\n", 23 | "print(sys.version)" 24 | ] 25 | }, 26 | { 27 | "cell_type": "code", 28 | "execution_count": null, 29 | "metadata": { 30 | "collapsed": false, 31 | "slideshow": { 32 | "slide_type": "slide" 33 | } 34 | }, 35 | "outputs": [], 36 | "source": [ 37 | "# the bar bones calculator\n", 38 | "# Step One, get numbers and symbols from user\n", 39 | "\n", 40 | "print(\"Calculator prompt\")\n", 41 | "user_input = input(\"\")\n", 42 | "print(user_input)" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": null, 48 | "metadata": { 49 | "collapsed": false, 50 | "slideshow": { 51 | "slide_type": "slide" 52 | } 53 | }, 54 | "outputs": [], 55 | "source": [ 56 | "# add procedural function\n", 57 | "def convert_user_input(value):\n", 58 | " return value\n", 59 | "\n", 60 | "print(\"Calculator prompt\")\n", 61 | "user_input = convert_user_input(input(\"\"))\n", 62 | "print(user_input, type(user_input))" 63 | ] 64 | }, 65 | { 66 | "cell_type": "markdown", 67 | "metadata": {}, 68 | "source": [ 69 | "# End Example III-2\n", 70 | "___\n", 71 | "\n", 72 | "# Start Example III-4" 73 | ] 74 | }, 75 | { 76 | "cell_type": "code", 77 | "execution_count": null, 78 | "metadata": { 79 | "collapsed": false, 80 | "slideshow": { 81 | "slide_type": "slide" 82 | } 83 | }, 84 | "outputs": [], 85 | "source": [ 86 | "# add in some logic for converting to number\n", 87 | "def isfloat(value):\n", 88 | " try:\n", 89 | " tmp = float(value)\n", 90 | " return True\n", 91 | " except ValueError:\n", 92 | " return False\n", 93 | " \n", 94 | "def convert_user_input(value):\n", 95 | " if isfloat(value):\n", 96 | " return float(value)\n", 97 | " \n", 98 | " elif(value=='+' or value=='-' or value=='/' or value=='*' or value=='q'):\n", 99 | " return value # leave as is and interpret operation later\n", 100 | "\n", 101 | "print(\"Calculator prompt\")\n", 102 | "user_input = convert_user_input(input(\"\"))\n", 103 | "print(user_input, type(user_input))" 104 | ] 105 | }, 106 | { 107 | "cell_type": "markdown", 108 | "metadata": {}, 109 | "source": [ 110 | "# End Example III-4\n", 111 | "_____\n", 112 | "\n", 113 | "# Start Example III-6" 114 | ] 115 | }, 116 | { 117 | "cell_type": "code", 118 | "execution_count": null, 119 | "metadata": { 120 | "collapsed": false, 121 | "slideshow": { 122 | "slide_type": "slide" 123 | } 124 | }, 125 | "outputs": [], 126 | "source": [ 127 | "# start adding in the evaluation queue \n", 128 | "def isfloat(value):\n", 129 | " try:\n", 130 | " tmp = float(value)\n", 131 | " return True\n", 132 | " except ValueError:\n", 133 | " return False\n", 134 | " \n", 135 | "def convert_user_input(value):\n", 136 | " if isfloat(value):\n", 137 | " return float(value)\n", 138 | " \n", 139 | " elif(value=='+' or value=='-' or value=='/' or value=='*' or value=='q'):\n", 140 | " return value # leave as is and interpret operation later\n", 141 | "\n", 142 | "print(\"Calculator prompt\")\n", 143 | "user_input = ''\n", 144 | "eval_queue = []\n", 145 | "while user_input != 'q': #arbitrary ending for RPN, will fix later\n", 146 | " user_input = convert_user_input(input(\"\"))\n", 147 | " eval_queue.append(user_input)" 148 | ] 149 | }, 150 | { 151 | "cell_type": "code", 152 | "execution_count": null, 153 | "metadata": { 154 | "collapsed": false, 155 | "slideshow": { 156 | "slide_type": "slide" 157 | } 158 | }, 159 | "outputs": [], 160 | "source": [ 161 | "# make the program functional, but not pythonic\n", 162 | "def isfloat(value):\n", 163 | " try:\n", 164 | " tmp = float(value)\n", 165 | " return True\n", 166 | " except ValueError:\n", 167 | " return False\n", 168 | " \n", 169 | "def convert_user_input(value):\n", 170 | " if isfloat(value):\n", 171 | " return float(value)\n", 172 | " \n", 173 | " elif(value=='+' or value=='-' or value=='/' or value=='*' or value=='q'):\n", 174 | " return value # leave as is and interpret operation later\n", 175 | "\n", 176 | "print(\"Calculator prompt\")\n", 177 | "user_input = ''\n", 178 | "eval_queue = []\n", 179 | "while user_input != 'q': #arbitrary ending for RPN, will fix later\n", 180 | " user_input = convert_user_input(input(\"\"))\n", 181 | " eval_queue.append(user_input)\n", 182 | " \n", 183 | " \n", 184 | " if len(eval_queue)>=3 and \\\n", 185 | " (eval_queue[-1]=='+' or eval_queue[-1]=='-' or eval_queue[-1]=='/' or eval_queue[-1]=='*'):\n", 186 | " \n", 187 | " op = eval_queue.pop()\n", 188 | " result = op\n", 189 | " \n", 190 | " v2 = eval_queue.pop()\n", 191 | " v1 = eval_queue.pop()\n", 192 | " if op=='-':\n", 193 | " result = v1-v2\n", 194 | " elif op=='+':\n", 195 | " result = v1+v2\n", 196 | " elif op=='*':\n", 197 | " result = v1*v2\n", 198 | " elif op=='/':\n", 199 | " result = v1/v2\n", 200 | " \n", 201 | " eval_queue.append(result)\n", 202 | " \n", 203 | " print(eval_queue)\n", 204 | " " 205 | ] 206 | }, 207 | { 208 | "cell_type": "code", 209 | "execution_count": null, 210 | "metadata": { 211 | "collapsed": false, 212 | "slideshow": { 213 | "slide_type": "slide" 214 | } 215 | }, 216 | "outputs": [], 217 | "source": [ 218 | "def isoperation(value):\n", 219 | " if(value=='+' or value=='-' or value=='/' or value=='*'):\n", 220 | " return True\n", 221 | " else:\n", 222 | " return False\n", 223 | " \n", 224 | "def isfloat(value):\n", 225 | " try:\n", 226 | " tmp = float(value)\n", 227 | " return True\n", 228 | " except ValueError:\n", 229 | " return False\n", 230 | " \n", 231 | "def convert_user_input(value):\n", 232 | " if isfloat(value):\n", 233 | " return float(value)\n", 234 | " \n", 235 | " elif(isoperation(value) or value=='q'):\n", 236 | " return value # leave as is and interpret operation later\n", 237 | " \n", 238 | "def perform_operation(op,vals):\n", 239 | " \n", 240 | " if op=='-':\n", 241 | " return vals[0]-vals[1]\n", 242 | " elif op=='+':\n", 243 | " return vals[0]+vals[1]\n", 244 | " elif op=='*':\n", 245 | " return vals[0]*vals[1]\n", 246 | " elif op=='/':\n", 247 | " return vals[0]/vals[1]\n", 248 | " \n", 249 | " return op\n", 250 | "\n", 251 | "print(\"Calculator prompt\")\n", 252 | "user_input = ''\n", 253 | "eval_queue = []\n", 254 | "while user_input != 'q': #arbitrary ending for RPN, will fix later\n", 255 | " user_input = convert_user_input(input(\"\"))\n", 256 | " eval_queue.append(user_input)\n", 257 | " \n", 258 | " \n", 259 | " if isoperation(eval_queue[-1]):\n", 260 | " \n", 261 | " op = eval_queue.pop()\n", 262 | " result = op\n", 263 | " \n", 264 | " v2 = eval_queue.pop()\n", 265 | " v1 = eval_queue.pop()\n", 266 | " \n", 267 | " result = perform_operation(op,(v1,v2))\n", 268 | " eval_queue.append(result)\n", 269 | " \n", 270 | " print(eval_queue)\n", 271 | " " 272 | ] 273 | }, 274 | { 275 | "cell_type": "code", 276 | "execution_count": null, 277 | "metadata": { 278 | "collapsed": false, 279 | "slideshow": { 280 | "slide_type": "slide" 281 | } 282 | }, 283 | "outputs": [], 284 | "source": [ 285 | "operations_list = ['+','-','*','/','^']\n", 286 | "# add some functionality and clean up\n", 287 | "def isoperation(value):\n", 288 | " if value in operations_list:\n", 289 | " return True\n", 290 | " else:\n", 291 | " return False\n", 292 | " \n", 293 | "def isfloat(value):\n", 294 | " try:\n", 295 | " tmp = float(value)\n", 296 | " return True\n", 297 | " except ValueError:\n", 298 | " return False\n", 299 | " \n", 300 | "def convert_user_input(value):\n", 301 | " if isfloat(value):\n", 302 | " return float(value)\n", 303 | " \n", 304 | " elif(isoperation(value) or value=='q'):\n", 305 | " return value # leave as is and interpret operation later\n", 306 | " \n", 307 | "def perform_operation(op,vals):\n", 308 | " \n", 309 | " if op=='-':\n", 310 | " return vals[0]-vals[1]\n", 311 | " elif op=='+':\n", 312 | " return vals[0]+vals[1]\n", 313 | " elif op=='*':\n", 314 | " return vals[0]*vals[1]\n", 315 | " elif op=='/':\n", 316 | " return vals[0]/vals[1]\n", 317 | " elif op=='^':\n", 318 | " return vals[0]**vals[1]\n", 319 | " \n", 320 | " return op\n", 321 | "\n", 322 | "print(\"Calculator prompt\")\n", 323 | "user_input = ''\n", 324 | "eval_queue = []\n", 325 | "while user_input != 'q': #arbitrary ending for RPN, will fix later\n", 326 | " user_input = convert_user_input(input(\"\"))\n", 327 | " eval_queue.append(user_input)\n", 328 | " \n", 329 | " if isoperation(eval_queue[-1]):\n", 330 | " \n", 331 | " op = eval_queue.pop()\n", 332 | " result = op\n", 333 | " \n", 334 | " v2 = eval_queue.pop()\n", 335 | " v1 = eval_queue.pop()\n", 336 | " \n", 337 | " result = perform_operation(op,(v1,v2))\n", 338 | " eval_queue.append(result)\n", 339 | " \n", 340 | " print(eval_queue)\n", 341 | " " 342 | ] 343 | }, 344 | { 345 | "cell_type": "markdown", 346 | "metadata": { 347 | "slideshow": { 348 | "slide_type": "notes" 349 | } 350 | }, 351 | "source": [ 352 | "# End Example III-6\n", 353 | "\n", 354 | "\n", 355 | "# END OF WEEK ONE EXAMPLE\n", 356 | "\n", 357 | "___\n", 358 | "\n", 359 | "# START WEEK TWO, EXAMPLE\n", 360 | "- lambdas\n", 361 | "- function passing\n", 362 | "- classes\n", 363 | "- exceptions\n", 364 | "- files\n", 365 | "- comprehensions\n", 366 | "\n", 367 | "\n", 368 | "____\n", 369 | "# Start Example II-2" 370 | ] 371 | }, 372 | { 373 | "cell_type": "code", 374 | "execution_count": 20, 375 | "metadata": { 376 | "collapsed": false, 377 | "slideshow": { 378 | "slide_type": "slide" 379 | } 380 | }, 381 | "outputs": [ 382 | { 383 | "name": "stdout", 384 | "output_type": "stream", 385 | "text": [ 386 | "Calculator prompt\n", 387 | "5\n", 388 | "[5.0]\n", 389 | "6\n", 390 | "[5.0, 6.0]\n", 391 | "+\n", 392 | "[11.0]\n", 393 | "q\n", 394 | "[11.0, 'q']\n" 395 | ] 396 | } 397 | ], 398 | "source": [ 399 | "from __future__ import print_function\n", 400 | "\n", 401 | "import operator as oper\n", 402 | "# add dictionary of operations and function passing\n", 403 | "operations_list = {'+':oper.add,\n", 404 | " '-':oper.sub,\n", 405 | " '*':oper.mul,\n", 406 | " '/':oper.truediv,\n", 407 | " '^':oper.pow,\n", 408 | " '%':oper.mod,\n", 409 | " }\n", 410 | "def isoperation(value):\n", 411 | " if value in operations_list.keys():\n", 412 | " return True\n", 413 | " else:\n", 414 | " return False\n", 415 | " \n", 416 | "def isfloat(value):\n", 417 | " try:\n", 418 | " tmp = float(value)\n", 419 | " return True\n", 420 | " except ValueError:\n", 421 | " return False\n", 422 | " \n", 423 | "def convert_user_input(value):\n", 424 | " if isfloat(value):\n", 425 | " return float(value)\n", 426 | " \n", 427 | " elif(isoperation(value) or value=='q'):\n", 428 | " return value # leave as is and interpret operation later\n", 429 | " \n", 430 | "def perform_operation(op,vals):\n", 431 | " if isoperation(op):\n", 432 | " func = operations_list[op]\n", 433 | " return func(vals[0],vals[1])\n", 434 | " \n", 435 | " return op\n", 436 | "\n", 437 | "print(\"Calculator prompt\")\n", 438 | "user_input = ''\n", 439 | "eval_queue = []\n", 440 | "while user_input != 'q': #arbitrary ending for RPN, will fix later\n", 441 | " user_input = convert_user_input(input(\"\"))\n", 442 | " eval_queue.append(user_input)\n", 443 | " \n", 444 | " if isoperation(eval_queue[-1]):\n", 445 | " \n", 446 | " result = eval_queue.pop()\n", 447 | " \n", 448 | " v2 = eval_queue.pop()\n", 449 | " v1 = eval_queue.pop()\n", 450 | " \n", 451 | " result = perform_operation(result,(v1,v2))\n", 452 | " eval_queue.append(result)\n", 453 | " \n", 454 | " print(eval_queue)\n", 455 | " " 456 | ] 457 | }, 458 | { 459 | "cell_type": "markdown", 460 | "metadata": {}, 461 | "source": [ 462 | "# End Example II-2\n", 463 | "____\n", 464 | "\n", 465 | "# Start Example II-4\n", 466 | "Make it object oriented" 467 | ] 468 | }, 469 | { 470 | "cell_type": "code", 471 | "execution_count": 21, 472 | "metadata": { 473 | "collapsed": false, 474 | "slideshow": { 475 | "slide_type": "slide" 476 | } 477 | }, 478 | "outputs": [ 479 | { 480 | "name": "stdout", 481 | "output_type": "stream", 482 | "text": [ 483 | "Calculator prompt\n", 484 | "5\n", 485 | "[5.0]\n", 486 | "2\n", 487 | "[5.0, 2.0]\n", 488 | "*\n", 489 | "[10.0]\n", 490 | "11\n", 491 | "[10.0, 11.0]\n", 492 | "-\n", 493 | "[-1.0]\n", 494 | "q\n", 495 | "[-1.0, 'q']\n" 496 | ] 497 | } 498 | ], 499 | "source": [ 500 | "# now make into class structure, first pass\n", 501 | "class Calculator:\n", 502 | " def __init__(self):\n", 503 | " \n", 504 | " import operator as oper\n", 505 | " # add dictionary of operations and function passing\n", 506 | " self.operations_list = {'+':oper.add,\n", 507 | " '-':oper.sub,\n", 508 | " '*':oper.mul,\n", 509 | " '/':oper.truediv,\n", 510 | " '^':oper.pow,\n", 511 | " '%':oper.mod,\n", 512 | " }\n", 513 | " \n", 514 | " def isoperation(self, value):\n", 515 | " if value in self.operations_list.keys():\n", 516 | " return True\n", 517 | " else:\n", 518 | " return False\n", 519 | "\n", 520 | " def isfloat(self, value):\n", 521 | " try:\n", 522 | " tmp = float(value)\n", 523 | " return True\n", 524 | " except ValueError:\n", 525 | " return False\n", 526 | "\n", 527 | " def convert_user_input(self, value):\n", 528 | " if self.isfloat(value):\n", 529 | " return float(value)\n", 530 | "\n", 531 | " elif(self.isoperation(value) or value=='q'):\n", 532 | " return value # leave as is and interpret operation later\n", 533 | " \n", 534 | " # else this will return NoneType\n", 535 | "\n", 536 | " def perform_operation(self, op,vals):\n", 537 | " if self.isoperation(op):\n", 538 | " return self.operations_list[op](vals[0],vals[1])\n", 539 | "\n", 540 | " return op\n", 541 | "\n", 542 | "\n", 543 | "print(\"Calculator prompt\")\n", 544 | "user_input = ''\n", 545 | "eval_queue = []\n", 546 | "calc = Calculator()\n", 547 | "while user_input != 'q': #arbitrary ending for RPN, will fix later\n", 548 | " user_input = calc.convert_user_input(input(\"\"))\n", 549 | " eval_queue.append(user_input)\n", 550 | " \n", 551 | " if calc.isoperation(eval_queue[-1]):\n", 552 | " \n", 553 | " result = eval_queue.pop()\n", 554 | " \n", 555 | " v2 = eval_queue.pop()\n", 556 | " v1 = eval_queue.pop()\n", 557 | " \n", 558 | " result = calc.perform_operation(result,(v1,v2))\n", 559 | " eval_queue.append(result)\n", 560 | " \n", 561 | " print(eval_queue)" 562 | ] 563 | }, 564 | { 565 | "cell_type": "code", 566 | "execution_count": 22, 567 | "metadata": { 568 | "collapsed": false, 569 | "slideshow": { 570 | "slide_type": "slide" 571 | } 572 | }, 573 | "outputs": [ 574 | { 575 | "name": "stdout", 576 | "output_type": "stream", 577 | "text": [ 578 | "Calculator\n", 579 | "Operations List: -, +, %, *, ^, /, \n", 580 | "3\n", 581 | "[3.0]\n", 582 | "3\n", 583 | "[3.0, 3.0]\n", 584 | "/\n", 585 | "[1.0]\n", 586 | "4\n", 587 | "[1.0, 4.0]\n", 588 | "^\n", 589 | "[1.0]\n", 590 | "7\n", 591 | "[1.0, 7.0]\n", 592 | "-\n", 593 | "[-6.0]\n", 594 | "+\n" 595 | ] 596 | }, 597 | { 598 | "ename": "IndexError", 599 | "evalue": "pop from empty list", 600 | "output_type": "error", 601 | "traceback": [ 602 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 603 | "\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)", 604 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 79\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 80\u001b[0m \u001b[0;31m# otherwise use calculator model to get results\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 81\u001b[0;31m \u001b[0mcalc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maddto_queue\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0muser_input\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 82\u001b[0m \u001b[0mcalc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprint_queue\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 83\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 605 | "\u001b[0;32m\u001b[0m in \u001b[0;36maddto_queue\u001b[0;34m(self, value)\u001b[0m\n\u001b[1;32m 30\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meval_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 31\u001b[0m \u001b[0mv2\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meval_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 32\u001b[0;31m \u001b[0mv1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meval_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\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 33\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 34\u001b[0m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcalc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mperform_operation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mv2\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 606 | "\u001b[0;31mIndexError\u001b[0m: pop from empty list" 607 | ] 608 | } 609 | ], 610 | "source": [ 611 | "# now lets make this more object oriented and really make the interface and model separate entities\n", 612 | "# Class stucture, second pass\n", 613 | "class Calculator:\n", 614 | " def __init__(self):\n", 615 | " \n", 616 | " import operator as oper\n", 617 | " # add dictionary of operations and function passing\n", 618 | " self.operations_list = {'+':oper.add,\n", 619 | " '-':oper.sub,\n", 620 | " '*':oper.mul,\n", 621 | " '/':oper.truediv,\n", 622 | " '^':oper.pow,\n", 623 | " '%':oper.mod,\n", 624 | " }\n", 625 | " self.eval_queue = []\n", 626 | " \n", 627 | " #==Queue Operations========\n", 628 | " def clear_queue(self):\n", 629 | " self.eval_queue = []\n", 630 | " \n", 631 | " def print_queue(self):\n", 632 | " print(self.eval_queue)\n", 633 | " \n", 634 | " def addto_queue(self,value):\n", 635 | " self.eval_queue.append( self.convert_user_input(value) )\n", 636 | " \n", 637 | " # evaluate operation if it was entered\n", 638 | " if self.isoperation(self.eval_queue[-1]):\n", 639 | "\n", 640 | " result = self.eval_queue.pop()\n", 641 | " v2 = self.eval_queue.pop()\n", 642 | " v1 = self.eval_queue.pop()\n", 643 | "\n", 644 | " result = calc.perform_operation(result,(v1,v2))\n", 645 | " self.eval_queue.append(result)\n", 646 | " \n", 647 | " def print_operations(self):\n", 648 | " # print supported operations\n", 649 | " print('Operations List:', end=' ')\n", 650 | " [print(x, end=', ') for x in self.operations_list.keys()]\n", 651 | " print('')\n", 652 | " \n", 653 | " #==check type Operations========\n", 654 | " def isoperation(self, value):\n", 655 | " if value in self.operations_list.keys():\n", 656 | " return True\n", 657 | " else:\n", 658 | " return False\n", 659 | "\n", 660 | " def isfloat(self, value):\n", 661 | " try:\n", 662 | " tmp = float(value)\n", 663 | " return True\n", 664 | " except ValueError:\n", 665 | " return False\n", 666 | "\n", 667 | " #===evalaute operations============\n", 668 | " def convert_user_input(self, value):\n", 669 | " if self.isfloat(value):\n", 670 | " return float(value)\n", 671 | "\n", 672 | " elif self.isoperation(value) :\n", 673 | " return value # leave as is and interpret operation later\n", 674 | " \n", 675 | " # else this will return NoneType\n", 676 | "\n", 677 | " def perform_operation(self, op,vals):\n", 678 | " if self.isoperation(op):\n", 679 | " return self.operations_list[op](vals[0],vals[1])\n", 680 | " return op\n", 681 | "\n", 682 | "print(\"Calculator\")\n", 683 | "calc = Calculator()\n", 684 | "calc.print_operations()\n", 685 | "while True: #arbitrary ending for RPN, will fix later\n", 686 | " user_input = input(\"\")\n", 687 | " if user_input == 'q':\n", 688 | " break\n", 689 | " \n", 690 | " # otherwise use calculator model to get results\n", 691 | " calc.addto_queue(user_input)\n", 692 | " calc.print_queue()\n", 693 | " \n", 694 | " " 695 | ] 696 | }, 697 | { 698 | "cell_type": "markdown", 699 | "metadata": {}, 700 | "source": [ 701 | "# End Example II-4\n", 702 | "____\n", 703 | "\n", 704 | "# Start Example II-6" 705 | ] 706 | }, 707 | { 708 | "cell_type": "code", 709 | "execution_count": 25, 710 | "metadata": { 711 | "collapsed": false, 712 | "slideshow": { 713 | "slide_type": "slide" 714 | } 715 | }, 716 | "outputs": [ 717 | { 718 | "name": "stdout", 719 | "output_type": "stream", 720 | "text": [ 721 | "Calculator\n", 722 | "Operations List: -, +, %, *, ^, /, \n", 723 | "45\n", 724 | "[45.0]\n", 725 | "5\n", 726 | "[45.0, 5.0]\n", 727 | "+\n", 728 | "[50.0]\n", 729 | "+\n", 730 | "Error: Not enough values to perform operation\n", 731 | "[50.0]\n", 732 | "3\n", 733 | "[50.0, 3.0]\n", 734 | "/\n", 735 | "[16.666666666666668]\n", 736 | "eric\n", 737 | "[16.666666666666668, None]\n", 738 | "+\n" 739 | ] 740 | }, 741 | { 742 | "ename": "TypeError", 743 | "evalue": "unsupported operand type(s) for +: 'float' and 'NoneType'", 744 | "output_type": "error", 745 | "traceback": [ 746 | "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", 747 | "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", 748 | "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 89\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 90\u001b[0m \u001b[0;31m# otherwise use calculator model to get results\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 91\u001b[0;31m \u001b[0mcalc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0maddto_queue\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0muser_input\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 92\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mCalculatorError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0mErr\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 93\u001b[0m \u001b[0mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Error: \"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mErr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", 749 | "\u001b[0;32m\u001b[0m in \u001b[0;36maddto_queue\u001b[0;34m(self, value)\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[0mv1\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meval_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 43\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mcalc\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mperform_operation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv1\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mv2\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 44\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0meval_queue\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mresult\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 750 | "\u001b[0;32m\u001b[0m in \u001b[0;36mperform_operation\u001b[0;34m(self, op, vals)\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mperform_operation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mvals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 77\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0misoperation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 78\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0moperations_list\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mop\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mvals\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mvals\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m1\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 79\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mop\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 80\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", 751 | "\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'float' and 'NoneType'" 752 | ] 753 | } 754 | ], 755 | "source": [ 756 | "# add in some exception handling\n", 757 | "# Class stucture, third pass\n", 758 | "class CalculatorError(ValueError):\n", 759 | " '''raise this when the user causes a mistake from the calculator'''\n", 760 | "\n", 761 | "class Calculator:\n", 762 | " def __init__(self):\n", 763 | " \n", 764 | " import operator as oper\n", 765 | " # add dictionary of operations and function passing\n", 766 | " self.operations_list = {'+':oper.add,\n", 767 | " '-':oper.sub,\n", 768 | " '*':oper.mul,\n", 769 | " '/':oper.truediv,\n", 770 | " '^':oper.pow,\n", 771 | " '%':oper.mod,\n", 772 | " }\n", 773 | " self.eval_queue = []\n", 774 | " \n", 775 | " #==Queue Operations========\n", 776 | " def clear_queue(self):\n", 777 | " self.eval_queue = []\n", 778 | " \n", 779 | " def print_queue(self):\n", 780 | " print(self.eval_queue)\n", 781 | " \n", 782 | " def addto_queue(self,value):\n", 783 | " self.eval_queue.append( self.convert_user_input(value) )\n", 784 | " \n", 785 | " \n", 786 | " # evaluate operation if it was entered\n", 787 | " if self.isoperation(self.eval_queue[-1]):\n", 788 | "\n", 789 | " result = self.eval_queue.pop()\n", 790 | " \n", 791 | " if len(self.eval_queue)<2:\n", 792 | " # not enough elements to perform an operation\n", 793 | " raise CalculatorError('Not enough values to perform operation')\n", 794 | " \n", 795 | " v2 = self.eval_queue.pop()\n", 796 | " v1 = self.eval_queue.pop()\n", 797 | "\n", 798 | " result = calc.perform_operation(result,(v1,v2))\n", 799 | " self.eval_queue.append(result)\n", 800 | " \n", 801 | " def print_operations(self):\n", 802 | " # print supported operations\n", 803 | " print('Operations List:', end=' ')\n", 804 | " [print(x, end=', ') for x in self.operations_list.keys()]\n", 805 | " print('')\n", 806 | " \n", 807 | " #==check type Operations========\n", 808 | " def isoperation(self, value):\n", 809 | " if value in self.operations_list.keys():\n", 810 | " return True\n", 811 | " else:\n", 812 | " return False\n", 813 | "\n", 814 | " def isfloat(self, value):\n", 815 | " try:\n", 816 | " tmp = float(value)\n", 817 | " return True\n", 818 | " except ValueError:\n", 819 | " return False\n", 820 | "\n", 821 | " #===evalaute operations============\n", 822 | " def convert_user_input(self, value):\n", 823 | " if self.isfloat(value):\n", 824 | " return float(value)\n", 825 | "\n", 826 | " elif self.isoperation(value) :\n", 827 | " return value # leave as is and interpret operation later\n", 828 | " \n", 829 | " # else this will return NoneType\n", 830 | "\n", 831 | " def perform_operation(self, op,vals):\n", 832 | " if self.isoperation(op):\n", 833 | " return self.operations_list[op](vals[0],vals[1])\n", 834 | " return op\n", 835 | "\n", 836 | "print(\"Calculator\")\n", 837 | "calc = Calculator()\n", 838 | "calc.print_operations()\n", 839 | "while True: #arbitrary ending for RPN, will fix later\n", 840 | " user_input = input(\"\")\n", 841 | " if user_input == 'q':\n", 842 | " break\n", 843 | " \n", 844 | " try: \n", 845 | " # otherwise use calculator model to get results\n", 846 | " calc.addto_queue(user_input)\n", 847 | " except CalculatorError as Err:\n", 848 | " print(\"Error: \", Err)\n", 849 | " calc.print_queue()\n", 850 | " \n", 851 | " " 852 | ] 853 | }, 854 | { 855 | "cell_type": "code", 856 | "execution_count": 26, 857 | "metadata": { 858 | "collapsed": false, 859 | "slideshow": { 860 | "slide_type": "slide" 861 | } 862 | }, 863 | "outputs": [ 864 | { 865 | "name": "stdout", 866 | "output_type": "stream", 867 | "text": [ 868 | "Calculator\n", 869 | "Operations List: -, +, %, *, ^, /, \n", 870 | "3\n", 871 | "Current Stack: [3.0]\n", 872 | "+\n", 873 | "Error: Not enough values to perform operation\n", 874 | "Current Stack: [3.0]\n", 875 | "eric\n", 876 | "Error: Invalid entry. Entry must be number or supported operator.\n", 877 | "Current Stack: [3.0]\n", 878 | "4\n", 879 | "Current Stack: [3.0, 4.0]\n", 880 | "_\n", 881 | "Error: Invalid entry. Entry must be number or supported operator.\n", 882 | "Current Stack: [3.0, 4.0]\n", 883 | "-\n", 884 | "Current Stack: [-1.0]\n", 885 | "q\n" 886 | ] 887 | } 888 | ], 889 | "source": [ 890 | "# add in some exception handling\n", 891 | "# Class stucture, fourth pass\n", 892 | "class CalculatorError(ValueError):\n", 893 | " '''raise this when the user causes a mistake from the calculator'''\n", 894 | "\n", 895 | "class Calculator:\n", 896 | " def __init__(self):\n", 897 | " \n", 898 | " import operator as oper\n", 899 | " # add dictionary of operations and function passing\n", 900 | " self.operations_list = {'+':oper.add,\n", 901 | " '-':oper.sub,\n", 902 | " '*':oper.mul,\n", 903 | " '/':oper.truediv,\n", 904 | " '^':oper.pow,\n", 905 | " '%':oper.mod,\n", 906 | " }\n", 907 | " self.eval_queue = []\n", 908 | " \n", 909 | " #==Queue Operations========\n", 910 | " def clear_queue(self):\n", 911 | " self.eval_queue = []\n", 912 | " \n", 913 | " def print_queue(self):\n", 914 | " print(\"Current Stack:\", self.eval_queue)\n", 915 | " \n", 916 | " def addto_queue(self,value):\n", 917 | " tmp = self.convert_user_input(value)\n", 918 | " self.eval_queue.append( tmp )\n", 919 | " \n", 920 | " \n", 921 | " # evaluate operation if it was entered\n", 922 | " if self.isoperation(self.eval_queue[-1]):\n", 923 | "\n", 924 | " result = self.eval_queue.pop()\n", 925 | " \n", 926 | " if len(self.eval_queue)<2:\n", 927 | " # not enough elements to perform an operation\n", 928 | " raise CalculatorError('Not enough values to perform operation')\n", 929 | " \n", 930 | " v2 = self.eval_queue.pop()\n", 931 | " v1 = self.eval_queue.pop()\n", 932 | "\n", 933 | " result = calc.perform_operation(result,(v1,v2))\n", 934 | " self.eval_queue.append(result)\n", 935 | " \n", 936 | " def print_operations(self):\n", 937 | " # print supported operations\n", 938 | " print('Operations List:', end=' ')\n", 939 | " [print(x, end=', ') for x in self.operations_list.keys()]\n", 940 | " print('')\n", 941 | " \n", 942 | " #==check type Operations========\n", 943 | " def isoperation(self, value):\n", 944 | " if value in self.operations_list.keys():\n", 945 | " return True\n", 946 | " else:\n", 947 | " return False\n", 948 | "\n", 949 | " def isfloat(self, value):\n", 950 | " try:\n", 951 | " tmp = float(value)\n", 952 | " return True\n", 953 | " except ValueError:\n", 954 | " return False\n", 955 | "\n", 956 | " \n", 957 | " def convert_user_input(self, value):\n", 958 | " if self.isfloat(value):\n", 959 | " return float(value)\n", 960 | " elif self.isoperation(value) :\n", 961 | " return value # leave as is and interpret operation later\n", 962 | " else:\n", 963 | " raise CalculatorError('Invalid entry. Entry must be number or supported operator.')\n", 964 | "\n", 965 | " #===evalaute operations============\n", 966 | " def perform_operation(self, op,vals):\n", 967 | " if self.isoperation(op):\n", 968 | " return self.operations_list[op](vals[0],vals[1])\n", 969 | " return op\n", 970 | "\n", 971 | "print(\"Calculator\")\n", 972 | "calc = Calculator()\n", 973 | "calc.print_operations()\n", 974 | "while True: #arbitrary ending for RPN, will fix later\n", 975 | " user_input = input(\"\")\n", 976 | " if user_input == 'q':\n", 977 | " break\n", 978 | "\n", 979 | " try: \n", 980 | " # otherwise use calculator model to get results\n", 981 | " calc.addto_queue(user_input)\n", 982 | " except CalculatorError as Err:\n", 983 | " print(\"Error: \", Err)\n", 984 | " calc.print_queue()\n", 985 | " \n", 986 | " " 987 | ] 988 | }, 989 | { 990 | "cell_type": "markdown", 991 | "metadata": {}, 992 | "source": [ 993 | "# End Example II-6\n", 994 | "\n", 995 | "____\n", 996 | "\n", 997 | "# Start Example II-8" 998 | ] 999 | }, 1000 | { 1001 | "cell_type": "code", 1002 | "execution_count": 35, 1003 | "metadata": { 1004 | "collapsed": false, 1005 | "slideshow": { 1006 | "slide_type": "slide" 1007 | } 1008 | }, 1009 | "outputs": [ 1010 | { 1011 | "name": "stdout", 1012 | "output_type": "stream", 1013 | "text": [ 1014 | "Calculator\n", 1015 | "Operations List: -, abs, +, %, *, ^, tan, /, sine, cosine, \n", 1016 | "56\n", 1017 | "Current Stack: [56.0]\n", 1018 | "tan\n", 1019 | "Current Stack: [-0.6112736881917098]\n", 1020 | "q\n" 1021 | ] 1022 | } 1023 | ], 1024 | "source": [ 1025 | "# add in custom user functions from JSON file\n", 1026 | "# Class structure, fifth pass\n", 1027 | "class CalculatorError(ValueError):\n", 1028 | " '''raise this when the user causes a mistake from the calculator'''\n", 1029 | "\n", 1030 | "class Operator:\n", 1031 | " def __init__(self, func, num_args=2):\n", 1032 | " self.func = func\n", 1033 | " self.num_args = num_args\n", 1034 | " \n", 1035 | " \n", 1036 | "class CustomCalculator(Calculator):\n", 1037 | " def __init__(self):\n", 1038 | " # THIS OVERWRITES THE INIT FUNCTION OF INHERITED CLASS\n", 1039 | " import operator as oper\n", 1040 | " # add dictionary of operations and function passing, include basic operations here\n", 1041 | " self.operations_list = {'+':Operator(oper.add),\n", 1042 | " '-':Operator(oper.sub),\n", 1043 | " '*':Operator(oper.mul),\n", 1044 | " '/':Operator(oper.truediv),\n", 1045 | " '^':Operator(oper.pow),\n", 1046 | " '%':Operator(oper.mod),\n", 1047 | " 'abs':Operator(oper.abs,num_args=1),\n", 1048 | " }\n", 1049 | " self.eval_queue = []\n", 1050 | " \n", 1051 | " def add_custom_operations(self,filename):\n", 1052 | " import json\n", 1053 | " with open(filename) as file:\n", 1054 | " data = json.loads(file.read()) # Grab file data\n", 1055 | "\n", 1056 | " import math\n", 1057 | " for key,module in data.items():\n", 1058 | " if hasattr(math, module):\n", 1059 | " self.operations_list[key] = Operator(getattr(math, module), num_args = 1)\n", 1060 | " \n", 1061 | " def addto_queue(self,value):\n", 1062 | " tmp = self.convert_user_input(value)\n", 1063 | " self.eval_queue.append( tmp )\n", 1064 | " \n", 1065 | " \n", 1066 | " # evaluate operation if it was entered\n", 1067 | " if self.isoperation(self.eval_queue[-1]):\n", 1068 | "\n", 1069 | " result = self.eval_queue.pop()\n", 1070 | " num_args = self.operations_list[result].num_args\n", 1071 | " \n", 1072 | " if len(self.eval_queue)\n" 304 | ] 305 | } 306 | ], 307 | "source": [ 308 | "print(var)\n", 309 | "print(type(var))" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": null, 315 | "metadata": { 316 | "collapsed": true 317 | }, 318 | "outputs": [], 319 | "source": [] 320 | } 321 | ], 322 | "metadata": { 323 | "anaconda-cloud": {}, 324 | "kernelspec": { 325 | "display_name": "Python 3", 326 | "language": "python", 327 | "name": "python3" 328 | }, 329 | "language_info": { 330 | "codemirror_mode": { 331 | "name": "ipython", 332 | "version": 3 333 | }, 334 | "file_extension": ".py", 335 | "mimetype": "text/x-python", 336 | "name": "python", 337 | "nbconvert_exporter": "python", 338 | "pygments_lexer": "ipython3", 339 | "version": "3.5.2" 340 | } 341 | }, 342 | "nbformat": 4, 343 | "nbformat_minor": 0 344 | } 345 | -------------------------------------------------------------------------------- /03b. CalculatorWithR.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "_____\n", 8 | "\n", 9 | "# Start Example III-3" 10 | ] 11 | }, 12 | { 13 | "cell_type": "code", 14 | "execution_count": 6, 15 | "metadata": { 16 | "collapsed": false 17 | }, 18 | "outputs": [ 19 | { 20 | "name": "stdout", 21 | "output_type": "stream", 22 | "text": [ 23 | "Calculator\n", 24 | "Operations List: sine, %, abs, tan, *, +, /, ^, cosine, -, \n", 25 | "45\n", 26 | "Current Stack: [45.0]\n", 27 | "3\n", 28 | "Current Stack: [45.0, 3.0]\n", 29 | "*\n", 30 | "Current Stack: [135.0]\n", 31 | "q\n" 32 | ] 33 | } 34 | ], 35 | "source": [ 36 | "# this file should be saved so that it is on the path or in the same directory as this notebook\n", 37 | "from __future__ import print_function\n", 38 | "from calculators import CustomCalculator\n", 39 | "from calculators import CalculatorError\n", 40 | "\n", 41 | "print(\"Calculator\")\n", 42 | "calc = CustomCalculator()\n", 43 | "calc.add_custom_operations('operators.json') # new function\n", 44 | "calc.print_operations() # inherited function\n", 45 | "\n", 46 | "while True: \n", 47 | " user_input = input(\"\")\n", 48 | " if user_input == 'q':\n", 49 | " break\n", 50 | " \n", 51 | " try: \n", 52 | " # otherwise use calculator model to get results\n", 53 | " calc.addto_queue(user_input) # overwritten function\n", 54 | " except CalculatorError as Err:\n", 55 | " print(\"Error: \", Err) \n", 56 | " \n", 57 | " calc.print_queue()\n", 58 | " " 59 | ] 60 | }, 61 | { 62 | "cell_type": "code", 63 | "execution_count": 8, 64 | "metadata": { 65 | "collapsed": false 66 | }, 67 | "outputs": [ 68 | { 69 | "name": "stdout", 70 | "output_type": "stream", 71 | "text": [ 72 | "Calculator\n", 73 | "Operations List: sine, %, abs, tan, *, cosine, ^, gauss, -, **, /, +, \n", 74 | "34\n", 75 | "Current Stack: [34.0]\n", 76 | "2\n", 77 | "Current Stack: [34.0, 2.0]\n", 78 | "**\n", 79 | "Current Stack: [1156.0]\n", 80 | "1\n", 81 | "Current Stack: [1156.0, 1.0]\n", 82 | "1\n", 83 | "Current Stack: [1156.0, 1.0, 1.0]\n", 84 | "gauss\n", 85 | "Current Stack: [0.00034510577889397293]\n", 86 | "q\n" 87 | ] 88 | } 89 | ], 90 | "source": [ 91 | "from calculators import Operator\n", 92 | "\n", 93 | "# now addin a custom calculator class that can add in other operations written in notebook\n", 94 | "class NotebookCalculator(CustomCalculator):\n", 95 | " def add_custom_function(self, func, key, num_args=1):\n", 96 | " self.operations_list[key] = Operator(func, num_args = num_args)\n", 97 | " \n", 98 | "# some user defined functions\n", 99 | "# extend the power function to also have ** operator\n", 100 | "def power(arg1, arg2):\n", 101 | " return arg2**arg1\n", 102 | "\n", 103 | "def gaussian(x,u=0.0,std=1.0):\n", 104 | " import math\n", 105 | " return math.exp((x-u)/(2*std**2))/math.sqrt(2*math.pi*std**2)\n", 106 | " \n", 107 | "\n", 108 | "print(\"Calculator\")\n", 109 | "calc = NotebookCalculator()\n", 110 | "calc.add_custom_operations('operators.json') \n", 111 | " \n", 112 | "calc.add_custom_function(power,'**',num_args=2)\n", 113 | "calc.add_custom_function(gaussian,'gauss',num_args=3) \n", 114 | " \n", 115 | "calc.print_operations() # inherited function\n", 116 | "\n", 117 | "while True: \n", 118 | " user_input = input(\"\")\n", 119 | " if user_input == 'q':\n", 120 | " break\n", 121 | " \n", 122 | " try: \n", 123 | " # otherwise use calculator model to get results\n", 124 | " calc.addto_queue(user_input) # overwritten function\n", 125 | " except CalculatorError as Err:\n", 126 | " print(\"Error: \", Err) \n", 127 | " \n", 128 | " calc.print_queue()\n", 129 | " " 130 | ] 131 | }, 132 | { 133 | "cell_type": "markdown", 134 | "metadata": {}, 135 | "source": [ 136 | "# End Example III-3\n", 137 | "\n", 138 | "_____\n", 139 | "\n", 140 | "# Start Example III-4\n", 141 | "Using Rpy2" 142 | ] 143 | }, 144 | { 145 | "cell_type": "code", 146 | "execution_count": 9, 147 | "metadata": { 148 | "collapsed": false 149 | }, 150 | "outputs": [ 151 | { 152 | "name": "stdout", 153 | "output_type": "stream", 154 | "text": [ 155 | "The rpy2.ipython extension is already loaded. To reload it, use:\n", 156 | " %reload_ext rpy2.ipython\n" 157 | ] 158 | } 159 | ], 160 | "source": [ 161 | "\n", 162 | "%load_ext rpy2.ipython" 163 | ] 164 | }, 165 | { 166 | "cell_type": "code", 167 | "execution_count": 10, 168 | "metadata": { 169 | "collapsed": false 170 | }, 171 | "outputs": [ 172 | { 173 | "name": "stdout", 174 | "output_type": "stream", 175 | "text": [ 176 | "[ 16.]\n" 177 | ] 178 | } 179 | ], 180 | "source": [ 181 | "input_arg_name = 2\n", 182 | "%R -i input_arg_name -o output_arg_name output_arg_name=input_arg_name^4\n", 183 | "print(output_arg_name)" 184 | ] 185 | }, 186 | { 187 | "cell_type": "code", 188 | "execution_count": 11, 189 | "metadata": { 190 | "collapsed": false 191 | }, 192 | "outputs": [ 193 | { 194 | "data": { 195 | "text/plain": [ 196 | "256.0" 197 | ] 198 | }, 199 | "execution_count": 11, 200 | "metadata": {}, 201 | "output_type": "execute_result" 202 | } 203 | ], 204 | "source": [ 205 | "def r_func(input_arg):\n", 206 | " %R -i input_arg -o output_arg_name output_arg_name<-input_arg^4\n", 207 | " return output_arg_name[0]\n", 208 | "\n", 209 | "r_func(4)" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": 12, 215 | "metadata": { 216 | "collapsed": false 217 | }, 218 | "outputs": [ 219 | { 220 | "name": "stdout", 221 | "output_type": "stream", 222 | "text": [ 223 | "Calculator\n", 224 | "Operations List: sine, %, abs, tan, *, cosine, ^, gauss, -, **, /, 4th, +, \n", 225 | "3\n", 226 | "Current Stack: [3.0]\n", 227 | "4th\n", 228 | "Current Stack: [81.0]\n", 229 | "q\n" 230 | ] 231 | } 232 | ], 233 | "source": [ 234 | "print(\"Calculator\")\n", 235 | "calc = NotebookCalculator()\n", 236 | "calc.add_custom_operations('operators.json') \n", 237 | " \n", 238 | "calc.add_custom_function(power,'**',num_args=2)\n", 239 | "calc.add_custom_function(gaussian,'gauss',num_args=3) \n", 240 | "calc.add_custom_function(r_func,'4th',num_args=1) \n", 241 | " \n", 242 | "calc.print_operations() # inherited function\n", 243 | "\n", 244 | "while True: \n", 245 | " user_input = input(\"\")\n", 246 | " if user_input == 'q':\n", 247 | " break\n", 248 | " \n", 249 | " try: \n", 250 | " # otherwise use calculator model to get results\n", 251 | " calc.addto_queue(user_input) # overwritten function\n", 252 | " except CalculatorError as Err:\n", 253 | " print(\"Error: \", Err) \n", 254 | " \n", 255 | " calc.print_queue()" 256 | ] 257 | }, 258 | { 259 | "cell_type": "code", 260 | "execution_count": 13, 261 | "metadata": { 262 | "collapsed": false 263 | }, 264 | "outputs": [], 265 | "source": [ 266 | "%%R\n", 267 | "# Create a function to sum squares of numbers in sequence.\n", 268 | "sum_vector <- function(a) {\n", 269 | " b = 0\n", 270 | " for(i in 1:a) {\n", 271 | " b = b+i^2\n", 272 | " }\n", 273 | " return(b) # last variable evaluated will be returned\n", 274 | "}" 275 | ] 276 | }, 277 | { 278 | "cell_type": "code", 279 | "execution_count": 14, 280 | "metadata": { 281 | "collapsed": false 282 | }, 283 | "outputs": [ 284 | { 285 | "name": "stdout", 286 | "output_type": "stream", 287 | "text": [ 288 | "14.0\n" 289 | ] 290 | } 291 | ], 292 | "source": [ 293 | "%R -o out out=sum_vector(3)\n", 294 | "print(out[0])" 295 | ] 296 | }, 297 | { 298 | "cell_type": "code", 299 | "execution_count": 15, 300 | "metadata": { 301 | "collapsed": false 302 | }, 303 | "outputs": [], 304 | "source": [ 305 | "# back to python, but R workspace is still active\n", 306 | "# wrap it in a python function for the calculator\n", 307 | "def sum_vector_in_r(arg):\n", 308 | " %R -i arg -o out out=sum_vector(arg)\n", 309 | " return out[0]" 310 | ] 311 | }, 312 | { 313 | "cell_type": "code", 314 | "execution_count": 16, 315 | "metadata": { 316 | "collapsed": false 317 | }, 318 | "outputs": [ 319 | { 320 | "name": "stdout", 321 | "output_type": "stream", 322 | "text": [ 323 | "Calculator\n", 324 | "Operations List: sine, %, abs, tan, *, cosine, ^, gauss, -, **, /, 4th, +, sumvect, \n", 325 | "10\n", 326 | "Current Stack: [10.0]\n", 327 | "sumvect\n", 328 | "Current Stack: [385.0]\n", 329 | "q\n" 330 | ] 331 | } 332 | ], 333 | "source": [ 334 | "print(\"Calculator\")\n", 335 | "calc = NotebookCalculator()\n", 336 | "calc.add_custom_operations('operators.json') \n", 337 | " \n", 338 | "calc.add_custom_function(power,'**',num_args=2)\n", 339 | "calc.add_custom_function(gaussian,'gauss',num_args=3) \n", 340 | "calc.add_custom_function(r_func,'4th',num_args=1) \n", 341 | "calc.add_custom_function(sum_vector_in_r,'sumvect',num_args=1) \n", 342 | " \n", 343 | "calc.print_operations() # inherited function\n", 344 | "\n", 345 | "while True: \n", 346 | " user_input = input(\"\")\n", 347 | " if user_input == 'q':\n", 348 | " break\n", 349 | " \n", 350 | " try: \n", 351 | " # otherwise use calculator model to get results\n", 352 | " calc.addto_queue(user_input) # overwritten function\n", 353 | " except CalculatorError as Err:\n", 354 | " print(\"Error: \", Err) \n", 355 | " \n", 356 | " calc.print_queue()" 357 | ] 358 | }, 359 | { 360 | "cell_type": "code", 361 | "execution_count": null, 362 | "metadata": { 363 | "collapsed": true 364 | }, 365 | "outputs": [], 366 | "source": [] 367 | } 368 | ], 369 | "metadata": { 370 | "kernelspec": { 371 | "display_name": "Python 3", 372 | "language": "python", 373 | "name": "python3" 374 | }, 375 | "language_info": { 376 | "codemirror_mode": { 377 | "name": "ipython", 378 | "version": 3 379 | }, 380 | "file_extension": ".py", 381 | "mimetype": "text/x-python", 382 | "name": "python", 383 | "nbconvert_exporter": "python", 384 | "pygments_lexer": "ipython3", 385 | "version": "3.5.2" 386 | } 387 | }, 388 | "nbformat": 4, 389 | "nbformat_minor": 0 390 | } 391 | -------------------------------------------------------------------------------- /04 Optimize.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Example III-1\n", 8 | "# Linear Algebra Review with a Few Numpy Operations" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "metadata": { 15 | "collapsed": false 16 | }, 17 | "outputs": [], 18 | "source": [ 19 | "import numpy as np\n", 20 | "# numpy examples (these will work for python 3 only)\n", 21 | "# in python 3, they have overloaded the @ operator to perform matrix multiplication\n", 22 | "\n", 23 | "a = np.array([[0,1,2],\n", 24 | " [3,4,5]])\n", 25 | "\n", 26 | "print(a)\n", 27 | "print('---')\n", 28 | "print(a.T)\n", 29 | "print('---')\n", 30 | "print(a.flatten())" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": null, 36 | "metadata": { 37 | "collapsed": false 38 | }, 39 | "outputs": [], 40 | "source": [ 41 | "a = np.array([1,2], float)\n", 42 | "b = np.array([3,4,5,6], float)\n", 43 | "c = np.array([7,8,9], float)\n", 44 | "np.concatenate((a, b, c))" 45 | ] 46 | }, 47 | { 48 | "cell_type": "code", 49 | "execution_count": null, 50 | "metadata": { 51 | "collapsed": false 52 | }, 53 | "outputs": [], 54 | "source": [ 55 | "a = np.array([[1, 2], [3, 4]], float)\n", 56 | "b = np.array([[5, 6], [7,8]], float)\n", 57 | "np.concatenate((a,b))" 58 | ] 59 | }, 60 | { 61 | "cell_type": "code", 62 | "execution_count": null, 63 | "metadata": { 64 | "collapsed": false 65 | }, 66 | "outputs": [], 67 | "source": [ 68 | "print(np.concatenate((a,b), axis=0))\n", 69 | "print(np.concatenate((a,b), axis=1))" 70 | ] 71 | }, 72 | { 73 | "cell_type": "code", 74 | "execution_count": null, 75 | "metadata": { 76 | "collapsed": false 77 | }, 78 | "outputs": [], 79 | "source": [ 80 | "a = np.array([1, 2, 3], float)\n", 81 | "print(a)\n", 82 | "print('---')\n", 83 | "print(a[:,np.newaxis])\n", 84 | "print('---')\n", 85 | "print(a[:,np.newaxis].shape)" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": { 92 | "collapsed": false 93 | }, 94 | "outputs": [], 95 | "source": [ 96 | "print(b[np.newaxis,:])\n", 97 | "print('---')\n", 98 | "print(b[np.newaxis,:].shape)" 99 | ] 100 | }, 101 | { 102 | "cell_type": "code", 103 | "execution_count": null, 104 | "metadata": { 105 | "collapsed": false 106 | }, 107 | "outputs": [], 108 | "source": [ 109 | "a = np.array([1,2,3], float)\n", 110 | "b = np.array([5,2,6], float)\n", 111 | "\n", 112 | "print('+ ', a + b)\n", 113 | "print('- ', a - b)\n", 114 | "print('* ', a * b)\n", 115 | "print('/ ', a / b)\n", 116 | "print('% ', a % b)\n", 117 | "print('**', b**a)\n", 118 | "print('@ ', a @ b)" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": null, 124 | "metadata": { 125 | "collapsed": false 126 | }, 127 | "outputs": [], 128 | "source": [ 129 | "# broadcasting\n", 130 | "a = np.array([[1, 2], [3, 4], [5, 6]], float)\n", 131 | "b = np.array([-1, 3], float)\n", 132 | "a\n", 133 | "b\n", 134 | "\n", 135 | "print(a + b)" 136 | ] 137 | }, 138 | { 139 | "cell_type": "code", 140 | "execution_count": null, 141 | "metadata": { 142 | "collapsed": false 143 | }, 144 | "outputs": [], 145 | "source": [ 146 | "np.unique([0,3,56,63,45,3234,3,24,76,4,234,6,3])" 147 | ] 148 | }, 149 | { 150 | "cell_type": "code", 151 | "execution_count": null, 152 | "metadata": { 153 | "collapsed": false 154 | }, 155 | "outputs": [], 156 | "source": [ 157 | "# indexing\n", 158 | "a = np.array([[1, 4.5, 1500],\n", 159 | " [5, 3.5, 800],\n", 160 | " [2, 0.5, 1300]])\n", 161 | "\n", 162 | "print(a[:,0])\n", 163 | "print(a[0,:])" 164 | ] 165 | }, 166 | { 167 | "cell_type": "code", 168 | "execution_count": null, 169 | "metadata": { 170 | "collapsed": false 171 | }, 172 | "outputs": [], 173 | "source": [ 174 | "print(a[:,0]>=2)\n", 175 | "print('---')\n", 176 | "print(a[ a[:,0]>=2 ])" 177 | ] 178 | }, 179 | { 180 | "cell_type": "code", 181 | "execution_count": null, 182 | "metadata": { 183 | "collapsed": false 184 | }, 185 | "outputs": [], 186 | "source": [ 187 | "print(np.trace(a))\n", 188 | "print('---')\n", 189 | "print(np.diagonal(a))\n", 190 | "print('---')\n", 191 | "\n", 192 | "v = np.diagonal(a)\n", 193 | "print(np.sum(v))\n", 194 | "print('---')\n", 195 | "print(np.diag(v))" 196 | ] 197 | }, 198 | { 199 | "cell_type": "code", 200 | "execution_count": null, 201 | "metadata": { 202 | "collapsed": false 203 | }, 204 | "outputs": [], 205 | "source": [ 206 | "from numpy import linalg as lin\n", 207 | "print(lin.det(a))\n", 208 | "print('---')\n", 209 | "print(lin.inv(a))" 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": null, 215 | "metadata": { 216 | "collapsed": false 217 | }, 218 | "outputs": [], 219 | "source": [ 220 | "vals, vects =lin.eig(a)\n", 221 | "print(vals)\n", 222 | "print('---')\n", 223 | "print(vects)" 224 | ] 225 | }, 226 | { 227 | "cell_type": "markdown", 228 | "metadata": {}, 229 | "source": [ 230 | "___\n", 231 | "# Example III-1" 232 | ] 233 | }, 234 | { 235 | "cell_type": "code", 236 | "execution_count": 14, 237 | "metadata": { 238 | "collapsed": false 239 | }, 240 | "outputs": [ 241 | { 242 | "name": "stdout", 243 | "output_type": "stream", 244 | "text": [ 245 | "[[-1 -2]\n", 246 | " [ 3 1]\n", 247 | " [ 4 5]]\n", 248 | "---\n", 249 | "[[ 0.2 0.8]]\n", 250 | "---\n" 251 | ] 252 | }, 253 | { 254 | "data": { 255 | "text/plain": [ 256 | "array([[-1.8],\n", 257 | " [ 1.4],\n", 258 | " [ 4.8]])" 259 | ] 260 | }, 261 | "execution_count": 14, 262 | "metadata": {}, 263 | "output_type": "execute_result" 264 | } 265 | ], 266 | "source": [ 267 | "import numpy as np\n", 268 | "# show formats for the function\n", 269 | "x = np.array([[-1, -2],\n", 270 | " [3, 1],\n", 271 | " [4, 5],\n", 272 | " ]) # make column\n", 273 | "\n", 274 | "w = np.array([[0.2 , 0.8]])\n", 275 | "\n", 276 | "print(x)\n", 277 | "print('---')\n", 278 | "print(w)\n", 279 | "print('---')\n", 280 | "np.dot(x,w.T)" 281 | ] 282 | }, 283 | { 284 | "cell_type": "code", 285 | "execution_count": 15, 286 | "metadata": { 287 | "collapsed": false 288 | }, 289 | "outputs": [ 290 | { 291 | "data": { 292 | "text/plain": [ 293 | "array([[ 0.14185106],\n", 294 | " [ 0.80218389],\n", 295 | " [ 0.99183743]])" 296 | ] 297 | }, 298 | "execution_count": 15, 299 | "metadata": {}, 300 | "output_type": "execute_result" 301 | } 302 | ], 303 | "source": [ 304 | "\n", 305 | "def yhat(x,w):\n", 306 | " return 1/(1+np.exp(-np.dot(x,w.T)))\n", 307 | "\n", 308 | "yhat(x,w)" 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": 16, 314 | "metadata": { 315 | "collapsed": true 316 | }, 317 | "outputs": [], 318 | "source": [ 319 | "# create objective function\n", 320 | "def obj(w,x,y):\n", 321 | " return np.sum((y-yhat(x,w))**2)" 322 | ] 323 | }, 324 | { 325 | "cell_type": "code", 326 | "execution_count": 17, 327 | "metadata": { 328 | "collapsed": false 329 | }, 330 | "outputs": [ 331 | { 332 | "name": "stdout", 333 | "output_type": "stream", 334 | "text": [ 335 | "0.336959748046\n", 336 | "---\n", 337 | "0.316656051456\n", 338 | "---\n", 339 | "0.319908985509\n" 340 | ] 341 | } 342 | ], 343 | "source": [ 344 | "# example \n", 345 | "x_rand = (np.random.rand(100,2)-0.5)*2 # n_rows by n_cols\n", 346 | "\n", 347 | "w_exact = np.array([5,3])\n", 348 | "y = yhat(x_rand,w_exact) # generate a function\n", 349 | "y = y + np.random.randn(*y.shape)*0.055 # add random Gaussian noise\n", 350 | "\n", 351 | "w_temp = np.array([5.5,3.2])\n", 352 | "print(obj(w_temp, x_rand, y) )\n", 353 | "\n", 354 | "print('---')\n", 355 | "w_temp = np.array([5.1,3.1])\n", 356 | "print(obj(w_temp, x_rand, y))\n", 357 | "\n", 358 | "print('---')\n", 359 | "print(obj(w_exact, x_rand, y) )" 360 | ] 361 | }, 362 | { 363 | "cell_type": "code", 364 | "execution_count": 18, 365 | "metadata": { 366 | "collapsed": false 367 | }, 368 | "outputs": [ 369 | { 370 | "data": { 371 | "text/plain": [ 372 | "" 373 | ] 374 | }, 375 | "execution_count": 18, 376 | "metadata": {}, 377 | "output_type": "execute_result" 378 | }, 379 | { 380 | "data": { 381 | "image/png": "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\n", 382 | "text/plain": [ 383 | "" 384 | ] 385 | }, 386 | "metadata": {}, 387 | "output_type": "display_data" 388 | } 389 | ], 390 | "source": [ 391 | "# simple graphing example\n", 392 | "from matplotlib import pyplot as plt\n", 393 | "%matplotlib inline\n", 394 | "\n", 395 | "plt.subplot(1,2,1)\n", 396 | "plt.plot(np.dot(x_rand,w_exact.T),y,'.')\n", 397 | "plt.title('Close w to actual')\n", 398 | "\n", 399 | "w_temp = np.array([5.5,0.2])\n", 400 | "plt.subplot(1,2,2)\n", 401 | "plt.plot(np.dot(x_rand,w_temp.T),y,'.')\n", 402 | "plt.title('Not so close w to actual')" 403 | ] 404 | }, 405 | { 406 | "cell_type": "code", 407 | "execution_count": 19, 408 | "metadata": { 409 | "collapsed": false 410 | }, 411 | "outputs": [ 412 | { 413 | "name": "stdout", 414 | "output_type": "stream", 415 | "text": [ 416 | " final_simplex: (array([[ 5.15437565, 3.15680068],\n", 417 | " [ 5.15442547, 3.15683257],\n", 418 | " [ 5.15443908, 3.15682873]]), array([ 0.31617365, 0.31617365, 0.31617365]))\n", 419 | " fun: 0.31617365228365896\n", 420 | " message: 'Optimization terminated successfully.'\n", 421 | " nfev: 136\n", 422 | " nit: 71\n", 423 | " status: 0\n", 424 | " success: True\n", 425 | " x: array([ 5.15437565, 3.15680068])\n", 426 | "Exact values: [5 3]\n" 427 | ] 428 | } 429 | ], 430 | "source": [ 431 | "# take first pass at optimization via Nelder Mead\n", 432 | "from scipy.optimize import minimize\n", 433 | "# optimize objective function\n", 434 | "w_start = np.random.rand(*w_exact.shape)\n", 435 | "w_found = minimize(obj, w_start, method = 'Nelder-Mead', args=(x_rand, y))\n", 436 | "\n", 437 | "print(w_found)\n", 438 | "print('Exact values:', w_exact)" 439 | ] 440 | }, 441 | { 442 | "cell_type": "markdown", 443 | "metadata": {}, 444 | "source": [ 445 | "___\n", 446 | "\n", 447 | "\n", 448 | "## Using Optimization for Curve Fitting\n", 449 | "We want to optimize the following optimization problem:\n", 450 | "\n", 451 | "\n", 452 | "$$\\hat{y}^{(i)}= \\frac{1}{1+\\exp(-w \\cdot x^{(i)})}$$\n", 453 | "\n", 454 | "$$\\text{obj}(w)= \\sum_i^N (y^{(i)}-\\hat{y}^{(i)})^2$$\n", 455 | "\n", 456 | "The derivative of the objective function is given by:\n", 457 | "$$ \\frac{\\partial}{\\partial w_j}\\text{obj}(w) = -2 \\sum_i^N (y^{(i)}-\\hat{y}^{(i)})(1-\\hat{y}^{(i)})\\hat{y}^{(i)}x_j^{(i)} $$\n", 458 | "\n", 459 | "Which is calculated for every \"j\" value. We can save the intermediate values of $(y^{(i)}-\\hat{y}^{(i)})(1-\\hat{y}^{(i)})\\hat{y}^{(i)}$ using $\\mathbf{y}-\\mathbf{\\hat{y}})\\odot(1-\\mathbf{\\hat{y}})\\odot\\mathbf{\\hat{y}})^\\text{T}$ where where $\\odot$ denotes element by element multiplication. The $\\mathbf{\\hat{y}}$ and $\\mathbf{y}$ vectors consist of each element of $i=$ 1 to $N$. Therefore, the equation can be represented for each value of $w$ as:\n", 460 | "$$ \\frac{\\partial}{\\partial w_j}\\text{obj}(w) = -2\\cdot\\underbrace{(\\mathbf{y}-\\mathbf{\\hat{y}})\\odot(1-\\mathbf{\\hat{y}})\\odot\\mathbf{\\hat{y}}}_{\\text{tmp vector}}\\cdot\\mathbf{x}_j^{(\\forall i)} $$\n", 461 | "\n", 462 | "Which can be written in linear algebra form more compactly, where $\\odot$ denotes element by element multiplication:\n", 463 | "\n", 464 | "$$ \\nabla\\mathbf{w} = -2\\cdot((\\mathbf{y}-\\mathbf{\\hat{y}})\\odot(1-\\mathbf{\\hat{y}})\\odot\\mathbf{\\hat{y}})^\\text{T}\\cdot\\mathbf{X} $$\n" 465 | ] 466 | }, 467 | { 468 | "cell_type": "code", 469 | "execution_count": 21, 470 | "metadata": { 471 | "collapsed": true 472 | }, 473 | "outputs": [], 474 | "source": [ 475 | "# define gradient without vectorized programming\n", 476 | "def obj_gradA(w,x,y):\n", 477 | " grad = []\n", 478 | " yh = yhat(x,w)\n", 479 | " # a not so great implementation of the derivative, lots of for loops\n", 480 | " for j in range(len(w)):\n", 481 | " tmp=0\n", 482 | " for i in range(len(x)):\n", 483 | " tmp = tmp+yh[i]*(y[i]-yh[i])*(1-yh[i])*x[i,j]\n", 484 | " grad.append(-2*tmp)\n", 485 | " \n", 486 | " return np.array(grad)\n", 487 | "\n", 488 | "# add in some vectorization\n", 489 | "def obj_gradB(w,x,y):\n", 490 | " grad = []\n", 491 | " yh = yhat(x,w)\n", 492 | " \n", 493 | " # a better implementation of the derivative\n", 494 | " tmp = yh*(y-yh)*(1-yh)\n", 495 | " for j in range(len(w)):\n", 496 | " grad.append(-2*np.sum(tmp*x[:,j]))\n", 497 | " \n", 498 | " return np.array(grad)\n", 499 | "\n", 500 | "#define the gradient in terms of numpy only operations, vectorized\n", 501 | "def obj_gradC(w,x,y):\n", 502 | " yh = yhat(x,w)\n", 503 | " return -2*np.dot(yh*(y-yh)*(1-yh),x) " 504 | ] 505 | }, 506 | { 507 | "cell_type": "code", 508 | "execution_count": 27, 509 | "metadata": { 510 | "collapsed": false 511 | }, 512 | "outputs": [ 513 | { 514 | "name": "stdout", 515 | "output_type": "stream", 516 | "text": [ 517 | "10 loops, best of 3: 36.9 ms per loop\n", 518 | "10 loops, best of 3: 46.6 ms per loop\n", 519 | "The slowest run took 11.67 times longer than the fastest. This could mean that an intermediate result is being cached.\n", 520 | "10 loops, best of 3: 10.4 ms per loop\n", 521 | "10 loops, best of 3: 9.93 ms per loop\n", 522 | "Exact values: [5 3]\n", 523 | "[ 5.15442831 3.15682916] 94\n", 524 | "[ 5.1543939 3.15680779] 14\n", 525 | "[ 5.1543939 3.15680779] 14\n", 526 | "[ 5.1543939 3.15680779] 14\n" 527 | ] 528 | } 529 | ], 530 | "source": [ 531 | "# Compare the timing for the different gradient methods\n", 532 | "w_start = np.random.rand(*w_exact.shape)\n", 533 | "%timeit w_found = minimize(obj, w_start, method = 'Nelder-Mead', args=(x_rand, y))\n", 534 | "%timeit w_foundA = minimize(obj, w_start, method='BFGS', args=(x_rand, y), jac=obj_gradA)\n", 535 | "%timeit w_foundB = minimize(obj, w_start, method='BFGS', args=(x_rand, y), jac=obj_gradB)\n", 536 | "%timeit w_foundC = minimize(obj, w_start, method='BFGS', args=(x_rand, y), jac=obj_gradC)\n", 537 | "\n", 538 | "# print out some summary information\n", 539 | "print ('Exact values:', w_exact)\n", 540 | "print (w_found.x, w_found.nfev)\n", 541 | "print (w_foundA.x, w_foundA.nfev)\n", 542 | "print (w_foundB.x, w_foundB.nfev)\n", 543 | "print (w_foundC.x, w_foundC.nfev)" 544 | ] 545 | }, 546 | { 547 | "cell_type": "code", 548 | "execution_count": 29, 549 | "metadata": { 550 | "collapsed": false 551 | }, 552 | "outputs": [ 553 | { 554 | "name": "stdout", 555 | "output_type": "stream", 556 | "text": [ 557 | "Enter a value for the sigmoid slope:6\n", 558 | "Enter a value for the noise fraction:0.3\n", 559 | "Slope found is: [ 6.86729429]\n" 560 | ] 561 | }, 562 | { 563 | "data": { 564 | "image/png": "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\nqbbE8sNSAgAAAABJRU5ErkJggg==\n", 565 | "text/plain": [ 566 | "" 567 | ] 568 | }, 569 | "metadata": {}, 570 | "output_type": "display_data" 571 | } 572 | ], 573 | "source": [ 574 | "# Okay, so now we have a sigmoid solver, let's do something fun with it\n", 575 | "\n", 576 | "w_exact = np.array([float(input('Enter a value for the sigmoid slope:'))])\n", 577 | "x_rand = (np.random.rand(100,w_exact.shape[0])-0.5)*2 # n_rows by n_cols\n", 578 | "y = yhat(x_rand,w_exact) # generate a function\n", 579 | "y = y + np.random.randn(*y.shape)*float(input('Enter a value for the noise fraction:')) # add random Gaussian noise\n", 580 | "\n", 581 | "w_start = np.random.rand(*w_exact.shape)\n", 582 | "w_foundC = minimize(obj, w_start, method='BFGS', args=(x_rand, y), jac=obj_gradC, options={'gtol':1e-9})\n", 583 | "\n", 584 | "print('Slope found is:', w_foundC.x)\n", 585 | "\n", 586 | "# now let's plot it\n", 587 | "x = np.linspace(np.min(x_rand), np.max(x_rand), 1000) # get 1000 points, ordered\n", 588 | "x = x[np.newaxis].T # make into column vector\n", 589 | "y_fit = yhat(x,w_foundC.x)\n", 590 | "\n", 591 | "plt.plot(x_rand,y,'.',label='Orig')\n", 592 | "plt.plot(x,y_fit,label='Fit')\n", 593 | "plt.legend(loc='best')\n", 594 | "plt.grid()\n", 595 | "plt.show()" 596 | ] 597 | }, 598 | { 599 | "cell_type": "code", 600 | "execution_count": 30, 601 | "metadata": { 602 | "collapsed": false 603 | }, 604 | "outputs": [ 605 | { 606 | "name": "stdout", 607 | "output_type": "stream", 608 | "text": [ 609 | "Slope found is: [ 10.31049545]\n" 610 | ] 611 | }, 612 | { 613 | "data": { 614 | "image/png": "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\n", 615 | "text/plain": [ 616 | "" 617 | ] 618 | }, 619 | "metadata": {}, 620 | "output_type": "display_data" 621 | } 622 | ], 623 | "source": [ 624 | "# how about using some actual interactive widgets!!?\n", 625 | "import ipywidgets as widgets\n", 626 | "\n", 627 | "def plot_func(w,noise=0.0015):\n", 628 | " w_exact = np.array([w])\n", 629 | " x_rand = (np.random.rand(100,w_exact.shape[0])-0.5)*2 # n_rows by n_cols\n", 630 | " y = yhat(x_rand,w_exact) # generate a function\n", 631 | " y = y + np.random.randn(*y.shape)*noise # add random Gaussian noise\n", 632 | "\n", 633 | " w_start = np.random.rand(*w_exact.shape)\n", 634 | " w_foundC = minimize(obj, w_start, method='BFGS', args=(x_rand, y), jac=obj_gradC, options={'gtol':1e-9})\n", 635 | "\n", 636 | " print ('Slope found is:', w_foundC.x)\n", 637 | "\n", 638 | " # now let's plot it\n", 639 | " x = np.linspace(np.min(x_rand), np.max(x_rand), 1000) # get 1000 points, ordered\n", 640 | " x = x[np.newaxis].T # make into column vector\n", 641 | " y_fit = yhat(x,w_foundC.x)\n", 642 | "\n", 643 | " plt.plot(x_rand,y,'.',label='Orig')\n", 644 | " plt.plot(x,y_fit,label='Fit')\n", 645 | " plt.legend(loc='best')\n", 646 | " plt.grid()\n", 647 | " plt.show()\n", 648 | " \n", 649 | "widgets.interact(plot_func,w=widgets.FloatSlider(min=-10, max=10, step=0.2),\n", 650 | " noise=widgets.FloatSlider(min=0.0, max=1, step=0.01),\n", 651 | " __manual=True)" 652 | ] 653 | }, 654 | { 655 | "cell_type": "markdown", 656 | "metadata": {}, 657 | "source": [ 658 | "# Bonus: Compiling Python via numba" 659 | ] 660 | }, 661 | { 662 | "cell_type": "code", 663 | "execution_count": 31, 664 | "metadata": { 665 | "collapsed": false 666 | }, 667 | "outputs": [ 668 | { 669 | "name": "stdout", 670 | "output_type": "stream", 671 | "text": [ 672 | "The slowest run took 27025.81 times longer than the fastest. This could mean that an intermediate result is being cached.\n", 673 | "1 loop, best of 3: 42.1 µs per loop\n" 674 | ] 675 | } 676 | ], 677 | "source": [ 678 | "from numba import jit\n", 679 | "from scipy.optimize import minimize\n", 680 | "\n", 681 | "# redefine example variables\n", 682 | "x_rand = (np.random.rand(100,2)-0.5)*2 # n_rows by n_cols\n", 683 | "\n", 684 | "w_exact = np.array([5,3])\n", 685 | "y = yhat(x_rand,w_exact) # generate a function\n", 686 | "y = y + np.random.randn(*y.shape)*0.015 # add random Gaussian noise\n", 687 | "\n", 688 | "# define gradient without vectorized programming\n", 689 | "@jit\n", 690 | "def obj_gradA(w,x,y):\n", 691 | " grad = np.zeros(w.shape)\n", 692 | " yh = yhat(x,w)\n", 693 | " # a not so great implementation of the derivative, lots of for loops\n", 694 | " for j in range(len(w)):\n", 695 | " tmp=0\n", 696 | " for i in range(len(x)):\n", 697 | " tmp = tmp+yh[i]*(y[i]-yh[i])*(1-yh[i])*x[i,j]\n", 698 | " grad[j]= -2*tmp\n", 699 | " \n", 700 | " return grad\n", 701 | "\n", 702 | "%timeit obj_gradA(w_exact,x_rand, y)" 703 | ] 704 | }, 705 | { 706 | "cell_type": "code", 707 | "execution_count": 34, 708 | "metadata": { 709 | "collapsed": false 710 | }, 711 | "outputs": [ 712 | { 713 | "name": "stdout", 714 | "output_type": "stream", 715 | "text": [ 716 | "100 loops, best of 3: 8.83 ms per loop\n", 717 | "100 loops, best of 3: 3.87 ms per loop\n", 718 | "100 loops, best of 3: 3.57 ms per loop\n", 719 | "100 loops, best of 3: 3.15 ms per loop\n", 720 | "Exact values: [5 3]\n", 721 | "[ 5.15442831 3.15682916] 94\n", 722 | "[ 5.1543939 3.15680779] 14\n", 723 | "[ 5.1543939 3.15680779] 14\n", 724 | "[ 6.86729429] 14\n" 725 | ] 726 | } 727 | ], 728 | "source": [ 729 | "# Compare the timing for the different gradient methods\n", 730 | "w_start = np.random.rand(*w_exact.shape)\n", 731 | "\n", 732 | "%timeit w_found = minimize(obj, w_start, method = 'Nelder-Mead', args=(x_rand, y))\n", 733 | "%timeit w_foundA = minimize(obj, w_start, method='BFGS', args=(x_rand, y), jac=obj_gradA)\n", 734 | "%timeit w_foundB = minimize(obj, w_start, method='BFGS', args=(x_rand, y), jac=obj_gradB)\n", 735 | "%timeit w_foundC = minimize(obj, w_start, method='BFGS', args=(x_rand, y), jac=obj_gradC)\n", 736 | "\n", 737 | "# print out some summary information\n", 738 | "print ('Exact values:', w_exact)\n", 739 | "print (w_found.x, w_found.nfev)\n", 740 | "print (w_foundA.x, w_foundA.nfev)\n", 741 | "print (w_foundB.x, w_foundB.nfev)\n", 742 | "print (w_foundC.x, w_foundC.nfev)" 743 | ] 744 | }, 745 | { 746 | "cell_type": "code", 747 | "execution_count": null, 748 | "metadata": { 749 | "collapsed": true 750 | }, 751 | "outputs": [], 752 | "source": [] 753 | } 754 | ], 755 | "metadata": { 756 | "anaconda-cloud": {}, 757 | "kernelspec": { 758 | "display_name": "Python [MLEnv]", 759 | "language": "python", 760 | "name": "Python [MLEnv]" 761 | }, 762 | "language_info": { 763 | "codemirror_mode": { 764 | "name": "ipython", 765 | "version": 3 766 | }, 767 | "file_extension": ".py", 768 | "mimetype": "text/x-python", 769 | "name": "python", 770 | "nbconvert_exporter": "python", 771 | "pygments_lexer": "ipython3", 772 | "version": "3.5.2" 773 | } 774 | }, 775 | "nbformat": 4, 776 | "nbformat_minor": 0 777 | } 778 | -------------------------------------------------------------------------------- /HelloWorld.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 2, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [ 10 | { 11 | "name": "stdout", 12 | "output_type": "stream", 13 | "text": [ 14 | "Hello World from Notebook\n" 15 | ] 16 | } 17 | ], 18 | "source": [ 19 | "print(\"Hello World from Notebook\")" 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": null, 25 | "metadata": { 26 | "collapsed": true 27 | }, 28 | "outputs": [], 29 | "source": [] 30 | } 31 | ], 32 | "metadata": { 33 | "anaconda-cloud": {}, 34 | "kernelspec": { 35 | "display_name": "Python [MLEnv]", 36 | "language": "python", 37 | "name": "Python [MLEnv]" 38 | }, 39 | "language_info": { 40 | "codemirror_mode": { 41 | "name": "ipython", 42 | "version": 3 43 | }, 44 | "file_extension": ".py", 45 | "mimetype": "text/x-python", 46 | "name": "python", 47 | "nbconvert_exporter": "python", 48 | "pygments_lexer": "ipython3", 49 | "version": "3.5.2" 50 | } 51 | }, 52 | "nbformat": 4, 53 | "nbformat_minor": 0 54 | } 55 | -------------------------------------------------------------------------------- /PDF_Slides/AllUnitsCombined.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclarson/PythonIntroBridge/044abc452bbbf903121934203db8230162819fd5/PDF_Slides/AllUnitsCombined.pdf -------------------------------------------------------------------------------- /PDF_Slides/Unit1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclarson/PythonIntroBridge/044abc452bbbf903121934203db8230162819fd5/PDF_Slides/Unit1.pdf -------------------------------------------------------------------------------- /PDF_Slides/Unit2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclarson/PythonIntroBridge/044abc452bbbf903121934203db8230162819fd5/PDF_Slides/Unit2.pdf -------------------------------------------------------------------------------- /PDF_Slides/Unit3.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclarson/PythonIntroBridge/044abc452bbbf903121934203db8230162819fd5/PDF_Slides/Unit3.pdf -------------------------------------------------------------------------------- /PDF_Slides/Unit4.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclarson/PythonIntroBridge/044abc452bbbf903121934203db8230162819fd5/PDF_Slides/Unit4.pdf -------------------------------------------------------------------------------- /PDF_Slides/Unit5.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclarson/PythonIntroBridge/044abc452bbbf903121934203db8230162819fd5/PDF_Slides/Unit5.pdf -------------------------------------------------------------------------------- /PDF_Slides/Unit6.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eclarson/PythonIntroBridge/044abc452bbbf903121934203db8230162819fd5/PDF_Slides/Unit6.pdf -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PythonIntroBridge 2 | -------------------------------------------------------------------------------- /calculator_example1.py: -------------------------------------------------------------------------------- 1 | # calculator example from file 2 | 3 | print("Calculator Prompt:") 4 | 5 | var1 = input("") 6 | 7 | print(var1) -------------------------------------------------------------------------------- /calculators.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | 4 | class CalculatorError(ValueError): 5 | '''raise this when the user causes a mistake from the calculator''' 6 | 7 | class Calculator: 8 | def __init__(self): 9 | 10 | import operator as oper 11 | # add dictionary of operations and function passing 12 | self.operations_list = {'+':oper.add, 13 | '-':oper.sub, 14 | '*':oper.mul, 15 | '/':oper.truediv, 16 | '^':oper.pow, 17 | '%':oper.mod, 18 | } 19 | self.eval_queue = [] 20 | 21 | #==Queue Operations======== 22 | def clear_queue(self): 23 | self.eval_queue = [] 24 | 25 | def print_queue(self): 26 | print("Current Stack:", self.eval_queue) 27 | 28 | def addto_queue(self,value): 29 | tmp = self.convert_user_input(value) 30 | self.eval_queue.append( tmp ) 31 | 32 | 33 | # evaluate operation if it was entered 34 | if self.isoperation(self.eval_queue[-1]): 35 | 36 | result = self.eval_queue.pop() 37 | 38 | if len(self.eval_queue)<2: 39 | # not enough elements to perform an operation 40 | raise CalculatorError('Not enough values to perform operation') 41 | 42 | v2 = self.eval_queue.pop() 43 | v1 = self.eval_queue.pop() 44 | 45 | result = calc.perform_operation(result,(v1,v2)) 46 | self.eval_queue.append(result) 47 | 48 | def print_operations(self): 49 | # print supported operations 50 | print('Operations List:', end=' ') 51 | [print(x, end=', ') for x in self.operations_list.keys()] 52 | print('') 53 | 54 | #==check type Operations======== 55 | def isoperation(self, value): 56 | if value in self.operations_list.keys(): 57 | return True 58 | else: 59 | return False 60 | 61 | def isfloat(self, value): 62 | try: 63 | tmp = float(value) 64 | return True 65 | except ValueError: 66 | return False 67 | 68 | #===evalaute operations============ 69 | def convert_user_input(self, value): 70 | if self.isfloat(value): 71 | return float(value) 72 | 73 | elif self.isoperation(value) : 74 | return value # leave as is and interpret operation later 75 | 76 | else: 77 | raise CalculatorError('Invalid entry. Entry must be number or supported operator.') 78 | 79 | def perform_operation(self, op,vals): 80 | if self.isoperation(op): 81 | return self.operations_list[op](vals[0],vals[1]) 82 | return op 83 | 84 | 85 | class Operator: 86 | def __init__(self, func, num_args=2): 87 | self.func = func 88 | self.num_args = num_args 89 | 90 | 91 | 92 | class CustomCalculator(Calculator): 93 | def __init__(self): 94 | # THIS OVERWRITES THE INIT FUNCTION OF INHERITED CLASS 95 | import operator as oper 96 | # add dictionary of operations and function passing, include basic operations here 97 | self.operations_list = {'+':Operator(oper.add), 98 | '-':Operator(oper.sub), 99 | '*':Operator(oper.mul), 100 | '/':Operator(oper.truediv), 101 | '^':Operator(oper.pow), 102 | '%':Operator(oper.mod), 103 | 'abs':Operator(oper.abs,num_args=1), 104 | } 105 | self.eval_queue = [] 106 | 107 | def add_custom_operations(self,filename): 108 | import json 109 | with open(filename) as file: 110 | data = json.loads(file.read()) # Grab file data 111 | 112 | import math 113 | for key,module in data.items(): 114 | if hasattr(math, module): 115 | self.operations_list[key] = Operator(getattr(math, module), num_args = 1) 116 | 117 | def addto_queue(self,value): 118 | tmp = self.convert_user_input(value) 119 | self.eval_queue.append( tmp ) 120 | 121 | 122 | # evaluate operation if it was entered 123 | if self.isoperation(self.eval_queue[-1]): 124 | 125 | result = self.eval_queue.pop() 126 | num_args = self.operations_list[result].num_args 127 | 128 | if len(self.eval_queue)