Transcript

Recitation 3

Programming for Engineers in Python

PlanModules / PackagesTuples

Mutable / ImutableDictionariesFunctions:

Scope Call by Ref / Call by Val

Frequency Counter

Module

Python Code Hierarchy

Statement

function

Package

Modules

All modules and their contents (functions, constants) can be found athttp://docs.python.org/modindex.html

>>> import math # mathematical functions >>> dir(math)['__doc__', '__name__', '__package__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'hypot', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'modf', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc']

>>> math.pi # a constant3.141592653589793>>> math.sqrt(16) # a function4.0>>> math.log(8, 2)3.0

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

PackagesNumPy

support for large, multi-dimensional arrays and matriceshigh-level mathematical functions

SciPy Optimization linear algebra integrationspecial functionssignal and image processingAnd more

Installing PackagesDownload NumPy:

http://sourceforge.net/projects/numpy/files/NumPy/

Choose Download numpy-1.6.1-win32-superpack-python2.7.exe

SciPy:

http://sourceforge.net/projects/scipy/files/

Choose Download scipy-0.9.0-win32-superpack-python2.6.exe

Mutable vs. ImmutableCan 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. ImmutableWhat 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'TypeError: 'str' object does not support item assignment

Immutable!

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

[1000,7,8,9]

>>> copy_list

[1000,7,8,9]

Surprise!

Assignments to List VariablesList 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.

[6,7,8,9 ]

Memoryorig_list

Assignments to List VariablesThe 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.

[6,7,8,9 ]

Memoryorig_list

copy_list

Assignments to List VariablesMutating list elements, orig_list[0] = 1000, does not create a new object and does not change existing references.

[1000,7,8,9 ]

Memoryorig_list

copy_list

TuplesA 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):

File "<pyshell#2>", line 1, in <module>

t[0]=‘do’

TypeError: 'tuple' object does not support item assignment

No append / extend / remove in Tuples!

TuplesSo what are tuples good for?

Faster than lists

Safe code

When immutable types are required (coming next).

DictionariesA dictionary is a set of key-value pairs.>>> dict_name = {key1:val1, key2:val2,…}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

DictionariesAdd 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?

DictionariesIdea: 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}TypeError: unhashable type: 'list‘What’s the problem?Fix:>>> heights = {(‘Alan Harper’, ‘Malibu’):1.76}>>> heights{('Alan Harper', 'Malibu'): 1.76}

DictionariesUseful 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 – ScopeConsider the following function, operating on two

arguments:

def linear_combination(x,y):y=2*yreturn (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.

linear_combination

x, y

3, 4 11

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

Functions – Scope>>> x=3>>> y=4>>> linear_combination(x,y)11 # this is the correct value>>> x3>>> y4The y in the calling environment and the y in the

function are not the same variable!

Functions – Call by Val / Call by RefFunctions 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 RefWhat is the difference? Run ta3_switch.py to find out!

Functions – Call by Val / Call by RefWhat is the difference? Run ta3_add.py to find out!

b=[3, 4]a=[1,2]

Functions – Call by Val / Call by RefThere are two possibilities: Call by Value – pass a’s value to x and

b’s value to y

Call by Reference – pass a’s address to x and b’s address to y

A_function

x = 3 y = 4

a, b

b=4a=3

a, b Another_function

x y

Functions – Call by ReferenceIn 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 Referencedef increment(lst):

for i in range(len(lst)):lst[i] = lst[i] +1

# no value returnedNow let us execute it in the following manner>>> list1=[0,1,2,3]>>> increment(list1)>>> list1[1, 2, 3, 4] # list1 has changed!

lst was mutated inside the body of increment(lst). Such change occurs only for mutable objects.

Functions – Call by ReferenceConsider the following function:def nullify(lst):

lst=[ ]# no value returnedNow let us execute it in the following manner>>> list1=[0,1,2,3]>>> nullify(list1)>>> list1[0, 1, 2, 3] # list1 has NOT changed!Why?

Functions - Information FlowTo 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. You find a long and representative text and start

counting. Which data structure will you use to keep your

findings?

s u p e r c a l i f r a g i l i s t i c e x p i a l i d o c i o u s

Frequency Counterstr1 = 'supercalifragilisticexpialidocious‘

# count letters

charCount = {}

for char in str1:

charCount[char] = charCount.get(char, 0) + 1

# sort alphabetically

sortedCharTuples = sorted(charCount.items())

Frequency Counter# printfor charTuple in sortedCharTuples:

print charTuple[0] , ‘ = ‘, charTuple[1]

a = 3c = 3d = 1e = 2f = 1g = 1…

Simulation – Guess Cardsצורהשם עברישם אנגליצבע

♠עלה/פיקSpadesשחור

♥לבHeartsאדום

♦יהלום/מעויןDiamondsאדום

♣תלתןClubsשחור

Simulation – ReminderIn 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 - CardsScenario: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 – 4n options, 1/ 4n chance of being correct in all guesses. For 25 cards the chance of being always correct drops to almost 0.

Simulation - ComparisonRoleDiseasesCards

Number of Guesses100 diseases1000 people

Number of Observations

1000 people25 cards

Rate (Expectation)Generated per each disease

25% per series

Exercise - Dice Odds

In backgammon, there are 36combinations 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 OddsCreate 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

2

4

3

Keys Values

) ]1 , 1 [ (

) ]1 , 2) , (2 ,1 [ (

) ]1 , 3) , (2 , 2) , (3 , 1 [ (

Exercise - Dice OddsThe general outline is:rolls = {}Loop with d1 from 1 to 6

Loop with d2 from 1 to 6 newTuple ← ( d1, d2 ) # create the tuple oldList ← dictionary entry for d1+d2 newList ← oldList + newTuple update dictionary entry

Loop over all keys in the dictionary print key, length of the list

Let’s Play!

Exercise - Dice Oddsrolls = {}for d1 in range(1, 7): # first dice

for d2 in range(1, 7): # second dicet = (d1, d2)key = d1+d2val = rolls.get(key, []) # update listval.append(t)rolls[key] = val

for key in rolls.keys(): # print resultprint key, len( rolls[key] )

Exercise - Dice Odds>>>2 13 24 35 46 57 68 59 410 311 212 1


Top Related