Advanced Python Training at VMWare - Day 3

May 28-30, 2018 Vikrant Patil

These notes are available online at http://notes.pipal.in/2018/vmware-advanced-may

© Pipal Academy LLP

Day 1 | Day 2 | Day 3

Python distribution

We will be using anaconda (python 3) distribution for this training. it can be downloaded from

https://www.anaconda.com/download/

why classes

In [1]:
%%file bank0.py

balance = 0

def get_balance():
    return balance

def deposite(amount):
    global balance
    balance += amount
    
def withdraw(amount):
    global balance
    balance -= amount
    
if __name__ == "__main__":
    print(get_balance())
    deposite(10)
    print(get_balance())
    deposite(5)
    print(get_balance())
Writing bank0.py
In [2]:
import bank0 as bank
In [3]:
%%file bank1.py

def make_account(balance=0):
    return {"balance":balance}

def get_balance(account):
    return account['balance']

def deposite(account, amount):
    account['balance'] += amount
    
def witdraw(account, amount):
    account['balance'] -= amount
    
if __name__ == "__main__":
    a1 = make_account(10)
    a2 = make_account()
    print(get_balance(a1))
Writing bank1.py
In [29]:
class BankAccount:
    
    def __init__(self, balance=0, name=None):
        self._balance = balance
        self._name = name
        self._email = "@".join([name, "vmware.com"])
        
    def get_balance(self):
        return self._balance
    
    def get_name(self):
        return self._name
    
    def get_email(self):
        return self._email
    
    def deposite(self, amount):
        self._balance += amount
        
    def withdraw(self, amount):
        self._balance -= amount
        
    
In [30]:
def foo():
    pass
In [31]:
foo
Out[31]:
<function __main__.foo>
In [32]:
BankAccount
Out[32]:
__main__.BankAccount
In [33]:
type(BankAccount)
Out[33]:
type
In [34]:
a1 =  BankAccount(100, "Python")
In [35]:
a1
Out[35]:
<__main__.BankAccount at 0x7f9bd85979e8>
In [36]:
type(a1)
Out[36]:
__main__.BankAccount
In [37]:
a1.get_balance()
Out[37]:
100
In [38]:
type(range(5))
Out[38]:
range
In [15]:
type(range)
Out[15]:
type
In [16]:
class Foo:
    x = 10
    
    def method(self):
        pass
In [19]:
Foo # this is class object
Out[19]:
__main__.Foo
In [20]:
f = Foo() # this is instance object
In [39]:
a1.get_email()
Out[39]:
'Python@vmware.com'
In [40]:
ef = BankAccount.get_email
In [41]:
ef
Out[41]:
<function __main__.BankAccount.get_email>
In [42]:
mf = a1.get_email
In [43]:
mf
Out[43]:
<bound method BankAccount.get_email of <__main__.BankAccount object at 0x7f9bd85979e8>>
In [44]:
BankAccount.get_email()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-e81aec9490b3> in <module>()
----> 1 BankAccount.get_email()

TypeError: get_email() missing 1 required positional argument: 'self'
In [45]:
a1.get_email()
Out[45]:
'Python@vmware.com'
In [46]:
a1
Out[46]:
<__main__.BankAccount at 0x7f9bd85979e8>
In [47]:
BankAccount.get_email(a1)
Out[47]:
'Python@vmware.com'
In [48]:
a1._email
Out[48]:
'Python@vmware.com'
In [49]:
class Foo:
    x = 10
    
    def __init__(self, y):
        self.y = y
In [50]:
Foo.x
Out[50]:
10
In [51]:
Foo.x
Out[51]:
10
In [53]:
f = Foo(5)
In [54]:
f.x
Out[54]:
10
In [55]:
f.y
Out[55]:
5
In [56]:
f1 = Foo(3)
In [57]:
f1.x
Out[57]:
10
In [59]:
f1.y
Out[59]:
3
In [60]:
Foo.x = 15
In [61]:
f.x
Out[61]:
15
In [62]:
f1.x
Out[62]:
15
In [63]:
f1.x = 10
In [64]:
f.z = 30
In [65]:
f1.x = 10
In [67]:
f1.x
Out[67]:
10
In [68]:
Foo.x
Out[68]:
15
In [69]:
f.x
Out[69]:
15

Customizing classes

In [70]:
Foo
Out[70]:
__main__.Foo
In [71]:
f
Out[71]:
<__main__.Foo at 0x7f9bd8597ba8>
In [72]:
print(f)
<__main__.Foo object at 0x7f9bd8597ba8>
In [73]:
x, y = 2, 3
x, y = y, x
In [74]:
l = [1,2,3]
l
Out[74]:
[1, 2, 3]
In [75]:
print(l)
[1, 2, 3]
In [76]:
class Pair:
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
   
In [77]:
p  = Pair(1,2)
In [78]:
p
Out[78]:
<__main__.Pair at 0x7f9bd85ab160>
In [79]:
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 "({0.x!s}, {0.y!s})".format(self)
In [80]:
p1 = Pair(1,2)
In [81]:
p1
Out[81]:
Pair(1, 2)
In [82]:
print(p1)
(1, 2)
In [83]:
p2 = Pair(3,4)
In [84]:
p3  = Pair(p1, p2)
In [85]:
p3
Out[85]:
Pair(Pair(1, 2), Pair(3, 4))
In [86]:
print(p3)
((1, 2), (3, 4))
In [87]:
class Pair1:
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __repr__(self):
        return str(self)
      
    
    def __str__(self):
        return "({0.x!s}, {0.y!s})".format(self)
In [88]:
Pair1(1,2)
Out[88]:
(1, 2)
In [89]:
str(p1)
Out[89]:
'(1, 2)'
In [90]:
p1.__str__()
Out[90]:
'(1, 2)'
In [91]:
print(p1)
(1, 2)
In [92]:
repr(p1)
Out[92]:
'Pair(1, 2)'
In [94]:
p1.__repr__()
Out[94]:
'Pair(1, 2)'
In [95]:
p1
Out[95]:
Pair(1, 2)
In [98]:
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 "({0.x!s}, {0.y!s})".format(self)
    
    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)
    
    
    
    
In [96]:
l * 2
Out[96]:
[1, 2, 3, 1, 2, 3]
In [97]:
2 * l
Out[97]:
[1, 2, 3, 1, 2, 3]
In [99]:
p1 = Pair(2,3)
In [100]:
p2 = (Pair(5,6))
In [101]:
p1 + p2
Out[101]:
<Pair(7, 9)>
In [102]:
p1
Out[102]:
<Pair(2, 3)>
In [103]:
p2
Out[103]:
<Pair(5, 6)>
In [104]:
p2 - p1
Out[104]:
<Pair(3, 3)>
In [105]:
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 "({0.x!s}, {0.y!s})".format(self)
    
    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 __getitem__(self, index):
        if index==0:
            return self.x
        elif index==1:
            return self.y
        else:
            raise IndexError("index can be only 0 or 1")
In [106]:
p1 = Pair(2,3)
In [107]:
p2 = Pair(5,8)
In [108]:
p1 + p2
Out[108]:
<Pair(7, 11)>
In [109]:
p2 - p1
Out[109]:
<Pair(3, 5)>
In [111]:
p1[0]
Out[111]:
2
In [112]:
p1[6]
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
<ipython-input-112-961bfb828db5> in <module>()
----> 1 p1[6]

<ipython-input-105-f3f17e9fe937> in __getitem__(self, index)
     24             return self.y
     25         else:
---> 26             raise IndexError("index can be only 0 or 1")

IndexError: index can be only 0 or 1

Inheritance

In [113]:
class Point:
    
    def __init__(self, x, y):
        self.x = x
        self.y = y
        
In [114]:
class ColoredPoint(Point):
    
    color = (0,0,0)
    
In [115]:
class ColoredPoint(Point):
    
    def __init__(self, x, y, color):
        #super().__init__(x,y)
        Point.__init__(self, x, y)
        self.color = (0,0,0)
    
In [119]:
class Base:
    
    def __init__(self):
        print("Base")
        
class A(Base):
    
    def __init__(self):
        Base.__init__(self)
        print("A")
        
class B(Base):
    
    def __init__(self):
        Base.__init__(self)
        print("B")
        
class C(A,B):
    
    def __init__(self):
        A.__init__(self)
        B.__init__(self)
        print("C")
In [120]:
C()
Base
A
Base
B
C
Out[120]:
<__main__.C at 0x7f9bd85596a0>
In [123]:
class Base:
    
    def __init__(self):
        print("Base")
        
class A(Base):
    
    def __init__(self):
        #Base.__init__(self)
        super().__init__()
        print("A")
        
class B(Base):
    
    def __init__(self):
        #Base.__init__(self)
        super().__init__()
        print("B")
        
class C(A,B):
    
    def __init__(self):
        super().__init__()
        print("C")
In [124]:
C()
Base
B
A
C
Out[124]:
<__main__.C at 0x7f9bd85593c8>
In [125]:
C.__mro__
Out[125]:
(__main__.C, __main__.A, __main__.B, __main__.Base, object)
In [126]:
Base.__dict__
Out[126]:
mappingproxy({'__dict__': <attribute '__dict__' of 'Base' objects>,
              '__doc__': None,
              '__init__': <function __main__.Base.__init__>,
              '__module__': '__main__',
              '__weakref__': <attribute '__weakref__' of 'Base' objects>})
In [127]:
p1
Out[127]:
<Pair(2, 3)>
In [128]:
p1.__dict__
Out[128]:
{'x': 2, 'y': 3}

problem

  • Write a class Timer which works as given below.
    t = Timer()
    t.start()
    time.sleep(2)
    t.stop()
    print("Time taken for the task", t.get_time_taken())
    2.001
In [129]:
import time

class Timer:
    
    def start(self):
        self.start_ = time.time()
        
    def stop(self):
        self.stop_ = time.time()
        
    def time_taken(self):
        return self.stop_ - self.start_
In [130]:
t = Timer()
In [131]:
t.start()
time.sleep(3)
t.stop()
print(t.time_taken())
3.001075267791748

Context managers

In [133]:
class ContextTimer(Timer):
    
    def __enter__(self):
        print("Start of with block")
        self.start()
        return self
    
    def __exit__(self, exception_type,exception_value, traceback):
        self.stop()
        print("End of with block")
        print("Time taken:", self.time_taken())
        
In [135]:
with ContextTimer() as t:
    s = 0.0
    print("Inside with block")
    for i in range(1000):
        for j in range(10000):
            s += i*j*1.0
Start of with block
Inside with block
End of with block
Time taken: 2.873403787612915

Controlling attributes

In [136]:
class Bar:
    pass
In [137]:
b = Bar()
In [138]:
b.x = 10
In [139]:
class Immutable:
    
    def __setattr__(self, name, value):
        raise Exception("No chance!")
        
In [140]:
a = Immutable()
In [141]:
a.x = 4
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-141-0168863fedce> in <module>()
----> 1 a.x = 4

<ipython-input-139-5d94559a6eab> in __setattr__(self, name, value)
      2 
      3     def __setattr__(self, name, value):
----> 4         raise Exception("No chance!")
      5 

Exception: No chance!
In [142]:
class UpperCase: 
    
    def __getattr__(self, name):
        return name.upper()
In [143]:
u = UpperCase()
In [144]:
u.vmware
Out[144]:
'VMWARE'
In [145]:
u.x
Out[145]:
'X'

problem

  • Write a class Foo which has attribute called bar. using setattr make it private!
In [177]:
class Foo:
    
    def __init__(self, bar, name):
        self.name = name
        self.__dict__['bar'] = bar
        #self.bar = bar
        
    def __setattr__(self, name, value):
        if name == "bar":
            raise Exception("bar is private variable!")
        elif not isinstance(value, str):
            raise TypeError("Name should be a string!")
        
In [178]:
f = Foo(3, "Python")
In [179]:
f.bar = 5
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-179-dbccefba043c> in <module>()
----> 1 f.bar = 5

<ipython-input-177-73550c03ed5f> in __setattr__(self, name, value)
      8     def __setattr__(self, name, value):
      9         if name == "bar":
---> 10             raise Exception("bar is private variable!")
     11         elif not isinstance(value, str):
     12             raise TypeError("Name should be a string!")

Exception: bar is private variable!
In [180]:
f.name = "java"
In [181]:
f.name = 3
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-181-c2f1e811f9f5> in <module>()
----> 1 f.name = 3

<ipython-input-177-73550c03ed5f> in __setattr__(self, name, value)
     10             raise Exception("bar is private variable!")
     11         elif not isinstance(value, str):
---> 12             raise TypeError("Name should be a string!")
     13 

TypeError: Name should be a string!
In [176]:
isinstance("name", str)
Out[176]:
True
In [182]:
class OptimizedDate:
    __slots__ = ["year","month","day"]
    
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day
        
    
In [183]:
d = OptimizedDate(2018,1,1)
In [184]:
d.year = 2013
In [185]:
d.x = 3
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-185-fb5fc190eec1> in <module>()
----> 1 d.x = 3

AttributeError: 'OptimizedDate' object has no attribute 'x'
In [186]:
class MyDate(OptimizedDate):
    
    def __init__(self, y, m , d, x):
        super().__init__(y, m, d)
        self.x = x
In [189]:
d = MyDate(2010,1,1,4)
In [190]:
d.__slots__
Out[190]:
['year', 'month', 'day']
In [192]:
d.z = 3

staticmethod and classmethod

In [193]:
class Foo:
    
    def method1(self):
        pass
    
    def function():
        pass
In [194]:
Foo.function()
In [195]:
Foo.method1()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-195-7fb007739be1> in <module>()
----> 1 Foo.method1()

TypeError: method1() missing 1 required positional argument: 'self'
In [197]:
class Bar:
    
    @staticmethod
    def getinstance():
        return Bar()
    
    
class Foo:
    
    def method1(self):
        pass
    
    def getinstance():
        return Foo()
In [198]:
Foo.getinstance()
Out[198]:
<__main__.Foo at 0x7f9bd85630b8>
In [199]:
f = Foo()
In [200]:
f.getinstance()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-200-629dc5589bff> in <module>()
----> 1 f.getinstance()

TypeError: getinstance() takes 0 positional arguments but 1 was given
In [201]:
Bar.getinstance()
Out[201]:
<__main__.Bar at 0x7f9bd85027b8>
In [202]:
b = Bar()
In [203]:
b.getinstance()
Out[203]:
<__main__.Bar at 0x7f9bd85024e0>
In [204]:
import datetime
class Mydate(datetime.datetime):
    pass
In [205]:
d = datetime.datetime.now()
In [206]:
type(d)
Out[206]:
datetime.datetime
In [209]:
datetime.datetime.today()
Out[209]:
datetime.datetime(2018, 5, 30, 14, 16, 46, 752903)
In [210]:
Mydate.now()
Out[210]:
Mydate(2018, 5, 30, 14, 16, 57, 480691)
In [212]:
class MyInt:
    
    def __init__(self, n):
        self.n = n
    
    @staticmethod
    def parseint(strvalue):
        return MyInt(int(strvalue))
In [213]:
MyInt.parseint("3")
Out[213]:
<__main__.MyInt at 0x7f9bd852ae80>
In [214]:
class Int(MyInt):
    pass
In [215]:
Int.parseint("4")
Out[215]:
<__main__.MyInt at 0x7f9bd852aa20>
In [216]:
class MyInt:
    
    def __init__(self, n):
        self.n = n
    
    @classmethod
    def parseint(cls, strvalue):
        return cls(int(strvalue))
    
class Int(MyInt):
    pass
In [217]:
Int.parseint("5")
Out[217]:
<__main__.Int at 0x7f9bd850b828>

properties

In [221]:
class Person:
    
    def __init__(self, name, lastname):
        self._name = name
        self._lastname = lastname
    
    @property
    def email(self):
        return "@".join([self._name, "vmware.com"])
    
    @email.setter
    def email(self, value):
        raise Exception("Can not set email!")
        
    
    @email.deleter
    def email(self):
        raise Exception("Can not delete email")
In [222]:
p = Person("anand", "c")
In [223]:
p.email
Out[223]:
'anand@vmware.com'
In [224]:
p.email = "abc@xyz.com"
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-224-8501252af849> in <module>()
----> 1 p.email = "abc@xyz.com"

<ipython-input-221-3e2bc4a6205c> in email(self, value)
     11     @email.setter
     12     def email(self, value):
---> 13         raise Exception("Can not set email!")
     14 
     15 

Exception: Can not set email!
In [225]:
del p.email
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-225-d5c698764d13> in <module>()
----> 1 del p.email

<ipython-input-221-3e2bc4a6205c> in email(self)
     16     @email.deleter
     17     def email(self):
---> 18         raise Exception("Can not delete email")

Exception: Can not delete email

Descriptors

In [231]:
class Integer:
    
    def __init__(self, name):
        self.name = name
        
    def __get__(self, instance, cls):
        print("get from Integer", instance, cls)
        if not instance:
            return self
        return instance.__dict__[self.name]
    
    def __set__(self, instance, value):
        print("set from Integer")
        instance.__dict__[self.name]=value
    
    def __delete__(self, instance):
        print("delete from Integer")
        raise Exception("Can not delete")
    

class Point:
    x = Integer("x")
    y = Integer("y")
    
    def __init__(self, x , y):
        self.x = x
        self.y = y
In [232]:
p = Point(2,3)
set from Integer
set from Integer
In [233]:
p.x
get from Integer <__main__.Point object at 0x7f9bd84b4f28> <class '__main__.Point'>
Out[233]:
2
In [234]:
isinstance(3, int)
Out[234]:
True
In [235]:
3
Out[235]:
3
In [240]:
class my_property:
    
    def __init__(self, f):
        self.f = f
        
    def __get__(self, instance, cls):
        if not instance:
            return self
        return self.f(instance)
    
class Foo:
    
    def __init__(self, x):
        self.x = x
    
    @my_property     ### name = my_property(name)
    def name(self):
        return "Name :" + str(self.x)
In [241]:
f = Foo("xyz")
In [242]:
f.name
Out[242]:
'Name :xyz'

class decorator

In [246]:
from functools import wraps

def methoddebugger(cls):
    
    def debug(f):
        
        @wraps(f)
        def wrapper(*args):
            print("Debugging ..", f.__qualname__)
            return f(*args)
        
        return wrapper
    
    for name, value in vars(cls).items():
        if callable(value):
            setattr(cls, name, debug(value))
    
    return cls

@methoddebugger
class Dummy:
    
    def mathod1(self):
        pass
    
    def method2(self):
        pass
    
    def method3(self):
        pass
In [247]:
d = Dummy()
In [248]:
d.mathod1()
Debugging .. Dummy.mathod1
In [249]:
d.method2()
Debugging .. Dummy.method2
In [250]:
d.method3()
Debugging .. Dummy.method3

Multithreading

In [251]:
import threading
In [258]:
import time
def tick(n):
    for i in range(n):
        print("Tick:",i)
        time.sleep(1)
        
t = threading.Thread(target=tick, args=(10,))
t.start()
print("*"*20)
Tick:******************** 
0
Tick: 1
Tick: 2
Tick: 3
Tick: 4
Tick: 5
Tick: 6
Tick: 7
Tick: 8
Tick: 9
In [260]:
import time
def tick(n):
    for i in range(n):
        print("Tick:",i)
        time.sleep(1)
        
t = threading.Thread(target=tick, args=(10,))
t.start()
t.join()
print("*"*20) # will come here only after thread has finished task
Tick: 0
Tick: 1
Tick: 2
Tick: 3
Tick: 4
Tick: 5
Tick: 6
Tick: 7
Tick: 8
Tick: 9
********************
In [277]:
%%file tdownload.py
import requests
import sys
import threading

def download(url):
    r = requests.get(url)
    r = requests.get(url)
    r = requests.get(url)
    filename = threading.currentThread().getName() + ".txt"
    with open(filename, "w") as f:
        f.write(r.text)

def spawanthread(nthreads):
    args = ["http://httpbin.org/html"]*10
    while args:
        if len(args) < nthreads:
            nthreads = len(args)
        threads = []
        for i in range(nthreads):
            t = threading.Thread(target=download, 
                                 args=(args.pop(),), 
                                 name=str(i))
            threads.append(t)
            
        for t in threads:
            t.start()
            print("started thread:", t.getName())
        for t in threads:
            t.join()
    
if __name__ == "__main__":
    spawanthread(int(sys.argv[1]))
Overwriting tdownload.py
In [279]:
!time -p python tdownload.py 1
started thread: 0
started thread: 0
started thread: 0
started thread: 0
started thread: 0
started thread: 0
started thread: 0
started thread: 0
started thread: 0
started thread: 0
real 26.30
user 0.60
sys 0.04
In [280]:
!time -p python tdownload.py 2
started thread: 0
started thread: 1
started thread: 0
started thread: 1
started thread: 0
started thread: 1
started thread: 0
started thread: 1
started thread: 0
started thread: 1
real 13.82
user 0.56
sys 0.08
In [281]:
!time -p python tdownload.py 4
started thread: 0
started thread: 1
started thread: 2
started thread: 3
started thread: 0
started thread: 1
started thread: 2
started thread: 3
started thread: 0
started thread: 1
real 7.96
user 0.59
sys 0.06
In [287]:
%%file tpdownload.py
import threading
import requests
import sys
from multiprocessing.pool import ThreadPool

def download(url):
    r = requests.get(url)
    r = requests.get(url)
    r = requests.get(url)
    filename = threading.currentThread().getName() + ".txt"
    print("Writing file", filename)
    with open(filename, "w") as f:
        f.write(r.text)

def spawanthread(nthreads):
    args = ["http://httpbin.org/html"]*10
   
    pool = ThreadPool(nthreads)
    pool.map(download, args)
    
    
if __name__ == "__main__":
    spawanthread(int(sys.argv[1]))
Overwriting tpdownload.py
In [289]:
!time -p python tpdownload.py 2
Writing file Thread-1.txt
Writing file Thread-2.txt
Writing file Thread-1.txt
Writing file Thread-2.txt
Writing file Thread-2.txt
Writing file Thread-1.txt
Writing file Thread-1.txt
Writing file Thread-2.txt
Writing file Thread-1.txt
Writing file Thread-1.txt
real 16.89
user 0.65
sys 0.05
In [290]:
!time -p python tpdownload.py 4
Writing file Thread-4.txt
Writing file Thread-1.txt
Writing file Thread-3.txt
Writing file Thread-2.txt
Writing file Thread-3.txt
Writing file Thread-4.txt
Writing file Thread-1.txt
Writing file Thread-2.txt
Writing file Thread-3.txt
Writing file Thread-1.txt
real 9.34
user 0.71
sys 0.07
In [295]:
%%file pcpu.py
from multiprocessing.pool import Pool
import sys
def saxpy(n):
    s = 0.0
    for i in range(1000):
        for j in range(10000):
            s += i*j*1.0
    return s

def spawnprocess(concurrency):
    pool = Pool(concurrency)
    pool.map(saxpy, [1]*10)
    
    
if __name__ == "__main__":
    spawnprocess(int(sys.argv[1]))
Overwriting pcpu.py
In [296]:
!time -p python pcpu.py 2
real 10.31
user 17.10
sys 0.01
In [297]:
!time -p python pcpu.py 1
real 19.35
user 19.25
sys 0.01
In [298]:
!time -p python pcpu.py 2
real 14.05
user 23.97
sys 0.03
In [299]:
!time -p python pcpu.py 4
real 12.90
user 35.33
sys 0.03
In [303]:
import threading
import time
def clock(ticks, e):
    for i in range(ticks):
        print("Tick:",i)
        time.sleep(3)
        if e.isSet():
            print("Boom....stoping!")
            break

e = threading.Event()

t = threading.Thread(target=clock, args=(10, e))
t.start()
Tick: 0
Tick: 1
Tick: 2
In [304]:
e.set()
Boom....stoping!

Sockets

In [306]:
%%file sockets.py
## this is python2.7 code
import SocketServer
import socket
import sys

class MyTCPHandler(SocketServer.BaseRequestHandler):

    def handle(self):
        data = self.request.recv(2048).strip()
        print "%s wrote: " % self.client_address[0]
        print data
        if data=="close":
            self.request.close()
            self.server.shutdown()
        else:
            self.request.send(data.upper())

def start_server():
    HOST, PORT = "127.0.0.1", 3456
    server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
    server.serve_forever()

def send_client_msg():
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(("localhost",3456))
    s.send("This is junk data KJHJKASGHD jhG ASDGH AHSGDJASGH DFJKAGH:OP{IO "*10)
    received = s.recv(1024)
    s.close()
    print "Received: " + received

if __name__ == "__main__":
    start_server()
Writing sockets.py

Commandline applications

In [316]:
%%file grep.py
import argparse

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("pattern",
                       help="Pattern to match")
    parser.add_argument("file", 
                       help="File in which pattern is searched.")
    
    return parser.parse_args()
    

if __name__ == "__main__":
    print(parse_args())
    
    
Overwriting grep.py
In [317]:
!python grep.py --help
usage: grep.py [-h] pattern file

positional arguments:
  pattern     Pattern to match
  file        File in which pattern is searched.

optional arguments:
  -h, --help  show this help message and exit
In [319]:
!python grep.py -h "def" mymodule.py
usage: grep.py [-h] pattern file

positional arguments:
  pattern     Pattern to match
  file        File in which pattern is searched.

optional arguments:
  -h, --help  show this help message and exit
In [323]:
%%file grep.py
import argparse

def parse_args():
    parser = argparse.ArgumentParser()
    parser.add_argument("pattern",
                       help="Pattern to match")
    parser.add_argument("file", 
                       help="File in which pattern is searched.")
    parser.add_argument("-v", "--invert",action="store_true",
                       help="Show lines that do not match pattern")
    parser.add_argument("-n", "--number-of-matches",
                       type=int,
                       help="show only first n matches")
    
    return parser.parse_args()
    

if __name__ == "__main__":
    print(parse_args())
    
    
Overwriting grep.py
In [324]:
!python grep.py -h
usage: grep.py [-h] [-v] [-n NUMBER_OF_MATCHES] pattern file

positional arguments:
  pattern               Pattern to match
  file                  File in which pattern is searched.

optional arguments:
  -h, --help            show this help message and exit
  -v, --invert          Show lines that do not match pattern
  -n NUMBER_OF_MATCHES, --number-of-matches NUMBER_OF_MATCHES
                        show only first n matches
In [322]:
!python grep.py -v "def " mymodule.py
Namespace(file='mymodule.py', invert=True, pattern='def ')
In [325]:
!python grep.py -v -n 5 "def " mymodule.py
Namespace(file='mymodule.py', invert=True, number_of_matches=5, pattern='def ')

References

In [ ]: