Python Tutorial_ Memoization and Decorators
Python Tutorial_ Memoization and Decorators
Home Python 2 Tutorial Python 3 Tutorial Advanced Topics Numerical Programming Machine Learning Tkinter Tutorial Contact
Skilled Python
Memory Programmers
Claude Gaspard But this line has to be directly in front of the decorated function, in our example fib(). The complete example in a Pythonic way looks like this now:
Bachet de Méziriac
was a French Jesuit
and a poet, scholar def memoize(f):
and mathematician. memo = {}
He was born at Bourg def helper(x):
in 1581, and died in if x not in memo:
memo[x] = f(x)
1638. He wrote the
return memo[x]
Problèmes plaisants, return helper
of which the first
edition was issued in @memoize
1612, a second and def fib(n):
enlarged edition was if n == 0:
brought out in 1624; return 0
elif n == 1:
this contains an
return 1
interesting collection else:
of arithmetical tricks return fib(n-1) + fib(n-2)
and questions.
print(fib(40))
In his collection of
"Amusing and
Delightful Number
Problems"
("Problèmes plaisants Using a Callable Class for Memoization
& délectables qui se
font par les This subchapter can be skipped without problems by those who don't know about object orientation so far.
nombres") he had
the puzzle We can encapsulate the caching of the results in a class as well, as you can see in the following example:
(number154), which
we use in our main class Memoize:
text:
"Etant donnée telle def __init__(self, fn):
quantité qu'on self.fn = fn
self.memo = {}
voudra pesant un
nombre de livres def __call__(self, *args):
depuis 1 jusques à if args not in self.memo:
40 inclusivement self.memo[args] = self.fn(*args)
(sans toutefois return self.memo[args]
admettre les
fractions), on @Memoize
demande combien de def fib(n):
if n == 0:
poids pour le moins il
return 0
faudrait employer à elif n == 1:
cet effet" return 1
(English translation: else:
"We are looking for return fib(n-1) + fib(n-2)
the minimum number
of weights to be used
on a scale to weigh As we are using a dictionary, we can't use mutable arguments, i.e. the arguments have to be immutable.
an arbitrary number
of pounds from 1 to
40 inclusive, without Exercise
admitting fractions.)
This website is 1. Our exercise is an old riddle, going back to 1612. The French Jesuit Claude-Gaspar Bachet phrased it. We have to weigh quantities (e.g. sugar or flour) from 1
supported by: to 40 pounds. What is the least number of weights that can be used on a balance scale to way any of these quantities.
Linux and Python The first idea might be to use weights of 1, 2, 4, 8, 16 and 32 pounds. This is a minimal number, if we restrict ourself to put weights on one side and the stuff,
Courses and e.g. the sugar, on the other side. But it is possible to put weights on both pans of the scale. Now, we need only four weights, i.e. 1, 3, 9, 27
Seminars
Write a Python function weigh(), which calculates the weights needed and their distribution on the pans to weigh any amount from 1 to 40.
Solution
def factors_set():
factors_set = ( (i, j, k, l) for i in [-1, 0, 1]
for j in [-1, 0, 1]
for k in [-1, 0, 1]
for l in [-1, 0, 1])
for factor in factors_set:
yield factor
def memoize(f):
results = {}
def helper(n):
if n not in results:
results[n] = f(n)
return results[n]
return helper
@memoize
def linear_combination(n):
""" returns the tuple (i,j,k,l) satisfying
n = i*1 + j*3 + k*9 + l*27 """
weighs = (1,3,9,27)
def weigh(pounds):
weights = (1, 3, 9, 27)
scalars = linear_combination(pounds)
left = ""
right = ""
for i in range(len(scalars)):
if scalars[i] == -1:
left += str(weights[i]) + " "
elif scalars[i] == 1:
right += str(weights[i]) + " "
return (left,right)
© 2011 - 2018, Bernd Klein, Bodenseo; Design by Denise Mitchinson adapted for python-course.eu by Bernd Klein