{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "

A crash course in Python

\n", "

Written by Dr. K. Kalpakis and V. Chavan for CMSC 491/691 in September 2017

\n", "\n", "

The material in this notebook is modeled after Chapter 2 (A Crash Course in Python) in the book by Grus\n", "

" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Start by getting some libaries first" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Importing a module (package/library) into python\n", "import sys\n", "import os" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true }, "outputs": [], "source": [ "#some common imports\n", "from __future__ import division\n", "import re\n", "import math\n", "\n", "#use new handle (alias) for imported library\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Calling functions from imported modules" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "4.47213595499958" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "math.sqrt(20) # call the sqrt function from the module math" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Strings\n", "Define strings using either 'single' or \"double\" quotes; use triple quotes used for multiline strings\n", "Use '\\' to escape special characters. " ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "s1 = \"First String\"\n", "s2 = 'second String'\n", "multiLine_string = '''This is a very long\n", "multi Line String. Which can go on, and on, and on...'''\n", "tab = \"\\t\"\n", "notab1 = \"\\\\t\"\n", "notab2 = r'\\t'" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1. First String\n", "2. second String\n", "3. This is a very long\n", "multi Line String. Which can go on, and on, and on...\n", "4. :\t:\n", "5. \\t\n", "6. \\t\n" ] } ], "source": [ "print(\"1. \" + s1)\n", "print(\"2. \" + s2)\n", "print(\"3. \" + multiLine_string)\n", "print(\"4. :\" + tab + \":\")\n", "print(\"5. \" + notab1)\n", "print(\"6. \" + notab2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Indentation using tabs or whitespaces to define the scope of blocks of code" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2 1.3862943611198906\n", "9 19.775021196025975\n", "16 44.3614195558365\n" ] } ], "source": [ "# Print numbers from 2 up to 20 with stride of 7\n", "for i in range(2,20,7):\n", " # body of the loop is indented\n", " j = i * math.log(i)\n", " print (i,j)\n", "# end of the loop body" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Control Flow" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### if.. elif.. else" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "92 A\n" ] } ], "source": [ "score = 92\n", "if (score >= 90):\n", " grade = 'A'\n", "elif (80 <= score < 90):\n", " grade = 'B'\n", "elif ( 70<= score < 80):\n", " grade = 'C'\n", "else:\n", " grade = 'F'\n", "print(score, grade)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### while loop" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 1.0\n", "1 2.718281828459045\n", "2 7.38905609893065\n", "3 20.085536923187668\n" ] } ], "source": [ "x = 0\n", "while (x < 4):\n", " print (x, math.exp(x))\n", " x += 1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### for loop" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "1\n", "2\n", "3\n", "4\n" ] } ], "source": [ "for x in range(5):\n", " print (x)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Indentation in case of *nested for* loops" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 2 2\n", "0 3 3\n", "0 4 4\n", "1 2 3\n", "1 3 4\n", "1 4 5\n" ] } ], "source": [ "# An example of nested for loops\n", "for i in range(2):\n", " for j in range(2,5):\n", " print(i,j, i+j)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Functions" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# define a function with 2 argunments and default values for its parameters\n", "def addition(arg1=100, arg2=200):\n", " # Body of the function\n", " t = arg1 + arg2\n", " return t" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15\n", "300\n", "120\n", "23\n" ] } ], "source": [ "# ways to call a function with actual parameter values\n", "\n", "# match parameter values to function arguments by position\n", "print(addition(5,10)) \n", "\n", "print(addition()) # use only the defaults\n", "\n", "# provide only named parameter value, rest take their defaults\n", "print(addition(arg2=20)) \n", "\n", "# call with parameters given out of order\n", "print(addition(arg2=20, arg1=3)) " ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# function call without parentheses\n", "addition" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Assign functions to variables " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "220" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Assign the function to another variable\n", "myAdd = addition\n", "myAdd(20) # call function reference" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Data Science'" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Dynamically typed\n", "myAdd(\"Data \", \"Science\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Pass functions as arguments to functions" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Create a new function for fancy printing\n", "def prettyPrint(data):\n", " print('\\t[', data(), ']\\n')" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\t[ 300 ]\n", "\n" ] } ], "source": [ "# Pass a function as an argument to it\n", "prettyPrint(myAdd)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Exceptions" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "division by 0 exception\n" ] } ], "source": [ "try:\n", " print (0/0)\n", "except ZeroDivisionError:\n", " print (\"division by 0 exception\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Lists\n", "An ordered collection of *things* of various types/kinds. Core Python data structure." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "simpleList = [10, 20, 30, 40, 50]\n", "\n", "heterogeneousList = [\"Apple\", 5.0, 42]\n", "\n", "list_of_lists = [[100,200,300,], simpleList]" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[10, 20, 30, 40, 50]" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "simpleList" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[100, 200, 300], [10, 20, 30, 40, 50]]" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "list_of_lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### lists are 0-indexed (similar to arrays in C++)" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "50" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# List elements can be accessed with index.\n", "simpleList[4]" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[10, 20, 30, 40, 50, 'Apple', 5.0, 42]" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Pass lists as arguments (+ concatenates the two operand lists)\n", "addition(simpleList, heterogeneousList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Slicing lists" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[10, 20, 30]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# sublist of first 3 elements\n", "simpleList[:3]" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[20, 40]" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# another sublist using strides (first location:last location:stride)\n", "simpleList[1:4:2]" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "40" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# the 2nd element from the end of the list\n", "simpleList[-2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### list membership" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0 No\n", "10 Yes\n", "20 Yes\n", "30 Yes\n", "40 Yes\n", "50 Yes\n", "60 No\n", "70 No\n", "80 No\n", "90 No\n" ] } ], "source": [ "for i in range(0,100,10):\n", " if (i in simpleList):\n", " print(i, \"Yes\")\n", " else:\n", " print(i, \"No\")" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None [10, 20, 30, 40, 50, 60]\n", "60 [10, 20, 30, 40, 50]\n", "30 [10, 20, 40, 50]\n", "2 [10, 20, 40, 50]\n", "None [10, 20, 30, 40, 50]\n" ] } ], "source": [ "# append/insert/search/remove elements from/to a list\n", "simpleList = [10, 20, 30, 40, 50]\n", "\n", "# append element at the end of a list\n", "print(simpleList.append(60), simpleList) \n", "\n", "#remove last list element, and return that element \n", "print(simpleList.pop(), simpleList)\n", "\n", "#remove element at given position\n", "print(simpleList.pop(2), simpleList) \n", "\n", "# find the position of given value in list\n", "print(simpleList.index(40), simpleList) \n", "\n", "# insert a value 30 at position 2 of list\n", "print(simpleList.insert(2, 30), simpleList) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Python trick: swap variables using lists" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "5 10\n", "10 5\n" ] } ], "source": [ "a = 5\n", "b = 10\n", "print(a,b)\n", "a, b = b, a # swap (assignment of elements across two lists)\n", "print(a,b)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tuples\n", "The 'immutable' cousins of Lists. \n", "All list operations that _do not_ modify the list are supported on tuples\n", "Use (...) instead of [...]" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "collapsed": true }, "outputs": [], "source": [ "my_tuple = (1,2,3)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Tuple elements can be accessed with index.\n", "my_tuple[2]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Let's try changing the value of the tuple at an index" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "error :: tuples are immutable\n" ] } ], "source": [ "# Tuples are immutable\n", "try:\n", " my_tuple[1] = 10\n", "except TypeError:\n", " print('error :: tuples are immutable')" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Odd\n" ] } ], "source": [ "# dynamic selection of tuple element\n", "i = 5\n", "val = (\"Even\", \"Odd\")[i % 2 != 0]\n", "print(val)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Sets\n", "A collection of *distinct* things (faster membership tests for sets than lists)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{1, 2} 2 True False\n" ] } ], "source": [ "s = set()\n", "s.add(1) # s is now { 1 }\n", "s.add(2) # s is now { 1, 2 }\n", "s.add(2) # s is still { 1, 2 }\n", "\n", "x = len(s) # length of set\n", "y = 2 in s # set membership\n", "z = 3 in s \n", "print(s, x, y, z)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{0, 1, 2}\n" ] } ], "source": [ "dups = [0,1,2,2,1,0,0,1] #list\n", "noDups = set(dups) #set\n", "print(noDups)" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{2}" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# intersect two sets\n", "set(set([0,1,2,3]) & set([2,5,10]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Dictionaries\n", "Mutable collection for storing (key : value) pairs" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Dictionary of names and ages\n", "name_age_dict = {\n", " \"Alex\" : 20,\n", " \"Amanda\" : 22,\n", " \"Ruben\" : 43,\n", " \"Dave\" : 6\n", "}\n", "\n", "# Dict of names and courses\n", "name_course_dict = {\n", " \"Alex\" : [\"404\", \"461\", \"469\"],\n", " \"Amanda\" : [\"321\", \"345\", \"404\"],\n", " \"Ruben\" : [\"691\", \"622\"],\n", " \"Dave\" : []\n", "}" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Alex : 20\n", "Amanda : 22\n", "Ruben : 43\n", "Dave : 6\n" ] } ], "source": [ "# Accessing key:value pairs in a dict\n", "for key, value in name_age_dict.items():\n", " print(key, \":\", value)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Adding new (key, value) entry to dictionary\n", "name_age_dict[\"Tom\"] = 12\n", "\n", "# Modify existing key\n", "name_age_dict[\"Amanda\"] = 21" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Alex : 20\n", "Amanda : 21\n", "Ruben : 43\n", "Dave : 6\n", "Tom : 12\n" ] } ], "source": [ "for key, value in name_age_dict.items():\n", " print(key, \":\", value)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "43\n" ] } ], "source": [ "# Get value associated with key\n", "print(name_age_dict[\"Ruben\"])" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "error :: key not found\n" ] } ], "source": [ "# Key error in case of missing keys\n", "try:\n", " print(name_age_dict[\"Yoda\"])\n", "except KeyError:\n", " print('error :: key not found')" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Ruben's age is 43\n", "Yoda's age is None\n", "Yoda's age is 150\n" ] } ], "source": [ "# To avoid KeyErrors use get() method which returns None\n", "print(\"Ruben's age is \",name_age_dict.get(\"Ruben\"))\n", "print(\"Yoda's age is \", name_age_dict.get(\"Yoda\"))\n", "\n", "# get() with default\n", "print(\"Yoda's age is \", name_age_dict.get(\"Yoda\", 150))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Default dictionaries\n", "append-to-value of key (pre-insert 'empty' value if key was missing prior) " ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "defaultdict(, {'a': 1})\n", "defaultdict(, {2: [[1, 'abc']]})\n" ] } ], "source": [ "from collections import defaultdict\n", "\n", "dd = defaultdict(int)\n", "dd['a'] += 1\n", "print(dd)\n", "\n", "dd = defaultdict(list) # list() produces an empty list\n", "dd[2].append([1, 'abc']) # now dd_list contains {2: [1, 'abc']}\n", "print(dd)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Booleans \n", "possible values are 'True', 'False', 'None'\n", "The expressions below evaluate to 'False'" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.0\n", "False\n" ] } ], "source": [ "x = False or None or [] or {} or \"\" or set() or 0 or 0.0\n", "print(x)\n", "if(x):\n", " print(\"True\")\n", "else:\n", " print(\"False\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Special functions: 'all' and 'any'\n", "'all' is an aggregated logical 'and', while 'any' is an aggregated logical 'or'" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "False\n", "True\n" ] } ], "source": [ "vals = [True, 1.0, False]\n", "print( all(vals) ) #evaluates to False\n", "print( any(vals) ) #evaluates to True" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Python trick: (emulating) the ternary conditional operator ? of C" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "dog\n" ] } ], "source": [ "# Using if..else\n", "x = True\n", "x = False\n", "val = \"cat\" if x else \"dog\"\n", "print(val)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Part II" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Build-in sorting functions\n", "'.sort()' method is in-place sorting for lists only\n", "
sorted() function returns a sorted version of any iterator" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[-7, 4, 5, 8, 12]\n", "[8, 4, 5, 12, -7]\n", "[-7, 4, 5, 8, 12]\n" ] } ], "source": [ "aList = [8,4,5,12,-7]\n", "\n", "# printing the sorted List\n", "print(sorted(aList))\n", "\n", "#initial list is still unsorted\n", "print(aList)\n", "\n", "# in-place sorting of list is changed to its sorted version\n", "aList.sort()\n", "print(aList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "sorting order is smallest to largest by default; can be changed by using the 'reverse' flag" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[12, 8, 5, 4, -7]\n" ] } ], "source": [ "aList.sort(reverse=True)\n", "print(aList)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## List comprehensions\n", "Powerful, elegant and efficient way of playing with lists." ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "All numbers: [0, 1, 2, 3, 4]\n", "Evens: [0, 2, 4]\n", "Squares: [0, 1, 4, 9, 16]\n", "Even Squares [0, 4, 16]\n" ] } ], "source": [ "all_numbers = [x for x in range(5)] # gives [0, 1, 2, 3, 4]\n", "\n", "even_numbers = [x for x in range(5) if x % 2 == 0] # gives [0, 2, 4]\n", "\n", "squares = [x * x for x in all_numbers] # [gives 0, 1, 4, 9, 16]\n", "\n", "even_squares = [x * x for x in even_numbers] # gives [0, 4, 16]\n", "\n", "print('All numbers:', all_numbers)\n", "print(\"Evens: \", even_numbers)\n", "print(\"Squares: \", squares)\n", "print(\"Even Squares\", even_squares)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[0, 4]" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# compute list intersection via list comprehensions\n", "[x for x in squares if x in even_numbers]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### List comprehension works for sets and dictionaries as well. \n", "list = [ expression for .... if... ]" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Dict: {0: '', 1: '|', 2: '||', 3: '|||', 4: '||||'} \n", "\n", "Set: {1, 2, 3, 4, 5, 6, 7, 8, 9}\n" ] } ], "source": [ "# associate k with string of k bars\n", "dict_comprehension = {x : \"|\"*x for x in range(5)}\n", "\n", "#make set with elements 1 ... 9\n", "set_comprehension = set(i for i in range(10) if i >0)\n", "\n", "print(\"\\nDict:\", dict_comprehension, \"\\n\\nSet:\", set_comprehension)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### create a 2D matrix using list comprehensions" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(0, 0, 0), (0, 1, 1), (0, 2, 2), (0, 3, 3), (0, 4, 4)]\n", "[(1, 0, 1), (1, 1, 2), (1, 2, 3), (1, 3, 4), (1, 4, 5)]\n", "[(2, 0, 2), (2, 1, 3), (2, 2, 4), (2, 3, 5), (2, 4, 6)]\n", "[(3, 0, 3), (3, 1, 4), (3, 2, 5), (3, 3, 6), (3, 4, 7)]\n" ] }, { "data": { "text/plain": [ "[[(0, 0, 0), (0, 1, 1), (0, 2, 2), (0, 3, 3), (0, 4, 4)],\n", " [(1, 0, 1), (1, 1, 2), (1, 2, 3), (1, 3, 4), (1, 4, 5)],\n", " [(2, 0, 2), (2, 1, 3), (2, 2, 4), (2, 3, 5), (2, 4, 6)],\n", " [(3, 0, 3), (3, 1, 4), (3, 2, 5), (3, 3, 6), (3, 4, 7)]]" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# create a 4x5 matrix of tuples (i,j,val) where val = i+j in a row-major way\n", "matrix = [ [ (i,j, i+j) for j in range(5)] for i in range(4)]\n", "for row in matrix:\n", " print(row)\n", "matrix" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Enumerate\n", "using both the index and value from an iterator" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[(0, 'a'), (1, 'b'), (2, ('c', 'd', 2))]\n" ] } ], "source": [ "#Enumerate: return a list of (index,value) pairs for the values in the input list\n", "objs = ['a','b', ('c', 'd', 2)]\n", " \n", "# make list of those (index,value) pairs\n", "pairs = [(i,v) for i,v in enumerate(objs)] \n", "print(pairs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Regular expressions" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "None\n", "<_sre.SRE_Match object; span=(1, 2), match='a'>\n", "None\n", "['c', 'r', 's']\n", "R-D-\n" ] } ], "source": [ "# basic regular expression operations\n", "import re\n", "\n", "# match(E, S) to find a match of regexp E to string S \n", "print(re.match(\"a\", \"cat\")) # no matches since 'cat' doesn't match 'a'\n", "print(re.search('a', 'cat')) #'cat' contains 'a'\n", "print(re.search('c', 'dog')) #'dog' does not have a 'c'\n", "\n", "print(re.split(\"[ab]\", 'carbs')) # split 'carbs' based on 'a' and 'b'\n", "\n", "print(re.sub(\"[0-9]\", \"-\", \"R2D2\")) # replace digits with dashes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Randomness" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0.8364325564429288, 0.28678598991130255, 0.8082579348783351, 0.7817166964118738]\n", "9\n", "[19, 17, 19, 20, 4]\n", "[2.325300055151302, 1.9520015393497638, 2.024105422429658, 2.275712650357259, 2.013381069465178]\n" ] } ], "source": [ "import random\n", "\n", "#get some random reals (as a list comprehension)\n", "X = [random.random() for _ in range(4)] # note the anonymous iterator variable _\n", "print(X)\n", "\n", "#random element from a range with a stride\n", "print(random.randrange(3, 20, 3))\n", "\n", "#some random integers between two endpoints\n", "print([random.randint(2, 20) for _ in range(5)])\n", "\n", "#some random values from a Normal distribution\n", "print([random.gauss(2, 0.2) for _ in range(5)])" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Spade\n" ] } ], "source": [ "# Randomly choose an item from a list\n", "suites = [\"Diamond\", \"Spade\", \"Club\", \"Heart\"]\n", "v = random.choice(suites)\n", "print(v)" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[26, 36, 43, 21, 48, 27]\n" ] } ], "source": [ "# Ranomly select k elements from a list without replacement \n", "lottery_numbers = range(60)\n", "winning_numbers = random.sample(lottery_numbers, 6)\n", "print(winning_numbers)" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Shuffled: [5, 8, 6, 3, 9, 2, 4, 7, 0, 1]\n" ] } ], "source": [ "\n", "# Shuffle in-place a list at random\n", "nums = list(range(10))\n", "random.shuffle(nums)\n", "print(\"Shuffled: \", nums)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Functional programming: map, filter, and reduce" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 4, 9, 16, 25]\n" ] } ], "source": [ "# MAP: apply a function over an iterator \n", "# use an anonymous function (lambda function)\n", "nums = [1,2,3,4,5]\n", "squares = list(map(lambda x:x**2, nums))\n", "print(squares)" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[4, 16]\n" ] } ], "source": [ "# FILTER(func, iter): select those elements x of an iterator that \n", "# have func(x) True. Returns an iterator\n", "\n", "# retain the even elements in squares\n", "even_squares = list(filter(lambda x: x % 2 == 0, squares))\n", "\n", "print(even_squares)" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "55\n" ] } ], "source": [ "# REDUCE: Successively use a single operator on all elements \n", "# of an iterator; returns a single value\n", "\n", "# import the reduce from the functools module so that it can be used directly\n", "from functools import reduce\n", "\n", "sum_of_squares = reduce(lambda x,y:x+y, squares)\n", "print(sum_of_squares)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Zip and Unzip \n", "Zip does argument unpacking. Think of 'the first thing that pops in head': your jacket's zipper. It's exactly that!" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[('a', 1), ('b', 2), ('c', 3), ('d', (4, 'base'))]\n" ] } ], "source": [ "# Combine corresponding elements (same index) from two input lists into tuples\n", "objsA = ['a','b','c','d','e']\n", "objsB = [1, 2, 3, (4, 'base')]\n", "\n", "objs = list(zip(objsA, objsB))\n", "print(objs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "unzip does argument unpacking. The '*' performs argument unpacking. Uses elements of pairs as individual arguments to zip." ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('a', 'b', 'c', 'd')\n", "(1, 2, 3, (4, 'base'))\n" ] } ], "source": [ "# Separate out the pairs in objs into two lists \n", "objsA, objsB = zip(*objs)\n", "\n", "# The above call is equivalent to zip(('a',1), ('b',2), ('c',3), ('d',4))\n", "print(objsA)\n", "print(objsB)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Object-oriented programming\n", "define new classes" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Define a new class\n", "\n", "class DS_Set:\n", " # these are the member methods take a first parameter \"self\" \n", " # (a Python convention) referencing the current class instance\n", " \n", " def __init__(self, values=None):\n", " \"\"\"This is the class constructor.\n", " s1 = DS_Set() # empty set\n", " s2 = DS_Set([1,2,2,3]) # initialize with values\"\"\"\n", " self.dict = {} # each instance has its own dictionary to track its members\n", " if values is not None:\n", " for v in values:\n", " self.add(v)\n", " \n", " def __repr__(self):\n", " \"\"\"this is the string representation of an instance\n", " if you type it at the Python prompt or pass it to str()\"\"\"\n", " return \"DS_Set: \" + str(self.dict.keys())\n", " \n", " # we'll represent membership by being a key in self.dict with value True\n", " def add(self, value):\n", " self.dict[value] = True\n", " \n", " # value is in the Set if it's a key in the dictionary\n", " def contains(self, value):\n", " return value in self.dict\n", " \n", " def remove(self, value):\n", " del self.dict[value]" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "DS_Set: dict_keys([1, 2, 3, 4])\n", "True\n", "False\n" ] } ], "source": [ "# Create an instance DS_Set\n", "s = DS_Set([1,2,3])\n", "\n", "# Add a new element\n", "s.add(4)\n", "print(s)\n", "\n", "# Check for memberhip\n", "print (s.contains(4)) # True\n", "\n", "# Remove an element\n", "s.remove(3)\n", "print(s.contains(3)) # False" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Generators and lazy iterators\n", "Generator: an object that you iterate over whose values are produced as needed (lazily)" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# define a lazy iterator. Notice the 'yield' instead of 'return'\n", "def lazy_evens(n):\n", " i = 0\n", " while i < n:\n", " yield i\n", " i += 2" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0\n", "2\n", "4\n", "6\n", "8\n", "10\n" ] } ], "source": [ "# use items of the generator lazy_evens as needed \n", "for i in lazy_evens(1000000000000):\n", " print (i)\n", " if i >= 10:\n", " break" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "102\n", "104\n", "106\n", "108\n", "110\n", "112\n", "114\n", "116\n", "118\n", "120\n", "122\n" ] } ], "source": [ "#can also make generator by wrapping a list comprehension in parentheses\n", "large_evens = (i for i in lazy_evens(200000000) if i > 100)\n", "for i in large_evens:\n", " print(i);\n", " if i > 120:\n", " break" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Functions with variable arguments " ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[1, 2, 'three']\n", "{'A': 1, 'B': 2, 'C': 3}\n", "Body of the function\n" ] } ], "source": [ "# Define a function with variable (number of) arguments\n", "def foo_varargs(*args, **kwargs):\n", " # print out the arguments:\n", " for a in args:\n", " print(a)\n", " for key, value in kwargs.items():\n", " print(key, value)\n", " print('Body of the function')\n", " return None\n", "\n", "# define parameter values and call the function\n", "args = [1,2,\"three\"]\n", "kwargs = {'A':1, 'B':2, \"C\":3 }\n", "\n", "foo_varargs(args, kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Splitting python code into multiple files (modules)" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "Can put some functions (say foo), classes etc in a file, eg 'my_code.py'\n", "Then, in notebook you can \n", " import my_code as mine\n", "and call then as\n", " mine.foo()\n", "Alternatively, can import all (*) or select items\n", " from my_code import foo\n", " from my_code import *\n", "Can also create a directory module with multiple files and a '__init__.py' as below\n", " my_code/\n", " __init__.py\n", " #contents of __init__.py are here\n", " from .partA import classA\n", " from .partB import fooB\n", " partA.py\n", " class classA():\n", " partB.py\n", " def fooB():\n", " \n", "and then import the module and use as \n", " import my_code as mine\n", " mine.fooB()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Including LaTeX markdowns in the notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The LaTex equations are interpreted by the notebook.\n", "\n", "$$e^x=\\sum_{i=0}^\\infty \\frac{x^i}{i!}$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\\noindent\n", "Any other LaTeX commands are interpreted when the notebook downloaded as .tex or .pdf.\n", "\n", "\\begin{itemize}\n", "\\item a $\\frac{2^x}{x+y}$\n", "\\item b\n", "\\end{itemize}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Build-in magic jupyter notebook commands" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "%magic\n", " get info about magic commands\n", " \n", "%debug\n", " enter the debug mode for the cell\n", " \n", "%%timeit\n", " time the execution of the cell\n", "%whos\n", " list of global scope (interactive) variables\n", " \n", "%%writefile filename\n", " writes the rest of a cell's contents into a file\n", " \n", "%load filename\n", " replaces the cell's contents with the contents of the filename \n", " \n", "%notebook filename\n", " export and save notebook to filename \n", "%pdef\n", " Print the call signature for any callable object.\n", "%%prun\n", " profile cell execution\n", "%dirs\n", "%env\n", "%cd\n", "?object\n", "%xdel name\n", " delete var with given name" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "Render the contents of the cell as LaTeX, eg\n", "$\\sum_i e^{t_i}$" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%latex\n", "Render the contents of the cell as LaTeX, eg\n", "$\\sum_i e^{t_i}$" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/html": [ "# Render the contents of the cell as HTML\n", "\n", "\n", "\n", "
12
ab
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%html\n", "# Render the contents of the cell as HTML\n", "\n", "\n", "\n", "
12
ab
" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Export notebook as slides (HTML slideshow)\n", "\n", "Can create a static HTML-based slideshow of the notebook\n", "\n", "jupyter nbconvert mynotebeek.ipynb --to slides\n", "\n", "Ensure that you have the reveal.js in the directory of the saved slideshow before opening it with browser \n", "\n", "In addition, a live slideshow of the notebook can be rendered using the RISE Jupyter extension \n", "(which creates a button on the noteboor's toolbar).\n", "\n", "See https://damianavila.github.io/RISE/ for installation instructions of RISE to your Jupyter notebook viewer.\n", "\n" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "!pip install RISE\n", "!jupyter-nbextension install rise --py --sys-prefix\n", "!jupyter-nbextension enable rise --py --sys-prefix" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.1" }, "widgets": { "application/vnd.jupyter.widget-state+json": { "state": {}, "version_major": 1, "version_minor": 0 } } }, "nbformat": 4, "nbformat_minor": 2 }