import numpy as np
from scipy import spatial

"""
Explanation: 必備的module
End of explanation
"""


def sim1(n):
    v1 = np.random.randint(0, 100, n)
    v2 = np.random.randint(0, 100, n)
    return 1 - spatial.distance.cosine(v1, v2)

def sim2(n):
    v1 = np.random.randint(0, 100, n)
    v2 = np.random.randint(0, 100, n)
    return np.dot(v1, v2) / np.linalg.norm(v1) / np.linalg.norm(v2)

import math
def sim3(n):
    v1 = np.random.randint(0, 100, n)
    v2 = np.random.randint(0, 100, n)
    return sum(v1 * v2) / math.sqrt(sum(v1 ** 2)) / math.sqrt(sum(v2 ** 2))

from itertools import izip
def dot_product(v1, v2):
    return sum(map(lambda x: x[0] * x[1], izip(v1, v2)))

def sim4(n):
    v1 = np.random.randint(0, 100, n)
    v2 = np.random.randint(0, 100, n)
    prod = dot_product(v1, v2)
    len1 = math.sqrt(dot_product(v1, v1))
    len2 = math.sqrt(dot_product(v2, v2))
    return prod / (len1 * len2)

%timeit sim1(400)

%timeit sim2(400)

%timeit sim3(400)

%timeit sim4(400)

"""
Explanation: 在python中計算cosine similarity最快的方法是什麼?

方法1: 利用spatial.distance.cosin
方法2: 利用np.dot，但要自己除以向量長度
方法3: 土法鍊鋼
方法4: HM的方法
End of explanation
"""


from datetime import datetime as dt

start = dt.now()
start.date(), start.time(), start

dt.now() - start

"""
Explanation: 結論
HM的方法最慢，用np.dot及np.linalg.norm組合的最快
日期時間的格式
End of explanation
"""


import logging
fmtstr = '%(asctime)s [%(levelname)s][%(name)s] %(message)s'
datefmtstr = '%Y/%m/%d %H:%M:%S'
if len(logging.getLogger().handlers) >= 1:
    logging.getLogger().handlers[0].setFormatter(logging.Formatter(fmtstr, datefmtstr))
else:
    logging.basicConfig(format=fmtstr, datefmt=datefmtstr)

# 如果直接呼叫 logging.warning，就是使用root logger
logging.warning("please set %d in %s", 100, "length")

"""
Explanation: logging: 整合所有的module log
logging module的用途是讓所有module有一致的介面可以留下執行記錄。基本的logging system有兩個角色
* Logger: 多個logger組成一個樹狀結構，會傳給root logger匯整
* Handler: 接收root logger的資訊，並輸出到檔案
在預設情況下，會使用StreamHandler，將log輸出到標準輸出。如果在basicConfig中指定filename參數，則會建立FileHandler輸出到檔案。
End of explanation
"""


# 在root logger下面增加child logger
aaa_logger = logging.getLogger('aaa')
bbb_logger = aaa_logger.getChild('bbb')
ccc_logger = bbb_logger.getChild('ccc')

aaa_logger.warn("hello")

bbb_logger.warn("hello")

# 當logger是樹狀結構時，logger的名稱會變成 aaa.bbb.ccc
ccc_logger.warn("hello")

"""
Explanation: 如果從某個module呼叫時，就用
End of explanation
"""


