1062 (lecture 5): python (part 2) - 20120113

124 days ago by William_Stein

Recall from last time that in Python:
v = [1, 2, 3] w = v w[0] = 10 v 
       
[10, 2, 3]
[10, 2, 3]

Show examples in book of Matlab and Mathematica (probably) copy-on-write. So watch out! Code that looks identical in Sage and Matlab can do very different things.

 
       
 
       

Control Flow

  • if -- choose what code to evaluate
  • while -- evaluate code as long as expression evaluates to True
  • for -- iterate over something

if

a = 2; b = 3 if a > b: c = 5 print (1) elif a == b: c = 10 print (2) else: c = 20 print (3) print "-----" 
       
3
-----
3
-----
       
20
20

Discussion: Indentation instead of brackets (etc.).

Dangerous code in C or Java:

if (a > b)     
    c = 5;       
    x = 10;

The above misleading code can't be written in Python.

 
       

while

i = 5 while i > 0: print(i) i = i - 1 
       
5
4
3
2
1
5
4
3
2
1

break (from a while loop)

i = 25 while i > 0: print(i) i = i - 1 if i == 20: break 
       
25
24
23
22
21
25
24
23
22
21

Python does not have a "do ... while <expr>" construction.

for

Iterate over something.

for i in [1, 2, 7, 15]: print i, i*i 
       
1 1
2 4
7 49
15 225
1 1
2 4
7 49
15 225

You can also use break in for loops (just like with while loops):

for i in [1, 2, 7, 15]: print i, i*i if i == 7: break 
       
1 1
2 4
7 49
1 1
2 4
7 49

Examples of things to iterate over:

range(10) 
       
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
range(5, 20) 
       
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
[5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
range(5, 21, 2) 
       
[5, 7, 9, 11, 13, 15, 17, 19]
[5, 7, 9, 11, 13, 15, 17, 19]
[1..10] 
       
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[5,7, .., 21] 
       
[5, 7, 9, 11, 13, 15, 17, 19, 21]
[5, 7, 9, 11, 13, 15, 17, 19, 21]
(1,3,..,9) 
       
<generator object ellipsis_iter at 0x5766050>
<generator object ellipsis_iter at 0x5766050>
for i in (1,3,..,21): print i, 
       
1 3 5 7 9 11 13 15 17 19 21
1 3 5 7 9 11 13 15 17 19 21
 
       

List Comprehensions

A way to create lists that looks like a for loop.

[i*i for i in [1,2,7,15]] 
       
[1, 4, 49, 225]
[1, 4, 49, 225]
v = [1/3, 2, 3, 'abc', 'xyz'] w = [type(z) for z in v] w 
       
[<type 'sage.rings.rational.Rational'>, <type
'sage.rings.integer.Integer'>, <type
'sage.rings.integer.Integer'>, <type 'str'>, <type
'str'>]
[<type 'sage.rings.rational.Rational'>, <type 'sage.rings.integer.Integer'>, <type 'sage.rings.integer.Integer'>, <type 'str'>, <type 'str'>]
v = [n for n in [1..250] if is_prime(n^2+1)] v 
       
[1, 2, 4, 6, 10, 14, 16, 20, 24, 26, 36, 40, 54, 56, 66, 74, 84, 90, 94,
110, 116, 120, 124, 126, 130, 134, 146, 150, 156, 160, 170, 176, 180,
184, 204, 206, 210, 224, 230, 236, 240, 250]
[1, 2, 4, 6, 10, 14, 16, 20, 24, 26, 36, 40, 54, 56, 66, 74, 84, 90, 94, 110, 116, 120, 124, 126, 130, 134, 146, 150, 156, 160, 170, 176, 180, 184, 204, 206, 210, 224, 230, 236, 240, 250]
 
       

Functions

Use def

def f(a, b, c=10): print "a=", a, "b=", b, "c=",c return a+b+c 
       
f(1,2,5) 
       
a= 1 b= 2 c= 5
8
a= 1 b= 2 c= 5
8
f(1,2) 
       
a= 1 b= 2 c= 10
13
a= 1 b= 2 c= 10
13
f(a=1, c=3, b=2) 
       
a= 1 b= 2 c= 3
6
a= 1 b= 2 c= 3
6

Variable Scope

c = 1; d = 1 def bar(a, b): global d c = a; d = b print c, d 
       
bar(5,10) 
       
5 10
5 10
c,d 
       
(1, 10)
(1, 10)

Python "functions" are not functions in the sense of mathematics.  They depend on more than their input, and can have side effects.

def f(x): import time if int(time.time()) % 2 == 0: return x^2 else: return x^3 
       
f(2) 
       
4
4
f(2) 
       
4
4
f(2) 
       
8
8
plot(f, figsize=[8,2]) 
       
plot(f, figsize=[8,2]) 
       
 
       

Arguments of functions are just new references to an object (just like assignments):

def f(v): print "v -->", id(v) v[0] = 10 print v 
       
v = [1,2,7] print id(v) f(v) 
       
90500488
v --> 90500488
[10, 2, 7]
90500488
v --> 90500488
[10, 2, 7]
       
[10, 2, 7]
[10, 2, 7]
v = [1,2,7] print id(v) f(copy(v)) 
       
108833536
v --> 90694144
[10, 2, 7]
108833536
v --> 90694144
[10, 2, 7]

Standard mistake that you may never make:  a default list as input

def f(a, L=[]): print "L -->", id(L) L.append(a) print L 
       
f(1) 
       
L --> 106352584
[1]
L --> 106352584
[1]
f(2) 
       
L --> 106352584
[1, 2]
L --> 106352584
[1, 2]
f(3) 
       
L --> 106352584
[1, 2, 3]
L --> 106352584
[1, 2, 3]

Recursion

It works, but by default it is limited.

def fac(n): # assume input >= 1 return n if n==1 else n*fac(n-1) 
       
fac(5) 
       
120
120
fac(1100) 
       
WARNING: Output truncated!  
full_output.txt



Traceback (click to the left of this block for traceback)
...
RuntimeError: maximum recursion depth exceeded in cmp
WARNING: Output truncated!  
full_output.txt



Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_101.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("ZmFjKDExMDAp"),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/tmp/tmpanid85/___code___.py", line 3, in <module>
    exec compile(u'fac(_sage_const_1100 )
  File "", line 1, in <module>
    
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac

...

    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
  File "/tmp/tmp8es5Q5/___code___.py", line 4, in fac
    return n if n==_sage_const_1  else n*fac(n-_sage_const_1 )
RuntimeError: maximum recursion depth exceeded in cmp
import sys sys.getrecursionlimit() 
       
1000
1000
sys.setrecursionlimit(1000000) 
       
fac(1100) 
       
534370848809263770342421558229505611830801307688668954088274588180366180\
507230142593359743515667883274154675144889870336145824766456944642617389\
104733808858036231887137145451981246007462271428980768726544820445627938\
521384696779273305727495769481668074212168774982084587690054053663052207\
974765307461854174761407828535465327192407514146840446037688836558176964\
615337214194379121252115480979065230041337053263382381903878504838477803\
724588229236052052802737146250787678631254934255034752507195831922837186\
030239875807777800355948130376137959023725202218865036777462816124054696\
067849623033545571878068013262711078162177228752949470718358225524298555\
062659304726235529400439683750995457229825772063311815720595326782817708\
920420936288168056236465773117812572473654112151753182299528872746983872\
340629193606959156392223691790438526372745935906675613488166812498098047\
697386214801382532597457501623884675983655617265690103925964794592333024\
323536810983017987978944342677864199822342261966341544427566312125083062\
324656190016824389531140071376929493673248560712179251586301228003899683\
281401139943312168491213607465195878608574071289179201422918723640246484\
582489779977603613604718849834315506364003926574273569421105427234464838\
229595036372921748183592701478838442454491279935703996801454263268591217\
411293039868708405683574547193689070618929850174592801197517541507435597\
289982955567323602505100388178442747542851341998969076383964477727378271\
071547961192019215362150550579304549119593219720589371606769113577207430\
589945046720705494848261132473585053881617998656177083673499543703808532\
192432883186291945808989805781924389370357686568396818659379312091885082\
282670831506561018936080655136970279976803222392921356379936817819124988\
714512823673236915860472014331087898518943799844045922160923039163416282\
747378951005309376545654483238563097799645410120160626688816981494456970\
335134673327992503771447719262504033078194051236272349251363303333031943\
725505672666478934559485065930513420665737267456485791075859859536589310\
456140360381555965691258129225797502605868499261246665965245515699452002\
476606332869836526626211811389591512469040731053588029798552054188230707\
892213626619862738697277632967887268727487919402518596797342957419685013\
036891174178271574199813848317234052091159529637811519976390901131118896\
757105267934486097267301995911743575358800329297051491721051468122364760\
559105886494816369278793601900859787526572270771248827682569134013497568\
169550577062064755085844944156336082567893030480431935935274066793521165\
881294443099150565491295279276352340940609556759543421730501252476349532\
078080000000000000000000000000000000000000000000000000000000000000000000\
000000000000000000000000000000000000000000000000000000000000000000000000\
000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000
53437084880926377034242155822950561183080130768866895408827458818036618050723014259335974351566788327415467514488987033614582476645694464261738910473380885803623188713714545198124600746227142898076872654482044562793852138469677927330572749576948166807421216877498208458769005405366305220797476530746185417476140782853546532719240751414684044603768883655817696461533721419437912125211548097906523004133705326338238190387850483847780372458822923605205280273714625078767863125493425503475250719583192283718603023987580777780035594813037613795902372520221886503677746281612405469606784962303354557187806801326271107816217722875294947071835822552429855506265930472623552940043968375099545722982577206331181572059532678281770892042093628816805623646577311781257247365411215175318229952887274698387234062919360695915639222369179043852637274593590667561348816681249809804769738621480138253259745750162388467598365561726569010392596479459233302432353681098301798797894434267786419982234226196634154442756631212508306232465619001682438953114007137692949367324856071217925158630122800389968328140113994331216849121360746519587860857407128917920142291872364024648458248977997760361360471884983431550636400392657427356942110542723446483822959503637292174818359270147883844245449127993570399680145426326859121741129303986870840568357454719368907061892985017459280119751754150743559728998295556732360250510038817844274754285134199896907638396447772737827107154796119201921536215055057930454911959321972058937160676911357720743058994504672070549484826113247358505388161799865617708367349954370380853219243288318629194580898980578192438937035768656839681865937931209188508228267083150656101893608065513697027997680322239292135637993681781912498871451282367323691586047201433108789851894379984404592216092303916341628274737895100530937654565448323856309779964541012016062668881698149445697033513467332799250377144771926250403307819405123627234925136330333303194372550567266647893455948506593051342066573726745648579107585985953658931045614036038155596569125812922579750260586849926124666596524551569945200247660633286983652662621181138959151246904073105358802979855205418823070789221362661986273869727763296788726872748791940251859679734295741968501303689117417827157419981384831723405209115952963781151997639090113111889675710526793448609726730199591174357535880032929705149172105146812236476055910588649481636927879360190085978752657227077124882768256913401349756816955057706206475508584494415633608256789303048043193593527406679352116588129444309915056549129527927635234094060955675954342173050125247634953207808000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
 
       

By the way, Sage's builtin factorial function (which is part of the MPIR library) is pretty damn fast (far faster to compute the answer than convert it to decimal):

time n = factorial(10^6) 
       
Time: CPU 0.94 s, Wall: 0.94 s
Time: CPU 0.94 s, Wall: 0.94 s
time len(str(n)) 
       
5565709
Time: CPU 5.50 s, Wall: 5.47 s
5565709
Time: CPU 5.50 s, Wall: 5.47 s
 
       

Symbolic Functions

These are used for Calculus.  They are also called "functions" but have little to do with Python functions.

f(x) = sin(x)*log(x) f 
       
x |--> log(x)*sin(x)
x |--> log(x)*sin(x)
type(f) 
       
<type 'sage.symbolic.expression.Expression'>
<type 'sage.symbolic.expression.Expression'>
f(pi/2) 
       
log(1/2*pi)
log(1/2*pi)
f.integrate(x) 
       
x |--> -log(x)*cos(x) + 1/2*Ei(-I*x) + 1/2*Ei(I*x)
x |--> -log(x)*cos(x) + 1/2*Ei(-I*x) + 1/2*Ei(I*x)
f.plot((x,0,10), figsize=[8,2]) 
       
 
       

Classes (your own data types)

class MyRational: def __init__(self, n, d): self._n = Integer(n); self._d = Integer(d) def __repr__(self): return '%s/%s'%(self._n, self._d) def __add__(self, right): return MyRational(self._n*right._d + self._d*right._n, self._d*right._d) def __mul__(self, right): return MyRational(self._n*right._n, self._d*right._d) def reduced_form(self): """Return the reduced form of this rational number.""" a = self._n / self._d return MyRational(a.numerator(), a.denominator()) 
       
a = MyRational(2,6); b = MyRational(2, 3) print a, b 
       
2/6 2/3
2/6 2/3
a.reduced_form() 
       
1/3
1/3
c = a + b; c 
       
18/18
18/18
c.reduced_form() 
       
1/1
1/1

How do you think we should get the following to work?

a - b 
       
Traceback (click to the left of this block for traceback)
...
TypeError: unsupported operand type(s) for -: 'instance' and 'instance'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "_sage_input_52.py", line 10, in <module>
    exec compile(u'open("___code___.py","w").write("# -*- coding: utf-8 -*-\\n" + _support_.preparse_worksheet_cell(base64.b64decode("YSAtIGI="),globals())+"\\n"); execfile(os.path.abspath("___code___.py"))
  File "", line 1, in <module>
    
  File "/private/var/folders/4z/h5m3q9b94zs641jlbxj79sv00000gn/T/tmp5CsvSO/___code___.py", line 2, in <module>
    exec compile(u'a - b
  File "", line 1, in <module>
    
TypeError: unsupported operand type(s) for -: 'instance' and 'instance'
 
       

Next: Extensive discussion of Python data types such as lists, tuples, strings, etc.