exec, callback, and iterators -...
Post on 22-Apr-2018
234 Views
Preview:
TRANSCRIPT
exec, callback, and iterators
1 The exec Functionchanging programs at run timeconstructing and defining the Simpson rule
2 Adding a Callback Functiona function for Newton’s methoda function of the user to process results
3 A Newton Iteratordefining a counter classrefactoring the Newton function into a class
MCS 507 Lecture 10Mathematical, Statistical and Scientific Software
Jan Verschelde, 19 September 2012
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 1 / 35
exec, callback, and iterators
1 The exec Functionchanging programs at run timeconstructing and defining the Simpson rule
2 Adding a Callback Functiona function for Newton’s methoda function of the user to process results
3 A Newton Iteratordefining a counter classrefactoring the Newton function into a class
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 2 / 35
executing Python code
The exec executes a string containing Python code.
>>> exec("x=3")
This cannot be done with eval.
We illustrate exec turning a formula into a function:
The code for the function definition is stored in a triple quotedstring, spanning multiple lines.
An %s marks the position to insert a formula.
The insertion is done by the % operator.
Calling exec on the code defines the function.
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 3 / 35
the script show_exec.py
from math import *
formula = raw_input(’Give a formula in x : ’)code = """def f(x):
return %s""" % formulaexec(code)x = input(’give a value for x : ’)y = f(x)print formula, "at x =", x , "is", y
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 4 / 35
running show_exec.py
At the command prompt $ we type
$ python show_exec.pyGive a formula in x : x**2 + 3give a value for x : 2x**2 + 3 at x = 2 is 7
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 5 / 35
exec, callback, and iterators
1 The exec Functionchanging programs at run timeconstructing and defining the Simpson rule
2 Adding a Callback Functiona function for Newton’s methoda function of the user to process results
3 A Newton Iteratordefining a counter classrefactoring the Newton function into a class
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 6 / 35
code from lecture 9
from sympy import *var(’a,b,wa,wm,wb’)rule = lambda f: wa*f(a) + wm*f((a+b)/2) \
+ wb*f(b)b0 = lambda x: 1; b1 = lambda x: xb2 = lambda x: x**2; var(’f,x’)e0 = rule(b0) - integrate(b0(x),(x,a,b))e1 = rule(b1) - integrate(b1(x),(x,a,b))e2 = rule(b2) - integrate(b2(x),(x,a,b))R = solve((e0,e1,e2),(wa,wm,wb))v = rule(f)s = Subs(v,(wa,wm,wb), \(R[wa],R[wm],R[wb])).doit()
formula = factor(s)
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 7 / 35
defining a function
We use exec to turn formulainto a function for the Simpson rule:
code = """def Simpson(f,A,B):
y = %sz = Subs(y,(a,b),(A,B)).doit()return z
""" % formulaexec(code)
Observe the difference between the symbolic variables a and b in theformula and the actual names of the formal parameters in Simpson.
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 8 / 35
testing the function
We integrate any quadric (using sympy):
print ’integrating c0+c1*x+c2*x**2 over [L,U]’var(’c0,c1,c2,L,U’)q = lambda x: c0 + c1*x + c2*x**2vr = simplify(Simpson(q,L,U))print ’approximation :’, vrer = integrate(q(x),(x,L,U))print ’ exact value :’, erprint ’ the error :’, vr - er
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 9 / 35
exec, callback, and iterators
1 The exec Functionchanging programs at run timeconstructing and defining the Simpson rule
2 Adding a Callback Functiona function for Newton’s methoda function of the user to process results
3 A Newton Iteratordefining a counter classrefactoring the Newton function into a class
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 10 / 35
Newton’s method
from sympy import *def Newton(f,df,x0,n=5,eps=1.0e-8):
"""Runs Newton’s method on f(x) = 0.INPUT PARAMETERS :
f a function in one variable,df derivative of the function f,x0 initial guess for the root,n maximum number of iterations,eps accurary requirement on |f(x)|
and on the update to x, |dx|.ON RETURN : the tuple (x,dx,y,fail), with:
x approximation for the root,dx magnitude of last correction,y residual |f(x)|,fail is true if accuracy not reached.
"""
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 11 / 35
the body of the function
def Newton(f,df,x0,n=5,eps=1.0e-8):" ... "x = x0; fail = Truefor i in xrange(n):
dx = -f(x)/df(x)x = x + dxy = abs(f(x))if ((abs(dx) <= eps) or (y <= eps)):
fail = Falsebreak
return (x,abs(dx),y,fail)
Observe the break: to exit the for loop when the accuracyrequirement is reached.
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 12 / 35
the main function
def main():"""Prompts the user for an expression in x,computes its derivative and calls Newton."""var(’x’)e = input(’Give an expression in x : ’)d = e.diff(x) # using sympyf = lambda v: Subs(e,(x),(v)).doit()df = lambda v: Subs(d,(x),(v)).doit()x0 = input(’Give an initial guess : ’)x0 = float(x0) # force float arithmeticprint Newton(f,df,x0)
main()
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 13 / 35
running newtonfun.py
At the command prompt $, we type
$ python newtonfun.pyGive an expression in x : exp(-x**2)*sin(x)Give an initial guess : 0.3(-4.08514573514360e-9, 0.00120525211528220, \
4.08514573514360e-9, False)$
What if we want intermediate output?
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 14 / 35
exec, callback, and iterators
1 The exec Functionchanging programs at run timeconstructing and defining the Simpson rule
2 Adding a Callback Functiona function for Newton’s methoda function of the user to process results
3 A Newton Iteratordefining a counter classrefactoring the Newton function into a class
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 15 / 35
a callback function
def print_steps(D):"""Prints the content of the dictionary Dand prompts the user to continue or not."""s = ""for k in D.keys():
s = s + " " + k + ’ = ’if ((k == ’dx’) or (k == ’res’)):
s = s + (’%.3e’ % D[k])else:
s = s + str(D[k])print sanswer = raw_input("continue ? (y/n) ")return (answer == ’y’)
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 16 / 35
using the callback
def Newton(f,df,x0,n=5,eps=1.0e-8,g=None):
Inside the for loop:
if g != None:D = {’step’: i+1, ’x’: x, ’dx’: dx, ’res’: y}proceed = g(D)if proceed != None:
if not proceed: break
In main: print Newton(f,df,x0,g=print_steps)
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 17 / 35
running newtoncallback.py
$ python newtoncallback.pyGive an expression in x : exp(-x**2)*sin(x)Give an initial guess : 0.3
x = -0.0798341284754188 step = 1 \dx = -3.798e-01 res = 7.924e-02
continue ? (y/n) yx = 0.00120524803013647 step = 2 \
dx = 8.104e-02 res = 1.205e-03continue ? (y/n) y
x = -4.08514573514360e-9 step = 3 \dx = -1.205e-03 res = 4.085e-09
continue ? (y/n) n(-4.08514573514360e-9, 0.00120525211528220, \
4.08514573514360e-9, False)
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 18 / 35
exec, callback, and iterators
1 The exec Functionchanging programs at run timeconstructing and defining the Simpson rule
2 Adding a Callback Functiona function for Newton’s methoda function of the user to process results
3 A Newton Iteratordefining a counter classrefactoring the Newton function into a class
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 19 / 35
a Counter class
class Counter():"""Our first class stores a counter."""def __init__(self,v=0):
"""Sets the counter to the value v."""self.count = v
def __str__(self):"""Returns the string representation."""return "counter is " + str(self.count)
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 20 / 35
use in Python session
If the class definition is saved in classcounter.py:
>>> from classcounter import *>>> c = Counter(3)>>> print ccounter is 3>>> str(c)’counter is 3’
Although we are not supposed to, we can manipulate the data attributeof an object of the class Counter directly:>>> c.count3>>> c.count = -4>>> ccounter is -4
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 21 / 35
class definition continued
If c is a Counter object, then typing c at the interactive prompt is thesame as print c.__repr__().
def __repr__(self):"""Defines the representation."""return self.__str__()
def next(self):"""Adds one to the counter."""self.count = self.count + 1
The next() method models an iterator.
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 22 / 35
a test function
def test():"""Performs a simple test."""c = Counter(3)print cc.next()print c
if __name__=="__main__": test()
Because of the last line, we run as
$ python classcounter.pycounter is 3counter is 4
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 23 / 35
exec, callback, and iterators
1 The exec Functionchanging programs at run timeconstructing and defining the Simpson rule
2 Adding a Callback Functiona function for Newton’s methoda function of the user to process results
3 A Newton Iteratordefining a counter classrefactoring the Newton function into a class
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 24 / 35
a Newton iterator
Problem: Adding a callback function to a Newton functionwe can see intermediate results and even stop the iteration,but the callback function remains subordinate to the mainfunction that performs the Newton iterations.
The class NewtonIterator defines an object that storesthe state of all variables in a Newton iteration.
Applying the next() method to an object of the classNewtonIterator executes one Newton step.
Control of the execution is reverted to the consumer.
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 25 / 35
using newtoniterator
>>> from newtoniterator import *>>> f = lambda x: x**2 - 2.0>>> df = lambda x: 2.0*x>>> nf = NewtonIterator(f,df,2.0)>>> print nfstep 0 : x = 2.0000000000000000e+00, \
|dx| = 1.000e+00, |f(x)| = 2.000e+00>>> nf.next()>>> print nfstep 1 : x = 1.5000000000000000e+00, \
|dx| = 5.000e-01, |f(x)| = 2.500e-01
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 26 / 35
storing the state
class NewtonIterator():"""A Newton iterator applies the Newton operatorto find a solution to the equation f(x) = 0."""def __init__(self,f,df,x0,n=5,eps=1.0e-8):
"""Initializes the state of the iterator."""self.step = 0self.f = fself.df = dfself.x = float(x0)self.max = nself.eps = epsself.dx = 1.0self.res = abs(f(x0))
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 27 / 35
printing the state
def __str__(self):"""Returns the string representationof the data attributes."""s = "step %d : " % self.steps = s + ("x = %.16e" % self.x)s = s + (", |dx| = %.3e" % self.dx)s = s + (", |f(x)| = %.3e" % self.res)return s
def __repr__(self): return self.__str__()
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 28 / 35
a Newton step
def next(self):"""Does one Newton step."""self.step = self.step + 1if (self.step > self.max):
raise StopIteration("only %d \steps allowed" % self.max)
else:z = self.xself.dx = -self.f(z)/self.df(z)self.x = z + self.dxself.dx = abs(self.dx)self.res = abs(self.f(self.x))
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 29 / 35
raising an exception
If we have reached the maximum number of steps:
>>> nf.next()Traceback (most recent call last):
File "<stdin>", line 1, in <module>File "newtoniterator.py", line 63, in nextraise StopIteration("only %d steps allowed" % self.max)
StopIteration: only 5 steps allowed
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 30 / 35
the stop test
def accurate(self):"""Returns True if the accuracy requirementsare satisfied. Returns False otherwise."""return ((self.dx <= self.eps) or
(self.res <= self.eps))
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 31 / 35
the test function
def test():"""Approximates the square root of 2."""f = lambda x: x**2 - 2.0df = lambda x: 2.0*xnf = NewtonIterator(f,df,2.0)print nffor i in xrange(5):
nf.next()print nfif nf.accurate(): break
if __name__=="__main__": test()
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 32 / 35
running newtoniterator.py
$ python newtoniterator.pystep 0 : x = 2.0000000000000000e+00, \|dx| = 1.000e+00, |f(x)| = 2.000e+00
step 1 : x = 1.5000000000000000e+00, \|dx| = 5.000e-01, |f(x)| = 2.500e-01
step 2 : x = 1.4166666666666667e+00, \|dx| = 8.333e-02, |f(x)| = 6.944e-03
step 3 : x = 1.4142156862745099e+00, \|dx| = 2.451e-03, |f(x)| = 6.007e-06
step 4 : x = 1.4142135623746899e+00, \|dx| = 2.124e-06, |f(x)| = 4.511e-12
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 33 / 35
Summary + Exercises
Refactoring code defined by a loop as an iterator via a class gives theuser more flexibility.
Exercises:1 Replace the break and the enclosing for loop in the functionNewton of the script newtonfun.py by an equivalent whileloop.
2 Write a script that prompts the user for n, the number of iterationsin a for loop that calls scipy.integrate.simps in its body.With each new call the number of function evaluations inscipy.integrate.simps doubles. Put the loop in a functionwhich takes n as an input parameter.Add a callback function to this function.
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 34 / 35
more exercises
3 Make an iterator for the composite Simpson rule, usingscipy.integrate.simps. In each step of the iterator, the totalnumber of function evaluations doubles.
4 Write code for your own composite Simpson rule to be used in aniterator fashion. Organize the computations so that all previousfunction evaluations are recycled.
The second homework is due on Friday 21 September, at 10AM:solve exercises 1 and 3 of Lecture 4; exercises 4 and 5 of Lecture 5;exercises 1, 2 and 5 of Lecture 6; exercises 1, 2, and 4 of Lecture 7.
Scientific Software (MCS 507) exec, callback, and iterators 19 Sep 2012 35 / 35
top related