Oct 22-24, 2018 Vikrant Patil
These notes are available online at http://notes.pipal.in/2018/arcesium-advanced-oct/day3.html
© Pipal Academy LLP
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 withdraw(self, amount):
self.balance -= amount
!cat bank1.py
a1 = BankAccount() # this actually calls __init__ method
a2 = BankAccount(balance=100)
type(a1)
a1.get_balance()
def foo():
pass
foo
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def getX(self):
return self.x
def getY(self):
return self.y
Point
type(Point)
type(Point.getX)
p1 = Point(3,4)
p1.x
type(p1.getX)
func = Point.getX
func()
func(p1)
methodx = p1.getX
methodx()
class Point:
color = "red"
def __init__(self, x, y):
self.x = x
self.y = x
p = Point(0,0)
p.x
p.y
p.color
Point.color
Point.x
class RedPoint:
color = "red"
def __init__(self, x, y):
self.x = x
self.y = x
r1 = RedPoint(0,0)
r2 = RedPoint(1,2)
r1.color
r2.color
RedPoint.color = "white"
r1.color
r2.color
r1.x
r1.z = 30
r1.color = "red"
del r1.color
r1.color
r1.__dict__
Point.__dict__
type(Point.__dict__['__weakref__'])
class Circle:
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14*self.radius**2
class Sqaure:
def __init__(self, side):
self.side = side
def area(self):
return self.side**2
class Traingle:
def __init__(self, a, b, c):
self.a = a
self.b = b
self.c = c
shapes = [Circle(1), Circle(2), Sqaure(2), Sqaure(5)]
areas = [s.area() for s in shapes ]
areas
shapes = [Circle(1), Circle(2), Sqaure(2), Sqaure(5), Traingle(2,3,4)]
[s.area() for s in shapes]
def list_attributes(obj):
for k,v in vars(obj).items():
if not callable(v) and not k.startswith("_"):
print(type(v), k)
list_attributes(r1)
list_attributes(Point)
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Pair({}, {})".format(self.x, self.y)
def __str__(self):
return "<{},{}>".format(self.x, self.y)
p1 = Pair(2,3)
p1
print(p1)
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Pair({0.x!r}, {0.y!r})".format(self)
def __str__(self):
return "<{},{}>".format(self.x, self.y)
Pair(2,3)
Pair(Pair(0,0), Pair(2,3))
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Pair({0.x!r}, {0.y!r})".format(self)
def __str__(self):
return "<{},{}>".format(self.x, self.y)
def __mul__(self, n):
return Pair(self.x*n, self.y*n)
def __rmul__(self, n):
return Pair(self.x*n, self.y*n)
def __eq__(self, p):
return p.x==self.x and p.y==self.y
Pair(2,3)*2
2*Pair(3,4)
Pair(2,3) == Pair(4,5)
Pair(2,3) == Pair(2,3)
class Pair:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return "Pair({0.x!r}, {0.y!r})".format(self)
def __str__(self):
return "<{},{}>".format(self.x, self.y)
def __mul__(self, n):
return Pair(self.x*n, self.y*n)
def __rmul__(self, n):
return Pair(self.x*n, self.y*n)
"""
def __eq__(self, p):
return p.x==self.x and p.y==self.y
"""
def __getitem__(self, key):
if key in ['x','y']:
return getattr(self, key)
else:
raise AttributeError("No such attribute", key)
def __setitem__(self, key, value):
if key in ['x','y']:
setattr(self, key, value)
else:
raise AttributeError("You can not set ", key)
p1 = Pair(3,4)
p2 = Pair(3,4)
p1 == p2
Pair(3,4) == Pair(3,4)
p1['x']
p1['x'] = 5
p1
getattr(p1, "x")
p1['z']
class Sealed:
def __init__(self, x):
self.x = x
def __setattr__(self, key, value):
if key != "x":
raise AttributeError("No chance!")
self.__dict__['x'] = value
s = Sealed(3)
s.x = 5
s.y = 4
Problem
t = (1,2,3,4)
t[0] = 2
class Immutable:
def __init__(self, x, y):
self.__dict__['x'] = x
self.__dict__['y'] = y
def __setattr__(self, k, v):
raise AttributeError("You can not edit this object!")
class Upper:
def __getattr__(self, key):
return key.upper()
u = Upper()
u.python
m = Immutable(2,3)
m.x = 3
class A:
def __init__(self):
print("A.__init__")
class B(A):
def __init__(self):
print("B__init__")
#A.__init__(self)
super().__init__()
class C(B):
def __init__(self):
print("C.__init__")
#B.__init__(self)
super().__init__()
class D(C,B):
def __init__(self):
print("D.__init__")
#C.__init__(self)
#B.__init__(self)
super().__init__()
c = D()
D.mro()
type(D)
type(r1)
type(RedPoint)
class Meta(type):
pass
type(Meta)
class SubMeta(Meta):
pass
type(SubMeta)
class SubMeta1(metaclass=Meta):
pass
type(SubMeta1)
class Singleton(type):
def __init__(self,*args, **kwargs):
print(args)
print(kwargs)
self._instance = None
def __call__(self, *args, **kwargs):
if self._instance:
return self._instance
else:
self._instance = super().__call__(*args, **kwargs)
return self._instance
class SingltonTop(metaclass=Singleton):
pass
x = SingltonTop()
y = X()
x == y
x is y
XYZ = type('XYZ', (), {'__module__': '__main__', '__qualname__': 'XYZ'})
type(XYZ)
x = XYZ()
type(x)
from abc import ABCMeta, abstractmethod
class Shape(metaclass=ABCMeta):
@abstractmethod
def area(self):
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
Circle()
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14*radius**2
c = Circle(3)
type(Circle)
class Foo(metaclass=Shape):
pass
class Integer:
def __init__(self, name):
self.name = name
def __get__(self, instance, cls):
print("__get__", instance, cls)
if not instance:
return self
else:
return instance.__dict__[self.name]
def __set__(self, instance, value):
print("__set__", instance, value)
if isinstance(value, int):
instance.__dict__[self.name] = value
def __delete__(self, instance):
print("__delete__")
raise Exception("Can not delete", self.name)
class Point:
x = Integer('x')
y = Integer('y')
def __init__(self, x, y):
self.x = x
self.y = y
p = Point(2, 3)
p.x
x = 2
Point.x
p.x
Point.__dict__['x'] =
data = 5
type(data)
problem
x = Integer('x')
x = 3
type(x)
class Person:
def __init__(self, name):
self.name = name
@property
def email(self):
return "@".join([self.name, "arcesium.com"])
@email.setter
def email(self, value):
raise Exception("You can not set email like this")
class my_property:
def __init__(self, f):
self.func = f
def __get__(self, instance, cls):
if not instance:
return self
return self.func(instance)
class Person_:
def __init__(self, name):
self.name = name
@my_property
def email(self):
return "@".join([self.name.split()[0], "arcesium.com"])
@my_property
def surname(self):
return self.name.split()[1]
p = Person("vikrant")
p.email
p.email = "xyz@xyz.com"
p = Person_("Vikrant Patil")
p.email
p.surname
import time
class Timer:
def __init__(self):
self._start = 0
self._end = 0
def start(self):
self._start = time.time()
def stop(self):
self._end = time.time()
def get_time_taken(self):
return self._end - self._start
class ContextTimer(Timer):
def reset(self):
self._start = 0
self._end = 0
def __enter__(self):
self.reset()
self.start()
return self
def __exit__(self, exc_ty, exc_val, tb):
self.stop()
print("Time take in with block: ", self.get_time_taken())
with ContextTimer() as t:
time.sleep(2)
import threading
def tick(n):
for i in range(n):
print("Tick-",i)
time.sleep(1)
def reversetick(n):
for i in range(n):
print("Tick-down-",n-i)
time.sleep(1)
t1 = threading.Thread(target=tick, args=(10,))
t2 = threading.Thread(target=reversetick, args=(10,))
t1.start()
t2.start()
def tick(n):
for i in range(n):
print("Tick-",i)
time.sleep(1)
def reversetick(n):
for i in range(n):
print("Tick-down-",n-i)
time.sleep(1)
t1 = threading.Thread(target=tick, args=(10,))
t2 = threading.Thread(target=reversetick, args=(10,))
t1.start()
t2.start()
t1.join()
t2.join()
event = threading.Event()
event.isSet()
event.set()
event.isSet()
def tick(event):
i = 0
while not event.isSet():
print("Tick-", i)
time.sleep(2)
i += 1
event = threading.Event()
t = threading.Thread(target=tick, args=(event,))
t.start()
event.set()
lock = threading.Lock()
def producer(data, lock, event):
while not event.isSet():
lock.acquire()
data.append(1) # protected by lock
print("Produced ...")
lock.release()
time.sleep(1)
def consumer(data, lock, event):
while not event.isSet():
lock.acquire()
data.pop()
print("Consumed ...")
lock.release()
time.sleep(1)
def observer(data, lock, event):
while not event.isSet():
print(data)
time.sleep(1)
data = list(range(5))
lock = threading.Lock()
event = threading.Event()
p = threading.Thread(target=producer, args=(data, lock, event))
c = threading.Thread(target=consumer, args=(data, lock, event))
o = threading.Thread(target=observer, args=(data, lock, event))
o.start()
p.start()
time.sleep(3)
c.start()
event.set()
from multiprocessing.pool import ThreadPool
pool = ThreadPool(4)
import requests
def download(url):
resp = requests.get(url)
return resp
def threaded_download(n):
pool = ThreadPool(n)
url = "http://httpbin.org/get"
urls = [url]*10
res = pool.map(download, urls)
for i in range(1,9):
with ContextTimer() as t:
threaded_download(i)
type(res)
help(pool.apply_async)
from multiprocessing.pool import Pool # process pool
import requests
def saxpy(n):
s = 0
for i in range(n):
for j in range(n):
s += i*j*1.0
return s
def threaded_task(n):
pool = ThreadPool(n)
args = [1000]*10
res = pool.map(saxpy, args)
for i in range(1,5):
with ContextTimer() as t:
threaded_task(i)
def saxpy(n):
s = 0
for i in range(n):
for j in range(n*10):
s += i*j*1.0
return s
def threaded_task(n):
pool = Pool(n)
args = [1000]*10
res = pool.map(saxpy, args)
for i in range(1,5):
with ContextTimer() as t:
threaded_task(i)
%load_ext Cython
%%cython --annotate
def add(x, y):
return x+y
%%timeit
add(100,200)
def add_(x,y):
return x+y
%%timeit
add_(100,200)
%%file cfib.pyx
from __future__ import print_function
def fib(n):
cdef int cur, prev
cur, prev = 1, 1
while cur < n:
cur, prev = cur+prev, cur
print(cur, end=",")
%%file setup.py
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules = cythonize("cfib.pyx"))
!python setup.py build_ext --inplace
!ls cfib.cpython-36m-x86_64-linux-gnu.so
import cfib
cfib.fib(100)
cfib.fib(1000)
%%file sample.c
int add(int x, int y){
return(x+y);
}
!gcc -c sample.c
!gcc -shared -o libsample.so sample.o
!ls libsample.so
import ctypes
import ctypes
import os
_file = "libsample.so"
_path = os.path.join(os.getcwd(), _file)
_mod = ctypes.cdll.LoadLibrary(_path)
add = _mod.add
add.argtypes = (ctypes.c_int, ctypes.c_int)
add.restype = ctypes.c_int
add(5, 8)
%%file struct.c
typedef struct Pair{
double x,y;
} Pair;
class Pair(ctypes.Structure):
_fields_ = [('x', ctypes.c_double),
('y', ctypes.c_double)]
from numba import jit
@jit
def add(x, y):
return x+y
@jit(nogil=True)
def saxpy(n):
s = 0
for i in range(n):
for j in range(n):
s += i*j*1.0
return s
@jit(nopython=True)
def saxpy(n):
s = 0
for i in range(n):
for j in range(n):
s += i*j*1.0
return s
@jit(nopython=True, parallel=True)
def saxpy(n):
s = 0
for i in range(n):
for j in range(n):
s += i*j*1.0
return s