# Day 1 week 2: ## We learn about intermediate Python: (https://colab.research.google.com/drive/1VzVTPTkfRzoxcOouZDkpqbeu7eqUvLXQ) Those stuffs: - List coprehensive - a = [a for a in range(10) if a % 2 == 0] - a = [a x a for a in range(10)] - Iterable and Generator # use to save memory, a generator is like a prepared factory but haven't produce anything - def generate_range(n): i = 0 while i < n: yield i i += 1 - automated testing via assert - randomness # if you all ready set up a random seed the result will be the same but still in randomness import random random seed(10) (set up a random seed) four_uniform_randoms = [random.random() for _ in range(4)] random.randrange(a) # choose randomly in range (0 -> a - 1) random.randrange(a, b) # choose randomly in range (a -> b-1) random.shuffle random.choice lottery_numbers = range(49) winning_numbers = random.sample(lottery_numbers, 6) # [16, 36, 10, 6, 25, 9] - zip and unpacking - pointer in Python - Python decorators Some use cases: Time functions Debugging Is the user logged in? - Recursive Greatest common division def GCD(a, b): if b == 0: return a else: return GCD(b%a, a) Fibo numbers def Fibo(n): if n == 1 or n ==2: return 1 else: return Fibo(n-1, n-2) Factorial n! def fac(n): if n == 1: return 1 else: return fac(n-1) Tower of Hanoi def Tower(n, a, b, c): if n == 1: return "a to c" else: return "n-1 to b, n to c, n -1 to c" - Regular expression ( to find parttern in text) import re Character classes . any character except newline \w \d \s word, digit, whitespace \W \D \S not word, digit, whitespace [abc] any of a, b, or c [^abc] not a, b, or c [a-g] character between a & g Anchors ^abc$ start / end of the string \b word boundary Character Description Example ? Match zero or one repetitions of preceding "ab?" matches "a" or "ab" * Match zero or more repetitions of preceding "ab*" matches "a", "ab", "abb", "abbb"... + Match one or more repetitions of preceding "ab+" matches "ab", "abb", "abbb"... but not "a" {n} Match n repetitions of preceding "ab{2}" matches "abb" {m,n} Match between m and n repetitions of preceding "ab{2,3}" matches "abb" or "abbb" Quantifiers & Alternation a* a+ a? 0 or more, 1 or more, 0 or 1 a{5} a{2,} exactly five, two or more a{1,3} between one & three a+? a{2,}? match as few as possible ab cd Escaped characters . * \ \ is used to escape special chars. * matches * \t \n \r tab, linefeed, carriage return # Day 2 week 2 ## Challenging day We've been introduced many important hard concepts to swallow Big O notation (use to calculate time a function run wen n go to infinity) 0(1) 0(n) 0(logn) 0(nlogn) 0(n**c) 0(c**n) Recursion ( use to give elegant solutions ) Factorial def fac(n): while n>0: if n = 1: return 1 elif n = 2: return a to b a to c b to c else: return fac(n-1)*n Tower of Hanoi def tower(n, a, b, c): while n>0: if n == 1: return a to c elif n = 2: return a to b, a to c, b to c else: return tower(n-1) Greatest common division Fibonacci number Sorting algorithm (reduce big 0 when use sort method) Quick sort Merge sort Object oriented programming instance attribute instance method class notebook: def __init__(self, cover, pages): self.cover = cover self.pages = pages def write(self, color): (instance method) return white def look(beautiful): return "this is a wonderful notebook" # Day 3 week 2: (another interesting day) ## NUMPY(alternative Tenserflow) (want some speed: try np.blablabla) Python built in top of C (C access directly to memory) Numpy c extension Create just one data type in a list in NUMPY Same size memory for faster searching (numpy) Different size memory for flexibility (search Python without numpy) code in numpy x = np.array([[[]]]) (x is an array) an array which is a list and that list is numbers aranged in dimesions represent a scalar , vector, matrix, 3D tensor (like a picture) ## Basic x.ndim (n dimention of x) x.shape 1,1,1 is dimesion 1 have 1 element, demension 2 have 1 element, demension 3 have 1 element x.size is all element the array have x.dtype int64, float64, bool # Indexing x = np.array([1, 2, 3]) # ndim 2, shape 1x3, size 3, dtype int64 print ("x: ", x) print ("x[0]: ", x[0]) # print out: x[0]: 1 x[0] = 0 print ("x: ", x) # print out: [0 2 3] # Slicing x = np.array([[1,2,3,4], [5,6,7,8], [9,10,11,12]]) print (x) [[1 2 3 4] [5 6 7 8] [9 10 11 12]] print ("x column 1: ", x[:, 1]) # "x column 1": 2 6 10 print ("x row 0: ", x[0, :]) # x row 0: 1 2 3 4 print ("x rows 0,1 & cols 1,2: \n", x[0:2, 1:3]) # [[2 3] [5 7]] # Integer array indexing print (x) rows_to_get = np.array([0, 1, 2]) # take rows 0 1 2 == first second third print ("rows_to_get: ", rows_to_get) cols_to_get = np.array([0, 2, 1]) # take columns 0 2 1 == first third second print ("cols_to_get: ", cols_to_get) # Combine sequences above to get values to get print ("indexed values: ", x[rows_to_get, cols_to_get]) # combine row and column produce six pairs which is the indexs of x we need to print out which is (0, 0), (1, 2), (2, 1) it should print: indexed values: [1 7 10] # Boolean array indexing x = np.array([[1, 2], [3, 4], [5, 6]]) print ("x:\n", x) # should print out: [[1 2] [3 4] [5 6]] print ("x > 2:\n", x > 2) # should print out: [[False False] [True True] [True True]] print ("x[x > 2]:\n", x[x > 2]) [3 4] [5 6] print(sum(x > 2)) [2 2] np.sum(x > 2) 4 ##Arithmetic # Basic math x = np.array([[1,2], [3,4]], dtype=np.float64) y = np.array([[1,2], [3,4]], dtype=np.float64) print ("x + y:\n", np.add(x, y)) # or x + y [[2 4] [6 8]] print ("x - y:\n", np.subtract(x, y)) # or x - y [0 0] [0 0] print ("x * y:\n", np.multiply(x, y)) # or x * y [[1 4] [9 16] # Dot product (USE in matrixs multiplication: reproduce every dots and built a new matrix: m*n * n*p = m * p) a = np.array([[1,2,3], [4,5,6]], dtype=np.float64) # we can specify dtype b = np.array([[7,8], [9,10], [11, 12]], dtype=np.float64) c = a.dot(b) # c = np.dot(a, b) print (f"{a.shape} ยท {b.shape} = {c.shape}") [2 2] print (c)) # Axis operations # Sum across a dimension x = np.array([[1,2],[3,4]]) print (x) print ("sum all: ", np.sum(x)) # adds all elements print ("sum axis=0: ", np.sum(x, axis=0)) # sum column + column (across rows) print ("sum axis=1: ", np.sum(x, axis=1)) # sum row + row (across columns) # Min/max x = np.array([[1,2,3], [4,5,6]]) print ("min: ", x.min()) # 1 print ("max: ", x.max()) # 6 print ("min axis=0: ", x.min(axis=0)) 1 2 3 print ("min axis=1: ", x.min(axis=1)) 1 4 Broadcasting Broadcasting in NumPy follows a strict set of rules to determine the interaction between the two arrays: Rule 1: If the two arrays differ in their number of dimensions, the shape of the one with fewer dimensions is padded with ones on its leading (left) side. Rule 2: If the shape of the two arrays does not match in any dimension, the array with shape equal to 1 in that dimension is stretched to match the other shape. Rule 3: If in any dimension the sizes disagree and neither is equal to 1, an error is raised. # Broadcasting x = np.array([1,2]) # vector y = np.array(3) # scalar z = x + y print ("z:\n", z) ## Advance Matrix # Transposing x = np.array([[1,2,3], [4,5,6]]) print ("x:\n", x) print ("x.shape: ", x.shape) y = np.transpose(x, (1,0)) # flip dimensions at index 0 and 1 print ("y:\n", y) print ("y.shape: ", y.shape) # Reshaping x = np.array([[1,2,3,4,5,6]]) print (x) print ("x.shape: ", x.shape) y = np.reshape(x, (2, 3)) print ("y: \n", y) print ("y.shape: ", y.shape) z = np.reshape(x, (2, -1)) print ("z: \n", z) print ("z.shape: ", z.shape) # Adding dimensions x = np.array([[1,2,3],[4,5,6]]) print ("x:\n", x) print ("x.shape: ", x.shape) y = np.expand_dims(x, 1) # expand dim 1 print ("y: \n", y) print ("y.shape: ", y.shape) # notice extra set of brackets are added # Removing dimensions x = np.array([[[1,2,3]],[[4,5,6]]]) print ("x:\n", x) print ("x.shape: ", x.shape) y = np.squeeze(x, 1) # squeeze dim 1 print ("y: \n", y) print ("y.shape: ", y.shape) # notice extra set of brackets are gone # Day 4 week 2: Data base story ## Data base - Table - Column - Row - Schema - Primary key, foreign key The relationship between two tables should be one to many or many to one AVOID many to many ## SQL syntax SELECT DISTINCT column, AGG_FUNC(column)... FROM mytable INNER/LEFT/RIGHT/FULL JOIN another_table ON mytable.column = another_table.column GROUP BY column HAVING constraint_expression ORDER BY column ASC / DESC LIMIT count OFFSET count # Day 5 week 2: Tough day Today teacher fixed some problems in 116 Python problems https://repl.it/~ And we spend more than three ours to do a test Which helped me understand decoration in Python better: def deco(function): def wrapper(*args, **kargs): print("something, before") print("something, after before but still before function execute") function(*args, **kargs) print("after function executed") return wrapper we use: @deco function(*args, **kargs) When we call function() And the result should be: something, before something, after before but still before function execute (function do sth) after function executed However, after being decorated, function() has gotten very confused about its identity. It now reports being the wrapper() inner function We use this: @functools.wraps(func) we put it here: def deco(function): ->>>> @functools.wraps(func) def wrapper(*args, **kargs): print("something, before") print("something, after before but still before function execute") function(*args, **kargs) print("after function executed") return wrapper