Programming for Engineers in Python Recitation 3 Plan

  • Slides: 44
Download presentation
Programming for Engineers in Python Recitation 3

Programming for Engineers in Python Recitation 3

Plan Modules / Packages Tuples Mutable / Imutable Dictionaries Functions: Scope Call by Ref

Plan Modules / Packages Tuples Mutable / Imutable Dictionaries Functions: Scope Call by Ref / Call by Val Frequency Counter

Python Code Hierarchy Statement function Module Package

Python Code Hierarchy Statement function Module Package

Modules All modules and their contents (functions, constants) can be found at http: //docs.

Modules All modules and their contents (functions, constants) can be found at http: //docs. python. org/modindex. html >>> import math # mathematical functions >>> dir(math) ['__doc__', '__name__', '__package__', 'acosh', 'asinh', 'atan 2', 'atanh', 'ceil', 'copysign', 'cosh', 'degrees', 'erf', 'erfc', 'expm 1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log 10', 'log 1 p', 'modf', 'pi', 'pow', 'radians', 'sinh', 'sqrt', 'tanh', 'trunc'] >>> math. pi # a constant 3. 141592653589793 >>> math. sqrt(16) # a function 4. 0 >>> math. log(8, 2) 3. 0

Modules – Cont. >>> import os #operating system interfaces >>> os. rename(‘my_file. txt’, ‘your_file.

Modules – Cont. >>> import os #operating system interfaces >>> os. rename(‘my_file. txt’, ‘your_file. txt’) >>> os. mkdir(‘new_dir’) >>> for root, dirs, files in os. walk('lib/email'): print root, "consumes", print sum(getsize(join(root, name)) for name in files), print "bytes in", len(files), "non-directory files" >>> os. times()[0] # user time 10. 1244649

Packages Num. Py support for large, multi-dimensional arrays and matrices high-level mathematical functions Sci.

Packages Num. Py support for large, multi-dimensional arrays and matrices high-level mathematical functions Sci. Py Optimization linear algebra integration special functions signal and image processing And more

Installing Packages Download Num. Py: http: //sourceforge. net/projects/numpy/files/Num. Py/ Choose Download numpy-1. 6. 1

Installing Packages Download Num. Py: http: //sourceforge. net/projects/numpy/files/Num. Py/ Choose Download numpy-1. 6. 1 -win 32 -superpackpython 2. 7. exe Sci. Py: http: //sourceforge. net/projects/scipy/files/ Choose Download scipy-0. 9. 0 -win 32 -superpackpython 2. 6. exe

Mutable vs. Immutable Can we change lists? >>> a_list = [1, 2, 3] >>>

Mutable vs. Immutable Can we change lists? >>> a_list = [1, 2, 3] >>> a_list[2] 3 >>> a_list[2] = ‘Inigo Montoya’ >>> a_list [1, 2, ’Inigo Montoya’] The assignment has mutated the list!

Mutable vs. Immutable What about strings? >>> name = ‘Inigo Montoya’ >>> name[0] '

Mutable vs. Immutable What about strings? >>> name = ‘Inigo Montoya’ >>> name[0] ' I' >>> name[5] ' ' >>> name[3] = ‘t’ Traceback (most recent call last): File "<pyshell#14>", line 1, in <module> name[3] = 't' Type. Error: 'str' object does not support item assignment Immutable!

Assignments to List Variables >>> orig_list = [1, 2, 3] >>> copy_list = orig_list

Assignments to List Variables >>> orig_list = [1, 2, 3] >>> copy_list = orig_list >>> orig_list = [6, 7, 8, 9] >>> copy_list [1, 2, 3] >>> orig_list [6, 7, 8, 9] So far - no surprises

Assignments to List Variables >>> copy_list = orig_list >>> orig_list[0] = 1000 >>> orig_list

Assignments to List Variables >>> copy_list = orig_list >>> orig_list[0] = 1000 >>> orig_list [1000, 7, 8, 9] >>> copy_list [1000, 7, 8, 9] Surprise!

Assignments to List Variables Memory [6, 7, 8, 9] orig_list Memor y List assignment

Assignments to List Variables Memory [6, 7, 8, 9] orig_list Memor y List assignment orig_list = [6, 7, 8, 9] creates: § a list object, [6, 7, 8, 9] § a reference from the variable name, orig_list, to this object.

Assignments to List Variables The assignment copy_list = orig_list does not create a new

Assignments to List Variables The assignment copy_list = orig_list does not create a new object, just a new variable name, copy_list, which now refers to the same object. Memory orig_list [6, 7, 8, 9] copy_list

Assignments to List Variables Mutating list elements, orig_list[0] = 1000, does not create a

Assignments to List Variables Mutating list elements, orig_list[0] = 1000, does not create a new object and does not change existing references. Memory orig_list [1000, 7, 8, 9] copy_list

Tuples A tuple is just like a list, only it is immutable. Syntax: note

Tuples A tuple is just like a list, only it is immutable. Syntax: note the parentheses! >>> t = (‘don’t’, ’worry’, ’be’, ’happy’) # definition >>> t (‘dont’, ’worry’, ’be’, ’happy’) >>> t[0] # indexing 'dont' >>> t[-1] # backwords indexing ‘worry' >>> t[1: 3] # slicing (’worry’, ’be’)

Tuples >>> t[0] = ‘do’ # try to change Traceback (most recent call last):

Tuples >>> t[0] = ‘do’ # try to change Traceback (most recent call last): File "<pyshell#2>", line 1, in <module> t[0]=‘do’ Type. Error: 'tuple' object does not support item assignment No append / extend / remove in Tuples!

Tuples So what are tuples good for? § Faster than lists § Safe code

Tuples So what are tuples good for? § Faster than lists § Safe code § When immutable types are required (coming next).

Dictionaries A dictionary is a set of key-value pairs. >>> dict_name = {key 1:

Dictionaries A dictionary is a set of key-value pairs. >>> dict_name = {key 1: val 1, key 2: val 2, …} Keys are unique and immutable, values are not. Example: Map names to heights: >>> heights = {‘Alan Harper’: 1. 76, ‘John Smith’: 1. 83, ‘Walden Schmidt’: 1. 90} >>> heights {'Walden Schmidt': 1. 9, 'John Smith': 1. 83, 'Alan Harper': 1. 76} Note: The pairs order changed

Dictionaries Add a new person: >>> heights[‘Lyndsey Makelroy’] = 1. 70 >>> heights {'Lyndsey

Dictionaries Add a new person: >>> heights[‘Lyndsey Makelroy’] = 1. 70 >>> heights {'Lyndsey Makelroy': 1. 7, 'Walden Schmidt': 1. 9, ‘John Smith': 1. 83, 'Alan Harper': 1. 76} What happens when the key already exists? >>> heights[‘John Smith’] = 2. 02 >>> heights {'Lyndsey Makelroy': 1. 7, 'Walden Schmidt': 1. 9, 'John Smith': 2. 02, 'Alan Harper': 1. 76} Solutions?

Dictionaries Idea: Add address to the key >>> heights = {[‘Alan Harper’, ‘Malibu’]: 1.

Dictionaries Idea: Add address to the key >>> heights = {[‘Alan Harper’, ‘Malibu’]: 1. 76} Traceback (most recent call last): File "<pyshell#46>", line 1, in <module> heights = {['Alan Harper', 'Malibu']: 1. 76} Type. Error: unhashable type: 'list‘ What’s the problem? Fix: >>> heights = {(‘Alan Harper’, ‘Malibu’): 1. 76} >>> heights {('Alan Harper', 'Malibu'): 1. 76}

Dictionaries Useful methods: § D. get(k[, d]) - D[k] if k in D, else

Dictionaries Useful methods: § D. get(k[, d]) - D[k] if k in D, else d (default – None). § D. has_key(k) - True if D has a key k, else False § D. items() - list of (key, value) pairs, as 2 -tuples § D. keys() - list of D's keys § D. values() - list of D's values § D. pop(k[, d]) - remove specified key and return the value. If key is not found, d is returned.

Functions – Scope Consider the following function, operating on two arguments: def linear_combination(x, y):

Functions – Scope Consider the following function, operating on two arguments: def linear_combination(x, y): y=2*y return (x+y) The formal parameters x and y are local, and their “life time" is just the execution of the function. They disappear when the function is returned. 3, 4 linear_combination x, y 11

Functions – Scope >>> a=3 >>> b=4 >>> linear combination(a, b) 11 # this

Functions – Scope >>> a=3 >>> b=4 >>> linear combination(a, b) 11 # this is the correct value >>> a 3 >>> b 4 # b has NOT changed The change in y is local - inside the body of the function.

Functions – Scope >>> x=3 >>> y=4 >>> linear_combination(x, y) 11 # this is

Functions – Scope >>> x=3 >>> y=4 >>> linear_combination(x, y) 11 # this is the correct value >>> x 3 >>> y 4 The y in the calling environment and the y in the function are not the same variable!

Functions – Call by Val / Call by Ref Functions have arguments that appear

Functions – Call by Val / Call by Ref Functions have arguments that appear in their prototype: def linear_combination(x, y): When you call a function, you must assign values to the function’s arguments: >>> linear_combination(3, 4) What happens when you pass variables? >>> linear_combination(a, b)

Functions – Call by Val / Call by Ref What is the difference? Run

Functions – Call by Val / Call by Ref What is the difference? Run ta 3_switch. py to find out!

Functions – Call by Val / Call by Ref What is the difference? Run

Functions – Call by Val / Call by Ref What is the difference? Run ta 3_add. py to find out!

Functions – Call by Val / Call by Ref There are two possibilities: §

Functions – Call by Val / Call by Ref There are two possibilities: § Call by Value – pass a’s value to x and b’s value to y a, b a=3 A_function x=3 b=4 y=4 § Call by Reference – pass a’s address to x and b’s address to y a, b a=[1, 2] b=[3, 4] Another_function x y

Functions – Call by Reference In Python – Call by reference A function can

Functions – Call by Reference In Python – Call by reference A function can mutate its parameters. When the address does not change, the mutations effect the original caller's environment. Remember: Assignment changes the address! That explains why y=2*y is not visible in the caller's environment.

Functions – Call by Reference def increment(lst): for i in range(len(lst)): lst[i] = lst[i]

Functions – Call by Reference def increment(lst): for i in range(len(lst)): lst[i] = lst[i] +1 # no value returned Now let us execute it in the following manner >>> list 1=[0, 1, 2, 3] >>> increment(list 1) >>> list 1 [1, 2, 3, 4] # list 1 has changed! lst was mutated inside the body of increment(lst). Such change occurs only for mutable objects.

Functions – Call by Reference Consider the following function: def nullify(lst): lst=[ ] #

Functions – Call by Reference Consider the following function: def nullify(lst): lst=[ ] # no value returned Now let us execute it in the following manner >>> list 1=[0, 1, 2, 3] >>> nullify(list 1) >>> list 1 [0, 1, 2, 3] # list 1 has NOT changed! Why?

Functions - Information Flow To conclude, we saw two ways of passing information from

Functions - Information Flow To conclude, we saw two ways of passing information from a function back to its caller: § Using return value(s) § Mutating a mutable parameter

Frequency Counter § Assume you want to learn about the frequencies of English letters.

Frequency Counter § Assume you want to learn about the frequencies of English letters. § You find a long and representative text and start counting. § Which data structure will you use to keep your findings? supercalifragilisticexpialidocio us

Frequency Counter str 1 = 'supercalifragilisticexpialidocious‘ # count letters char. Count = {} for

Frequency Counter str 1 = 'supercalifragilisticexpialidocious‘ # count letters char. Count = {} for char in str 1: char. Count[char] = char. Count. get(char, 0) + 1 # sort alphabetically sorted. Char. Tuples = sorted(char. Count. items())

Frequency Counter # print for char. Tuple in sorted. Char. Tuples: print char. Tuple[0]

Frequency Counter # print for char. Tuple in sorted. Char. Tuples: print char. Tuple[0] , ‘ = ‘, char. Tuple[1] a=3 c=3 d=1 e=2 f= 1 g=1 …

Simulation – Reminder In class: Simulated a rare disease by: Generating its distribution in

Simulation – Reminder In class: Simulated a rare disease by: Generating its distribution in the entire population, assume we received 2% Generating a sample of 1000 people. For every person – “toss a coin” with 2% chance of “heads” (have the disease) and 98% of “tails” (don’t have the disease) Check whether the number of sick people is significantly higher then expected (20 people) Repeat for 100 diseases

Simulation - Cards Scenario: Generate 25 playing cards. Guess which series every card belongs

Simulation - Cards Scenario: Generate 25 playing cards. Guess which series every card belongs to. One card - there is an equal chance that the card belongs to each of the four series, hence - 25% chance for being correct. Two cards – 16 options with equal chance 6. 25% chance n cards – 4 n options, 1/ 4 n chance of being correct in all guesses. For 25 cards the chance of being always correct drops to almost 0.

Simulation - Comparison Role Diseases Cards Number of Guesses 100 diseases 1000 people Number

Simulation - Comparison Role Diseases Cards Number of Guesses 100 diseases 1000 people Number of Observations 1000 people 25 cards Rate (Expectation) Generated per each disease 25% per series

Exercise - Dice Odds In backgammon, there are 36 combinations of rolling the dice.

Exercise - Dice Odds In backgammon, there are 36 combinations of rolling the dice. We are interested in the sum of the two dice. Therefore: § count the number of combinations for every possible sum § find the chance of getting it.

Exercise - Dice Odds Create the following data structure: § Each combination of two

Exercise - Dice Odds Create the following data structure: § Each combination of two dice is a tuple. § All combinations are held in a dictionary, where the key is the sum of the combination. § Each value in the dictionary is a list of tuples – that is, all combinations that sum to key Keys Values 2 [ (1 , 1) ] 3 [ (1 , 2) , (2, 1) ] 4 [ (1 , 3) , (2 , 2) , (3 , 1) ]

Exercise - Dice Odds The general outline is: rolls = {} Loop with d

Exercise - Dice Odds The general outline is: rolls = {} Loop with d 1 from 1 to 6 Loop with d 2 from 1 to 6 new. Tuple ← ( d 1, d 2 ) # create the tuple old. List ← dictionary entry for d 1+d 2 new. List ← old. List + new. Tuple update dictionary entry Loop over all keys in the dictionary print key, length of the list Let’s Play!

Exercise - Dice Odds rolls = {} for d 1 in range(1, 7): #

Exercise - Dice Odds rolls = {} for d 1 in range(1, 7): # first dice for d 2 in range(1, 7): # second dice t = (d 1, d 2) key = d 1+d 2 val = rolls. get(key, []) # update list val. append(t) rolls[key] = val for key in rolls. keys(): print key, len( rolls[key] ) # print result

Exercise - Dice Odds >>> 2 1 3 2 4 3 5 4 6

Exercise - Dice Odds >>> 2 1 3 2 4 3 5 4 6 5 7 6 8 5 9 4 10 3 11 2 12 1