def __getitem__(self,
                 idx):  # __getitem__ make the class slicing like a sequence
     cls = type(self)
     if isinstance(idx, slice):
         return cls(self._components[idx])
     elif isinstance(idx, int):
         return self._components[idx]
     else:
         msg = '{cls.__name__} indices must be integer'
         print_tab(msg.format(cls=cls))
	def clocked(*args, **kwargs):
		t0 = time.time()
		result = func(*args, **kwargs)
		elapsed = time.time() - t0
		name = func.__name__
		arg_lst = []
		if args:
			arg_lst.append(', '.join(repr(arg) for arg in args))
		if kwargs:
			pairs = ['%s=%r' % (k, w) for k, w in sorted(kwargs.items())]
			arg_lst.append(', '.join(pairs))
		arg_str = ', '.join(arg_lst)
		print_tab('[%0.8fs] %s(%s) -> %r ' % (elapsed, name, arg_str, result))
		return result
import collections
import math

from utils import print_tab

##### Using namedtuple to contruct class with no methods
print("[+] Using namedtuple to contruct class with no methods")
Student = collections.namedtuple('Student', ['GPA', 'department'])
student_1 = Student(3.5, 'Economy')
student_2 = Student._make((3.9, 'Computer Science'))

print_tab("Student 1: " + str(student_1))
print_tab("Student 2: " + str(student_2))

##### Implementing special methods
print('[+] Implementing special methods')


class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __repr__(self):
        return f"Vector x: {self.x}, y: {self.y}"

    def __str__(self):
        return f"Vector x: {self.x}, y: {self.y}"

    def __abs__(self):
        return math.sqrt(self.x**2 + self.y**2)
Esempio n. 4
0
from collections import defaultdict, UserDict

from utils import print_tab

### USE defaultdict TO HANDLE MISSING KEYS
print("USE defaultdict TO HANDLE MISSING KEYS")
dd = defaultdict(list)
country_city = [('HaNoi', 'VietNam'), ('Tokyo', 'Japan')]
for city, country in country_city:
    dd[country].append(city)
country_city = [('HaiPhong', 'VietNam'), ('Osaka', 'Japan')]
for city, country in country_city:
    dd[country].append(city)
print_tab(dd)

### USE UserDict TO CREATE A NEW MAPPING CLASS
print('USE UserDict TO CREATE A NEW MAPPING CLASS')


class StrKeyDict(UserDict):
    '''
    A MAPPING TYPE WHICH ONLY ACCEPT KEY AS STRING TYPE
    '''
    def __missing__(self, key):
        if isinstance(key, str):
            raise KeyError(key)
        return self[str(key)]

    def __contains__(self, item):
        return str(item) in self.data
from utils import print_tab
print("Chapter 8: Object References, Mutability,and Recycling".upper())
print("Variable are not boxes".upper())
a = [1, 2, 3]
b = a
print_tab(f'b and a refer to the same object in memory')
a.append(4)
print_tab(f'b get updated if a get updated {b} == {a}')

print('IDENTITY, EQUALITY, ALIASES')
print_tab(
    f'Using id() to get identity of a variable, id of b is: {id(b)}, id of a is: {id(a)}'
)
print_tab(f'a is b if only id of a == id of b')
print_tab(f'a equal to b if only value of a == value of b')

print('CHOOSING BETWEEN == AND is')
print_tab(
    f'In most cases, we use == to compare two variables. However if we compare with singleton (eg: None), we better use is'
)

print('COPY IS SHALLOW BY DEFAULT')
a = [1, (2, 3, 4)]
b = a[:]  # this is copy a to b
print_tab(f'b == a: {b==a}, b is a: {b is a}')
print(
    f'SHALLOW COPY WILL CLONE THE OUTTERMOST OBJECT. IF THE OBJECT CONTAINS MUTABLE OBJECTS, IT DOES NOT CLONE THE INSIDE MUTABLE OBJECTS'
)
a = [1, [2, 3, 4]]
b = list(a)  # shallow copy
b[1].append(5)
def func(a,*,b):
	print_tab(f'a: {a} is positional argument, and b: {b} is keyword-only argument')
'''
CODE EXAMPLES OF CHAPTER 5
'''
from utils import print_tab
print('CHAPTER 5: FIRST-CLASS FUNCTIONS')
print_tab('In python, functions are first class objects')

print('TREATING FUNCTION AS AN OBJECT')
def factorial(n):
	''' Function to calculate factorial of an integer'''
	return 1 if n < 2 else n * factorial(n-1)
print_tab(f'{factorial.__doc__}, type:  {type(factorial)}')

print('HIGHER ORDER FUNCTION')
print_tab('Pass function as argument to another function')
list_str = ['chào mừng', 'tiếng cười', 'bố', 'mẹ', 'con', 'ngôi nhà']
print_tab(f'Using sorting string by length: {sorted(list_str, key=len)}')

print('map, filter CAN BE REPLACED BY LIST COMP')
list_facts = [factorial(n) for n in range(5)]
print_tab(str(list_facts))
list_facts = [factorial(n) for n in range(10) if n%2 == 0]
print_tab(str(list_facts))

from functools import reduce
from operator import add
print('USING reduce, add TO SUM ALL ELEMENTS IN LIST')
print_tab(f'Sum of 10 first integers: {reduce(add, range(10))}')

print('ANONYMOUS FUNCTION/LAMBDA EXPRESSION')
names = ['TRAN MANH HUNG', 'NGUYEN QUANG HUNG', 'PHAN VAN ANH', 'ANH THI VIEN']
Esempio n. 8
0
def print_mro(cls):
	# this function to print mro of a given class
	print_tab(', '.join([c.__name__ for c in cls.__mro__]))
Esempio n. 9
0
from utils import print_tab
outline = ''' CHAPTER 12: Inheritance: For Good or For Worse
OUTLINE:
• The pitfalls of subclassing from built-in types which use C implementation
• Multiple inheritance and the method resolution order
'''
print('Subclassing from built-in types such as list, dict do not allow you to override the superclass methods'.upper())
class SomeDict(dict):
	def __getitem__(self, item):
		return 100 # always return 100 no matter what

somedict  = SomeDict(a = 'hello')
d = {}
d.update(somedict)
print_tab(f'Check getitem: {somedict["a"]}')
print_tab(f'getitem in dict init will ignore getitem inplementation in SomeDict class: {d["a"]}')
print_tab(f'All problems can be fixed if we subclass from collections.UserDict class')

print('METHOD RESOLUTION ORDER')
class A():
	def msg(self):
		return 'This is class A'

class B():
	def msg(self):
		return 'This is class B'

class C(A,B):
	def msg(self):
		return super().msg()
c = C()
        return len(self._components)

    def __getitem__(self,
                    idx):  # __getitem__ make the class slicing like a sequence
        cls = type(self)
        if isinstance(idx, slice):
            return cls(self._components[idx])
        elif isinstance(idx, int):
            return self._components[idx]
        else:
            msg = '{cls.__name__} indices must be integer'
            print_tab(msg.format(cls=cls))


v1 = Vector([1, 2, 3, 4])
print_tab(f'Slicing Vector instance is still a Vector instance: {v1[1:3]}')
v1[1.2]

print('DYNAMIC ATTRIBUTE USING __getattr__')

import string


class Vector_Dyna_Attr(Vector):
    attr_list = string.ascii_lowercase

    def __str__(self):
        return "Vector_Dyna_Attr class, attributes: " + str(self._components)

    def __getattr__(self, name):
        if len(name) == 1:
Esempio n. 11
0
	def __init__(self, text):
		self.text = text
		self.words = RE_WORD.findall(text) #re.findall returns a list with all nonoverlapping matches of the regular expression, as a list of strings.
	def __len__(self):
		return len(self.words)
	def __getitem__(self, item):
		# if item == 0:
		# 	raise KeyError
		return self.words[item]
	def __repr__(self):
		return f'Sentence: {reprlib.repr(self.text)}'
	# def __iter__(self):


s = Sentence('This book is awesome')
print_tab('If __getitem__ is implemented and index starts from 0, class will behave like sequence')
print_tab('__getitem__ does not guarantee the class is iterable when using checking type like issubclass/isinstance')
print_tab(f'Sentence class is Iterable: {issubclass(Sentence, abc.Iterable)}')

print(f'ITERABLEs vs ITERATORs')
print_tab('Iterator can be built from Iterable')
print_tab('Once iterator is exhausted, it is useless. You should delete it')
it = iter(s)
while True:
	try:
		print_tab(f'{next(it)}')
	except StopIteration:
		del it
		break

print(f'DESIGN A CLASSIC ITERATOR')
from utils import print_tab
### BYTES ESSENTIALS
print('BYTES ESSENTIALS')
# string to bytes is encoding,  bytes to string is decoding
cafe = bytes("đứng", encoding='utf-8')
print_tab(f'{cafe}, length = {len(cafe)}')
print_tab(
    f'{cafe.decode(encoding="utf - 8")}, length = {len(cafe.decode(encoding="utf-8"))}'
)

print('Bytes is immutable, Bytearray is mutable')
b = bytes("hello", encoding='utf-8')
b_array = bytearray(b)
print_tab(b)
print_tab(b_array)

print('STRUCT AND MEMORYVIEW')
print(
    'Struct let you parse packed bytes into a tuple of values based on predefined format. Or it can do opposite converting from values to packed bytes'
)
print(
    'Memoryview do not create a new buffer, but provides shared memory access to slices of data'
)

import struct
fmt = '3s3sHH'  # 3s3s two sequence of 3 bytes, HH two short integer 16bits
with open('gif_img.gif', 'rb') as f:
    img = memoryview(f.read())  # no copy here
header = img[:10]  # slicing, no copy here
print_tab(f'Pointer at: {header}, Byte values: {bytes(header)}')
print_tab(f'Unpacked by struck: {struct.unpack(fmt, header)}')
	def inner():
		print_tab('running inner')
def register(func):
	print_tab('running register right after the decorator loaded (%s)' % func)
	registry.append(func)
	return func
import math
import sys

from utils import print_tab

print('CHAPTER 6 - DESIGN PATTERN')
print('Using inspect to get members of a module')


def strategy_1(a, b):
    return (a + b) / 2


def strategy_2(a, b):
    return math.sqrt(a * b)


def best_strat(a, b):
    import inspect
    strats = [
        func for name, func in inspect.getmembers(
            sys.modules[__name__], inspect.isfunction) if 'strategy_' in name
    ]
    return max((strat(a, b) for strat in strats))


print_tab(f'{best_strat(20,10)}')
Esempio n. 16
0
		return len(self._cards)

	def __delitem__(self, key):
		del self._cards[key]

	def __setitem__(self, key, value):
		self._cards[key] = value

	def __getitem__(self, item):
		return self._cards[item]

	def insert(self, index: int, value) -> None:
		self._cards.insert(index, value)

deck = FrenchDeck()
print_tab(f'When inherit from a class with abstract methods. You must implement all abstract methods in subclass. Otherwise, TypeError will be raised in runtime')

print('TO CHECK FOR INTEGER/FLOAT YOU CAN USE numbers MODULE')
from numbers import *

a = 10
print_tab(f'a = {a}, a is integer: {isinstance(a, Integral)}')
print_tab(f'a = {a}, a is float: {isinstance(a, Real)}. a is float because integer is subclass of float')
a = 10.5
print_tab(f'a = {a}, a is integer: {isinstance(a, Integral)}')
print_tab(f'a = {a}, a is float: {isinstance(a, Real)}')

import abc
print('CREATE CUSTOM ABC (Abstract Base Class)')
class Shape(abc.ABC):
	@abc.abstractmethod