Recitation 3 Programming for Engineers in Python.
-
Upload
kelley-dorthy-bruce -
Category
Documents
-
view
227 -
download
0
Transcript of Recitation 3 Programming for Engineers in Python.
PlanModules / PackagesTuples
Mutable / ImutableDictionariesFunctions:
Scope Call by Ref / Call by Val
Frequency Counter
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)
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] )