Apr 02-04, 2018 Vikrant Patil
These notes are available online at http://notes.pipal.in/2018/vmware-advanced-apr
© Pipal Academy LLP
We will be using anaconda (python 3) distribution for this training. it can be downloaded from
%%file trace.py
import os
level = 0
def log(*args):
if os.getenv("DEBUG")=="true":
print(*args)
def trace(f):
def wrapper(*args, **kwargs):
global level
log("| " * level + "|-- " + f.__qualname__, args)
level += 1
value = f(*args)
level -= 1
log("| " * level + "|-- " + "return", value)
return value
return wrapper
%%file fib.py
import sys
from trace import trace
@trace
def fib(n):
if n in [1,2]:
return 1
else:
return fib(n-1) + fib(n-2)
if __name__ == "__main__":
print(fib(int(sys.argv[1])))
!DEBUG="true" python fib.py 12
!time -p python fib.py 30
Recursion gives elegant solution , but creates memory issues, resulting in slow computation. We can make use of tyechnique called memoization to cache the results and avoid repetative calls with same parameters.
%%file memoize.py
def memoize(f):
cache = {}
def wrapper(*args):
if args not in cache:
cache[args] = f(*args)
return cache[args]
return wrapper
%%file fib1.py
import sys
from trace import trace
from memoize import memoize
@memoize
@trace
def fib(n):
if n in [1,2]:
return 1
else:
return fib(n-1) + fib(n-2)
if __name__ == "__main__":
print(fib(int(sys.argv[1])))
!DEBUG="true" python fib1.py 12
!DEBUG="true" python fib.py 12
!time -p python fib1.py 30
def decor1(f):
def wrapper(*args):
print("From decor1")
return f(*args)
return wrapper
def decor2(f):
def wrapper(*args):
print("From decor2")
return f(*args)
return wrapper
@decor1
@decor2
def f():
pass
def g():
pass
def g():
pass
g = decor2(decor1(g))
g()
def g():
pass
g = decor1(decor2(g))
g()
@decor1
@decor2
def g():
pass
g()
%%file functions.py
from collections import deque
def cat(filename):
print(open(filename))
def head(filename, n=5):
with open(filename) as f:
for i in range(n):
print(f.readline(), end="")
def tail(filename, n=5):
history = deque(maxlen=n)
for line in open(filename):
history.append(line.strip())
print("\n".join(history))
%%file functions1.py
from collections import deque
from commands import command, main
@command
def cat(filename):
"""
prints given file to standard output
"""
print(open(filename).read())
@command
def head(filename, n="5"):
with open(filename) as f:
for i in range(int(n)):
print(f.readline(), end="")
@command
def tail(filename, n="5"):
"""
shows last few lines of file
"""
history = deque(maxlen=int(n))
for line in open(filename):
history.append(line.strip())
print("\n".join(history))
if __name__ == "__main__":
main()
%%file commands.py
import sys
cache = {}
def command(f):
global cache
cache[f.__qualname__] = f
return f
def help_():
print("Available commands are")
for name, f in cache.items():
print(name, ":", f.__doc__)
def main():
cmd = sys.argv[1]
args = sys.argv[2:]
if cmd in cache:
f = cache[cmd]
f(*args)
else:
help_()
if __name__ == "__main__":
pass
!python functions1.py cat data.csv
Advantages of generators
import os
def find(root):
for path, dname, filenames in os.walk(root):
for file in filenames:
yield os.sep.join([path, file])
def take(seq, n):
return [next(seq) for i in range(n)]
def integers():
i = 1
while True:
yield i
i += 1
ints = integers()
take(ints, 10)
take(ints, 10)
for i in reversed([1,2,3,4,5]):
print(i)
r = reversed([1,2,3])
for i in r:
print(i)
for i in r:
print(i)
files = find(os.getcwd())
take(files, 5)
[i*i for i in range(10)]
(i*i for i in range(10))
def grep(pattern, seq):
import re
p = re.compile(pattern)
return (item for item in seq if p.match(item))
def count(seq):
i = 0
for item in seq:
i +=1
return i
files = find("/home/vikrant/trainings/2018/")
pyfiles = grep("^.*\.py$", files)
take(pyfiles,5)
def readlines(files):
for file in files:
for line in open(file):
yield line
files = find("/home/vikrant/trainings/2018/")
pyfiles = grep("^.*\.py$", files)
lines = readlines(pyfiles)
funcs = grep("^def .*:$", lines)
count(funcs)
problems
def five():
i = 0
while i < 5:
yield i
i += 1
f = five()
f
next(f)
next(f)
next(f)
next(f)
next(f)
next(f)
f = five()
for i in f:
print(i)
next(f)
def get_paragraphs(lines):
para = []
for line in lines:
if line.strip()=="":
if para:
yield "".join(para)
para = []
else:
para.append(line)
if para:
yield "".join(para)
import requests
resp = requests.get("https://ia801405.us.archive.org/12/items/prideandprejudic01342gut/pandp12.txt")
f = open("pnp.txt", "w")
f.write(resp.text)
f.close()
!python functions1.py tail pnp.txt
paras = get_paragraphs(open("pnp.txt"))
count(paras)
def integers():
i = 1
while True:
yield i
i += 1
n1 = integers()
n2 = integers()
def addseq(seq1, seq2):
for i,j in zip(seq1, seq2):
yield (i+j)
n3 = addseq(n1, n2)
take(n3, 10)
take(n3, 10)
n4 = addseq(n1, [1,2,3,4,5])
count(n4)
def consumedups(seq):
seen = set()
for item in seq:
if item not in seen:
seen.add(item)
yield item
c = consumedups([1,1,2,2,1,4,2,7,2,4,5,2])
for i in c:
print(i, end=",")
%%file bank0.py
balance = 0
def get_balance():
return balance
def withdraw(amount):
global balance
balance -= amount
def deposit(amount):
global balance
balance += amount
if __name__ == "__main__":
pass
%%file bank1.py
def make_account():
return {"balance":0}
def get_balance(account):
return account['balance']
def witdraw(account, amount):
account['balance'] -= amount
def deposit(account, amount):
account["balance"] += amount
if __name__ == "__main__":
a1 = make_account()
a2 = make_account()
a1.get_balance()
class BankAccount:
def __init__(self, balance=0):
self._balance = balance
def get_balance(self):
return self._balance
def deposit(self, amount):
self._balance += amount
def witdraw(self, amount):
self._balance -= amount
a = BankAccount()
BankAccount
a
type(a)
a.__dict__
a._balance
a.x = 10
a.__dict__
a.x
BankAccount._balance
b = BankAccount()
b.x
a.x
b.y = 20
b.y
a.y
class Light:
color = "white"
def __init__(self, status="off"):
self.status = status
l1 = Light()
l2 = Light("on")
l1.status
l2.status
l1.color
l2.color
Light.color
Light.color = "yellow"
l1.color
l2.color
l1.color = "red"
Light.color
l2.color
l1.color
vars(Light)
vars(l1)
vars(l2)
class Shape:
def area(self):
pass
class Circle(Shape):
def __init__(self, r):
self.radius = r
def area(self):
return 3.14*self.radius**2
class Square(Shape):
def __init__(self, s):
self.side = s
def area(self):
return self.side**2
class Rectangle:
def __init__(self, l, w):
self.len = l
self.width = w
def area(self):
return self.len*self.width
class Poly:
def __init__(self, sides):
self.sides = sides
shapes = [Circle(1), Square(1), Rectangle(1,1)]
areas = [s.area() for s in shapes]
areas
shapes.extend([Circle(2), Poly([10,10,20,30,12])])
areas = [s.area() for s in shapes]
count(get_paragraphs(open("pnp.txt")))
count(get_paragraphs(["A\n", "B\n","\n","C"]))
class Poly1(Shape):
pass
shapes1 = [Circle(1), Square(1), Rectangle(1,1), Poly1()]
[s.area() for s in shapes1]
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
p = Pair(1,2)
p
print(p)
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):
return "<{},{}>".format(self.x, self.y)
print(Pair(2,3))
p = Pair(1,2)
p
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):#print uses this, also str
return "<{},{}>".format(str(self.x), str(self.y))
def __repr__(self): # this is used by interpreter, also by repr
return "Pair({},{})".format(repr(self.x), repr(self.y))
Pair(1,2)
p = Pair(1,2)
str(p)
repr(p)
p1 = Pair(0,0)
p2 = Pair(1,1)
p3 = Pair(p1, p2)
print(p3)
p3
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __str__(self):#print uses this, also str
return "<{},{}>".format(str(self.x), str(self.y))
def __repr__(self): # this is used by interpreter, also by repr
return "Pair({},{})".format(repr(self.x), repr(self.y))
def __add__(self, p):
return Pair(self.x+p.x, self.y+ p.y)
def __sub__(self, p):
return Pair(self.x-p.x, self.y-p.y)
def __mul__(self, c):
return Pair(c*self.x, c*self.y)
def __rmul__(self, c):
return Pair(c*self.x, c*self.y)
def __eq__(self, p):
return self.x==p.x and self.y == p.y
p1 = Pair(1,1)
p1 + p1
p1 - p2
p1*2
2*p1
p1 == p1
p1 == Pair(1,1)
problem
t = Timer()
t.start()
saxpy()
t.stop()
print(t.time_taken)
class Foo:
def __init__(self, f):
self.foo = f
def bar(self):
pass
def foobar(self):
self.bar = 0
f = Foo(2)
vars(f)
f.bar()
f.foobar()
f.bar
f.bar()
class A:
def __init__(self):
print("A.__init__")
class B(A):
def __init__(self):
print("B.__init__")
super().__init__()
class C(B):
def __init__(self):
print("C.__init__")
super().__init__()
A()
B()
C()
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
self.z = (x+y)/2
class ColoredPoint(Point):
def __init__(self, x, y, color):
self.x = x
self.y = y
self.color = color
cp = ColoredPoint(2,3,"red")
cp.z
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
self.z = (x+y)/2
class ColoredPoint(Point):
def __init__(self, x, y, color):
super().__init__(x,y)
self.color = color
cp = ColoredPoint(1,2,"red")
cp.z
%matplotlib inline
import math
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def distance(p1, p2):
xdelta = p1.x - p2.x
ydelta = p1.y - p2.y
return math.sqrt(xdelta**2 + ydelta**2)
class Shape:
origin = Point(250,250)
def contains(self, point):
pass
class Circle(Shape):
def __init__(self, r):
self.r = r
def contains(self, p):
return distance(p, self.origin) <= self.r
class Rectangle(Shape):
def __init__(self, w, l):
self.l = l
self.w = w
def contains(self, p):
xd = abs(p.x - self.origin.x)
yd = abs(p.y - self.origin.y)
return xd <= self.l and yd <= self.w
class Union(Shape):
def __init__(self, items):
self.items = items
def contains(self, p):
flag = False
for s in self.items:
flag = flag or s.contains(p)
return flag
class Intersection(Shape):
def __init__(self, items):
self.items = items
def contains(self, p):
flag = True
for s in self.items:
flag = flag and s.contains(p)
return flag
import matplotlib.pyplot as plt
def imshow(img):
plt.imshow(img, cmap=plt.cm.gray)
plt.show()
class Canvas:
def __init__(self, w, l):
self.w = w
self.l = l
self.data = [[False for i in range(w)] for i in range(l)]
def paint(self, shape):
self.data = [[shape.contains(Point(i,j)) or self.data[i][j]
for i in range(self.w)] for j in range(self.l)]
def display(self):
imshow(self.data)
c = Canvas(500, 500)
c1 = Circle(50)
c.paint(c1)
c.display()
r = Rectangle(25,75)
c.paint(r)
c.display()
c = Canvas(500,500)
i = Intersection([Circle(50), Rectangle(30,80)])
c.paint(i)
c.display()
c = Canvas(500, 500)
u = Union([Circle(50), Rectangle(30,80)])
c.paint(u)
c.display()
class Foo:
def __setattr__(self, name, value):
if name not in ["x","y"]:
raise Exception("You can set only x,y")
self.__dict__[name] = value
def __getattr__(self, name):
print("__getattr__", name)
if name in ["x","y"]:
return self.__dict__[name]
else:
raise AttributeError("No such attribute", name)
f = Foo()
f.x = 2
f.x
f.z = 4
f.z
problem
import requests
url = "https://api.github.com/orgs/vmware/repos"
repos = requests.get(url).json()
type(repos)
for r in repos:
print(r['full_name'], r['forks'])