"""
提升树：基于二叉回归树的提升算法
程序暂考虑输入为一维的情况
"""
from collections import defaultdict
import numpy as np
import matplotlib.pyplot as plt

class BoostingTree:
    def __init__(self, epsilon=1e-2):
        self.epsilon = epsilon  # 设置阀值
        self.cand_splits = []  # 候选切分点
        self.split_index = defaultdict(tuple)  # 由于要多次切分数据集，故预先存储，切分后数据点的索引
        self.split_list = []  # 最终各个基本回归树的切分点
        self.c1_list = []  # 切分点左区域取值
        self.c2_list = []  # 切分点右区域取值
        self.N = None  # 储存样本点个数
        self.n_split = None  # 记录所有切分点的个数

    def init_param(self, X_data):
        # 初始化参数
        self.N = X_data.shape[0]  # 过去样本点个数
        for i in range(1, self.N):
            self.cand_splits.append((X_data[i][0] + X_data[i - 1][0]) / 2)  # 计算所有可能的切分点
        self.n_split = len(self.cand_splits)
        for split in self.cand_splits:  # 遍历所有切分点
            left_index = np.where(X_data[:, 0] <= split)[0]  # 记录每个切分点的左边index
            right_index = list(set(range(self.N))-set(left_index))  # 记录切分点的右边index
            self.split_index[split] = (left_index, right_index)  # 记录切分点的左右的切分情况
        return

    def _cal_err(self, split, y_res):
        # 计算每个切分点的误差
        inds = self.split_index[split]  # 获取切分点下标
        left = y_res[inds[0]]  # 获取切分点左边的数据集合
        right = y_res[inds[1]]  # 获取切分点右边的数据集合

        c1 = np.sum(left) / len(left)  # 左侧平均值
        c2 = np.sum(right) / len(right)  # 右侧平均值
        y_res_left = left - c1  # 左侧的残差列表
        #print('y_res_left=%s'%y_res_left)
        y_res_right = right - c2  # 右侧的残差列表
        res = np.hstack([y_res_left, y_res_right])  # 获得一个完整的残差列表
        res_square = np.apply_along_axis(lambda x: x ** 2, 0, res).sum()  # 计算残差的平方和,既损失函数
        return res_square, c1, c2

    def best_split(self, y_res):
        # 获取最佳切分点，并返回对应的残差
        best_split = self.cand_splits[0]  # 初始化最佳切分点
        #print('best_split=%s'%best_split)
        min_res_square, best_c1, best_c2 = self._cal_err(best_split, y_res)  # 初始化损失函数值, 左侧与右侧数据集的平均值

        for i in range(1, self.n_split):  # 遍历所有切分点, 获取最佳切分点, 并且计算相关的值
            res_square, c1, c2 = self._cal_err(self.cand_splits[i], y_res)
            if res_square < min_res_square:
                best_split = self.cand_splits[i]
                min_res_square = res_square
                best_c1 = c1
                best_c2 = c2

        self.split_list.append(best_split)  # 记录最佳切分点
        self.c1_list.append(best_c1)  # 记录左侧数据集的平均值
        self.c2_list.append(best_c2)  # 记录右侧数据集的平均值
        return

    def _fx(self, X):
        # 基于当前组合树，预测X的输出值
        s = 0
        # 遍历每一棵子树, 累加, 计算出组合树对x的预测值
        for split, c1, c2 in zip(self.split_list, self.c1_list, self.c2_list):
            if X < split:
                s += c1
            else:
                s += c2
        return s

    def update_y(self, X_data, y_data):
        # 每添加一颗回归树，就要更新y,即基于当前组合回归树的预测残差
        y_res = []  # 初始化化残差表
        for X, y in zip(X_data, y_data):  # 将X_data, y_data打包成一个（x,y）元素对
            y_res.append(y - self._fx(X[0]))  # 计算每一个元素对应的残差值
        y_res = np.array(y_res)
        res_square = np.apply_along_axis(lambda x: x ** 2, 0, y_res).sum()  # 计算出残差的平方, 既是损失函数
        return y_res, res_square

    def fit(self, X_data, y_data):
        self.init_param(X_data)  # 初始化参数, 村里参数
        y_res = y_data
        while True:
            self.best_split(y_res)
            y_res, res_square = self.update_y(X_data, y_data)
            if res_square < self.epsilon:  # 当损失函数的值小于阀值, 退出循环
                break
        return

    def predict(self, X):
        return self._fx(X)

if __name__ == '__main__':
    # data = np.array(
    #     [[1, 5.56], [2, 5.70], [3, 5.91], [4, 6.40], [5, 6.80], [6, 7.05], [7, 8.90], [8, 8.70], [9, 9.00], [10, 9.05]])
    # X_data = data[:, :-1]
    # y_data = data[:, -1]
    # BT = BoostingTree(epsilon=0.18)
    # BT.fit(X_data, y_data)
    # print(BT.split_list, BT.c1_list, BT.c2_list)
    X_data_raw = np.linspace(-5, 5, 100)  # 生成x
    #print('X_data_raw=%s'%X_data_raw)
    X_data = np.transpose([X_data_raw])  # 转秩, 生成列矩阵
    #print('X_data=%s'%X_data)
    y_data = np.sin(X_data_raw)  # 对应与每一个x,生y
    BT = BoostingTree(epsilon=0.1)
    BT.fit(X_data, y_data)

    y_pred = [BT.predict(X) for X in X_data]  # 计算出预测值

    # 计算两个矩阵的相关度, 既计算预测与实际数据之间差距
    score = np.corrcoef(y_pred, y_data, rowvar=0)[0, 1]
    print("\n\nThe accruacy socre is ", score)
    print('The error score is ', 1 - score)

    p1 = plt.scatter(X_data_raw, y_data, color='r')
    p2 = plt.scatter(X_data_raw, y_pred, color='b')
    plt.legend([p1, p2], ['real', 'pred'])
    plt.show()


from flask import Flask, jsonify, request
from flask_restful import Api, Resource
import numpy as np
import traceback
import json
from model.model import Net
import torch
import cv2

app = Flask(__name__)
api = Api(app)

model = Net()
model.load_state_dict(torch.load('mnist_cnn.pt'))
model.eval()

# convert request_input dict to input accepted by model.
def parse_input(request_input):
    """parse input to make it ready for model input.

    Arguments:
        request_input::file- input received from API call.

    Returns:
        model_ready_input::torch.Tensor- data ready to be fed into model.
    """
    img = request_input.read()
    img = np.frombuffer(img, np.uint8)
    img = cv2.imdecode(img,cv2.IMREAD_COLOR)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    img = cv2.resize(img,(28,28))
    img = img.reshape((1,1,28,28))
    return torch.Tensor(img)

# convert model prediction to dict to return as JSON
def parse_prediction(prediction):
    """parse prediction to prepare a request response.

    Arguments:
        prediction::torch.Tensor- output of model inference

    Returns:
        response::dict- dictionary to return as a JSON response.
    """
    prediction = prediction.argmax(dim=1, keepdim=True)
    return {'class':int(prediction[0][0])}

# class inheriting from Resource prepares it to become an API endpoint
class MakePrediction(Resource):
    @staticmethod
    def post():
        if model:
            try:
                request_input = request.files['file']

                model_input = parse_input(request_input)

                prediction = model(model_input)

                model_output = parse_prediction(prediction)

                return jsonify(model_output)

            except:
                return jsonify({'trace': traceback.format_exc()})
        else:
            return jsonify({'trace': 'No model found'})

api.add_resource(MakePrediction, '/predict') # add endpoint to API

class dummy_post(Resource):
    @staticmethod
    def post():
        if model:
            try:
                request_input = request.get_json()

                return jsonify(request_input)

            except:
                return jsonify({'trace': traceback.format_exc()})
        else:
            return jsonify({'trace': 'No model found'})

api.add_resource(dummy_post, '/dummy_post')

class dummy_get(Resource):
    @staticmethod
    def get():
        if model:
            try:
                return str("dummy get request")

            except:
                return jsonify({'trace': traceback.format_exc()})
        else:
            return jsonify({'trace': 'No model found'})

api.add_resource(dummy_get, '/dummy_get')

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0',port=8080)


# -*- coding: utf-8 -*-
"""
Created on Sun Feb 16 09:44:54 2020

@author: Sathvik

Version 1.0.5
"""

import math

# definig the liquids in shell and tube
benzWeight = 20000
benzUnit = 'kg/hr'
waterWeight = '?'
waterUnit = 'kg/hr'

# temperature of the cold and hot fluid
waterInitialTemp = 80
waterFinalTemp = 60
benzInitialTemp = 25
benzFinalTemp = 65
TempUnit = 'C'

# Molecular Weight
waterMolecularWt = 18
benzMolecularWt = 78

def step1():
    # finding the water and benzene mean Temp using (T1+T2)/2
    global waterTempAvg, benzTempAvg, waterTempAvgK, benzTempAvgK
    waterTempAvg = (waterInitialTemp + waterFinalTemp)/2
    benzTempAvg = (benzInitialTemp + benzFinalTemp)/2
    print('T(Wavg) :', waterTempAvg, 'C')
    print('T(Bavg) :', benzTempAvg, 'C')
    # Converting C to K
    waterTempAvgK = waterTempAvg + 273
    benzTempAvgK = benzTempAvg + 273
    print('T(Wavg) :', waterTempAvgK, 'K')
    print('T(Bavg) :', benzTempAvgK, 'K')

def step2():
    # Density of Water and Benzene
    global waterTempAvgDensitySI, benzTempAvgDenistySI
    taue = 1 - (waterTempAvgK/647.096)
    print(taue)
    waterTempAvgDensity1 = 17.86
    waterTempAvgDensity2 = (58.60*(pow(taue, 0.35)))
    waterTempAvgDensity3 = -(95.36*(taue**(2/3)))
    waterTempAvgDensity4 = (213.89*taue)
    waterTempAvgDensity5 = -(141.26*(taue**(4/3)))
    print(waterTempAvgDensity1, waterTempAvgDensity2, waterTempAvgDensity3, waterTempAvgDensity4, waterTempAvgDensity5)
    waterTempAvgDensity = waterTempAvgDensity1 + waterTempAvgDensity2 + waterTempAvgDensity3 + waterTempAvgDensity4 + waterTempAvgDensity5
    print(waterTempAvgDensity)
    waterTempAvgDensitySI = waterTempAvgDensity * ((18*10**-3)/10**-3)
    print('Density of Water:', waterTempAvgDensitySI, 'kg/m3')
    c1 = 1.0259
    c2 = 0.266
    c3 = 562.05
    c4 = 0.2839
    benzTempAvgDensity = (c1/(c2**(1+(1-(benzTempAvgK/c3))**c4)))
    print(benzTempAvgDensity)
    benzTempAvgDensitySI = 851.56 # benzTempAvgDensity*(78*10**-3/10**-3)
    print('Density of Benzene :', benzTempAvgDensitySI, 'kg/m3')

def step3():
    # Heat Capacity of Water and Benzene
    global heatCapacityWaterJperkK, heatCapacityBenzJperkK
    # c1 [0] = water, c2 [1] = benzene
    C1 = [276370, 129440]
    C2 = [-2090.1, -169.5]
    C3 = [8.125, 0.647]
    C4 = [-0.0141, 0]
    C5 = [9.370*10**-6, 0]
    for i in range(0, 1):
        heatCapacityWater = C1[i] + (C2[i]*waterTempAvgK) + (C3[i]*(waterTempAvgK**2)) + (C4[i]*(waterTempAvgK**3)) + (C5[i]*(waterTempAvgK**4))
        heatCapacityWaterJperkK = heatCapacityWater/waterMolecularWt
        print('Specific Heat Capacity of Water :', heatCapacityWaterJperkK, 'J/kK')
    for i in range(1, 2):
        heatCapacityBenz = C1[i] + (C2[i]*benzTempAvgK) + (C3[i]*(benzTempAvgK**2)) + (C4[i]*(benzTempAvgK**3)) + (C5[i]*(benzTempAvgK**4))
        heatCapacityBenzJperkK = heatCapacityBenz/benzMolecularWt
        print('Specific Heat Capacity of Benzene :', heatCapacityBenzJperkK, 'J/kK')

def step4():
    # Thermal Conductivity and Viscocity of Water and Benzene
    global thermalConductivityWater, thermalCondutivityBenz
    # C1 [0] = water, C2 [1] = benzene
    C1 = [-0.432, 0.23444]
    C2 = [0.0057255, -0.00030572]
    C3 = [-0.000008078, 0]
    C4 = [1.861*10**-9, 0]
    C5 = [0, 0]
    for i in range(0, 1):
        thermalConductivityWater = C1[i] + (C2[i]*waterTempAvgK) + (C3[i]*(waterTempAvgK**2)) + (C4[i]*(waterTempAvgK**3)) + (C5[i]*(waterTempAvgK**4))
        print('Thermal Conductivity of Water :', thermalConductivityWater, 'W/mK')
    for i in range(1, 2):
        thermalConductivityBenz = C1[i] + (C2[i]*benzTempAvgK) + (C3[i]*(benzTempAvgK**2)) + (C4[i]*(benzTempAvgK**3)) + (C5[i]*(benzTempAvgK**4))
        print('Thrmal Conductivity of Benzene', thermalConductivityBenz, 'W/mK')
    # find the viscocity

def step5():
    # Heat Balance and FlowRate
    global benzWeightSI, waterWeightSI, waterUnitSI, totalMassFlowRate
    # water - hot liquid, benzene - cold liquid
    if benzUnit == 'kg/hr':
        benzWeightSI = benzWeight/3600
    print('MassFlow Rate of Benzene :', benzWeightSI, 'kg/s')
    waterUnitSI = 'kg/s'
    waterWeightSI = ((benzWeightSI*heatCapacityBenzJperkK*(benzFinalTemp-benzInitialTemp))/(heatCapacityWaterJperkK*(waterInitialTemp-waterFinalTemp)))
    print('MassFlow Rate of Water :', waterWeightSI, waterUnitSI)
    totalMassFlowRateBenz = benzWeightSI*heatCapacityBenzJperkK*(benzFinalTemp-benzInitialTemp)
    # totalMassFlowRateWater = waterWeightSI*heatCapacityWaterJperkK*(waterInitialTemp-waterFinalTemp)
    totalMassFlowRate = totalMassFlowRateBenz # totalMassFlowRateBenz == totalMassFlowRateWater == 401613.1851
    print('Total MassFlow Rate Q : ', totalMassFlowRate, 'J/s')

def step6():
    # LMTD Calculation
    global deltaLMTDCorrectedFt
    deltaT1 = waterInitialTemp-benzFinalTemp
    deltaT2 = waterFinalTemp-benzInitialTemp
    LMTD = (deltaT2-deltaT1)/math.log(deltaT2/deltaT1)
    print(LMTD)
    R = (waterInitialTemp-waterFinalTemp)/(benzFinalTemp-benzInitialTemp)
    S = (benzFinalTemp-benzInitialTemp)/(waterInitialTemp-benzInitialTemp)
    LMTDCorrectionFt = 0.95 # calcultated from the graph
    deltaLMTDCorrectedFt = LMTDCorrectionFt*LMTD
    print(R, S, deltaLMTDCorrectedFt)

def step7():
    # Ud and Atra of the Tube
    # Water - Tube, Benzene - Shell
    global Ud, UdUnit, UdAssumed
    global Rd, RdUnit, At
    Ud = 100 # between 50-150
    UdUnit = 'Btu/Fft2h'
    Rd = 0.003
    RdUnit = 'Fft2h/Btu'
    Rd /= 5.6783
    Ud *= 5.6783
    UdAssumed = Ud
    print('Ud : ', Ud, UdUnit)
    # Overall HeatTransfter Area
    At = totalMassFlowRate/(UdAssumed*deltaLMTDCorrectedFt)
    print('Area of the HeatTransfer : ', At, ' m2')

def step8():
    # Tube Dia, Length, Number
    global tubedo, tubedi, tubeUnit, BWGGauge
    global Pt, lengthTube, lengthTubeUnit, numberTubes
    global numberShell, numberPasses
    tubeOD = 1
    tubeID = 0.870
    tubeRawUnit = 'in'
    BWGGauge = 16
    if tubeRawUnit == 'in':
        tubedo = tubeOD*0.0254
        tubedi = tubeID*0.0254
        tubeUnit = 'm'
        print('Outer Dia of Tube : ', tubedo, tubeUnit)
        print('Inner Dia of Tube : ', tubedi, tubeUnit)
    else:
        tubedo = tubeOD
        tubedi = tubeID
        tubeUnit = tubeRawUnit
    print(tubedo)
    # Assume Triangluar Pitch
    Pt = 1.25*tubedo
    PtUnit = 'm'
    print('Pitch : ', Pt, PtUnit)
    # Standard Lenght = 6, 8, 12, 16, 20, 24 ft
    lengthTubeRaw = 20
    lengthTubeRawUnit = 'ft'
    if lengthTubeRawUnit == 'ft':
        lengthTube = lengthTubeRaw*0.3048
        lengthTubeUnit = 'm'
    else:
        lengthTube = lengthTubeRaw
        lengthTubeUnit = lengthTubeRawUnit
    print('Length of the Tube : ', lengthTube, lengthTubeUnit)
    numberTubes = At/(math.pi*tubedo*lengthTube)
    numberTubes = int(round(numberTubes))
    for i in range(numberTubes, numberTubes+9):
        if numberTubes % 3 != 0:
            numberTubes += 1
    print('Number of Tubes : ', numberTubes)
    # [2 - 4 SHTE], 2 - Shell, 4 - Passes
    numberShell = 2
    numberPasses = 4
    print('Number of Shell : ', numberShell)
    print('Number of Passes : ', numberPasses)

def step9():
    # Area of the Tube
    At = (math.pi/4)*(tubedi**2)*(numberTubes/numberPasses)
    print('Area of the Tube : ', At, 'm')
    # Mass Velocity
    Gt = waterWeightSI/At
    print('Mass FlowRate : ', Gt, 'kg/m2s')
    # Raynolds Number
    # Nre = (tubeid*Gt)/ # Find The Viscocity

step1()
step2()
step3()
step4()
step5()
step6()
step7()
step8()
step9()


import os
from copy import copy
from my_turtle import trace

"""
After updating the database, please run this script.
"""

def find_solutions(trace_ans, state, index):
    solutions = []
    for x in range(1, 6):
        state[index] = x
        if index < 4:
            solutions += find_solutions(trace_ans, state, index + 1)
        else:
            try:
                trace_state = trace(state)
            except IndexError:
                pass
            else:
                if trace_ans == trace_state:
                    solutions.append(copy(state))
    return solutions

if(__name__ == "__main__"):
    traces, all_sols = [], []

    fname = os.path.join('data', 'patterns.dat')
    with open(fname, 'r') as f:
        for line in f:
            pattern = line.split()[0]
            pattern = [int(x) for x in pattern]
            try:
                pattern_trace = trace(pattern)
            except IndexError:
                pass
            else:
                traces.append(pattern_trace)

    with open('data/patterns.dat', 'w') as f:
        for value in traces:
            solutions = find_solutions(value, [1, 1, 1, 1, 1], 0)
            if solutions not in all_sols:
                all_sols.append(solutions)
                for pattern in solutions:
                    for element in pattern:
                        f.write(str(element))
                    if pattern != solutions[-1]:
                        f.write(" ")
            if value != traces[-1]:
                f.write('\n')


# coding=utf-8
import scrapy

from scrapy_splash import  SplashRequest
from scrapy.loader import ItemLoader
from wyy.items import WyyItem
import gzip
import zlib
import requests, json
from wyy.spiders import Decrypt
'''  js=string.format([[x=document.getElementsByClassName('nm nm-icn f-thide s-fc0');x[%d].click()]],args.same_az_id)
  splash:evaljs(js)'''
script = '''
function main(splash, args)
  splash.images_enabled= false
  local header=assert(splash:go{args.url,headers=args.headers})
  assert(splash:wait(args.wait))
  return header.headers

end
'''
class WyySpiderSpider(scrapy.Spider):
    name = 'wyy_spider'
    allowed_domains = ['music.163.com']
    country_id = {1, 2, 6, 7, 4}  # 分别代表 华语、欧美、日本、韩国、其他
    gender_id = {1, 2, 3}   # 分别代表男歌手、女歌手、组合
    cookies = {
        '_ntes_nnid': '7eced19b27ffae35dad3f8f2bf5885cd, 1476521011210',
        '_ntes_nuid': '7eced19b27ffae35dad3f8f2bf5885cd',
        'usertrack': 'c+5+hlgB7TgnsAmACnXtAg==',
        'Province': '025',
        'City': '025',
        'NTES_PASSPORT': '6n9ihXhbWKPi8yAqG.i2kETSCRa.ug06Txh8EMrrRsliVQXFV_orx5HffqhQjuGHkNQrLOIRLLotGohL9s10wcYSPiQfI2wiPacKlJ3nYAXgM',
        'P_INFO': 'hourui93@163.com|1476523293|1|study|11&12|jis&1476511733&mail163#jis&320100#10#0#0|151889&0|g37_client_check&mailsettings&mail163&study&blog|hourui93@163.com',
        'NTES_SESS': 'Fa2uk.YZsGoj59AgD6tRjTXGaJ8_1_4YvGfXUkS7C1NwtMe.tG1Vzr255TXM6yj2mKqTZzqFtoEKQrgewi9ZK60ylIqq5puaG6QIaNQ7EK5MTcRgHLOhqttDHfaI_vsBzB4bibfamzx1.fhlpqZh_FcnXUYQFw5F5KIBUmGJg7xdasvGf_EgfICWV',
        'S_INFO': '1476597594|1|0&80##|hourui93',
        'NETEASE_AUTH_SOURCE': 'space',
        'NETEASE_AUTH_USERNAME': 'hourui93',
        '_ga': 'GA1.2.1405085820.1476521280',
        'JSESSIONID-WYYY': 'cbd082d2ce2cffbcd5c085d8bf565a95aee3173ddbbb00bfa270950f93f1d8bb4cb55a56a4049fa8c828373f630c78f4a43d6c3d252c4c44f44b098a9434a7d8fc110670a6e1e9af992c78092936b1e19351435ecff76a181993780035547fa5241a5afb96e8c665182d0d5b911663281967d675ff2658015887a94b3ee1575fa1956a5a%3A1476607977016',
        '_iuqxldmzr_': '25',
        '__utma': '94650624.1038096298.1476521011.1476595468.1476606177.8',
        '__utmb': '94650624.20.10.1476606177',
        '__utmc': '94650624',
        '__utmz': '94650624.1476521011.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',

    }
    def start_requests(self):
        for country in self.country_id:
            for gender in self.gender_id:
                for i in range(65, 91):
                    url = 'https://music.163.com/discover/artist/cat?id={}00{}&initial={}'.format(
                            country, gender, i) #获取所有国家所有类型所有姓氏的url
                    yield scrapy.Request(url=url, headers=self.settings.get('HEADERS'), callback=self.parse,
                                        cookies=self.cookies,meta={'dont_merge_cookies':True,'url':url})

    # def parse(self, response):
    #     item = WyyItem()
    #     html = response.body.decode('utf-8')
    #     singers = response.xpath('''.//a[@class='nm nm-icn f-thide s-fc0']''')
    #     for same_az_id,singer in enumerate(singers):
    #         yield SplashRequest(response.meta['url'], callback=self.singer_parse, endpoint='execute', args={
    #             'lua_source': script, 'same_az_id': same_az_id, 'wait': 1,'headers':self.settings.get('HEADERS')
    #         })
    # def singer_parse(self, response):
    #     # 有的不需要解压 加个判断就好了
    #     html = response.body.decode('utf-8')
    #     try:
    #         decode_data = gzip.decompress(response.body.decode('utf-8')).decode('utf-8')
    #         #decode_data = zlib.decompress(response.body, 16 + zlib.MAX_WBITS)
    #         # print('用了gzip啊：{}'.format(decode_data))
    #     except:  # 请求失败的链接返回的是json 不能用gzip
    #         decode_data = response.body.decode()
    #     music_list = decode_data.xpath('''.//table[@class='m-table m-table-1 m-table-4']/tbody//tr''')
    #     for music in music_list:
    #         music_name = music.xpath('./td[2]//a/b/@title').extract_first('没拿到歌名?')
    #         music_url = music.xpath('./td[2]//a/@href').extract_first('没拿到song的herf?')
    #         music_id = music_url.replace('/song?id=', '').strip()
    #         real_music_url = 'https://music.163.com/song?id={}&limit=200'.format(music_id)

    def parse(self, response):
        item = WyyItem()
        html = response.body.decode('utf-8')
        singers = response.xpath('''.//a[@class='nm nm-icn f-thide s-fc0']''')
        for i,singer in enumerate(singers):
            #if i == 0:   #调试只拿一个歌手
                singer_name = singer.xpath('./text()').extract_first('没拿到name')
                singer_url = singer.xpath('./@href').extract_first('没拿到singer的herf?')
                singer_id = singer_url .replace('/artist?id=', '').strip()  # 获取歌手ID
                real_singer_url = 'https://music.163.com/artist?id={}'.format(singer_id)

                item['singer_name'] = singer_name
                item['singer_id'] = singer_id

                yield scrapy.Request(url=real_singer_url, callback=self.singer_parse,
                                     headers=self.settings.get('HEADERS'), cookies=self.cookies,
                                     meta={'dont_merge_cookies':True,'item':item})

    def singer_parse(self, response):
        item = response.meta['item']
        html = response.body.decode('utf-8')
        music_list = response.xpath('''.//ul[@class='f-hide']//li''')
        for i, music in enumerate(music_list):
            #if i==0:   #调试只取一首歌
                music_name = music.xpath('./a/text()').extract_first('没拿到歌名?')
                music_url = music.xpath('./a/@href').extract_first('没拿到song的herf?')
                music_id = music_url.replace('/song?id=', '').strip()
                real_music_url = 'https://music.163.com/song?id={}'.format(music_id)
                music_comment_url = "https://music.163.com/weapi/comment/resource/comments/get?csrf_token="
                item['music_name'] = music_name
                item['music_id'] = music_id
                item['music_url'] = real_music_url
                first_param = Decrypt.get_comment_first_param(music_id, 1)
                getkey = Decrypt.GetMusicKeyParameter(first_param, Decrypt.second_param,
                                                      Decrypt.third_param, Decrypt.forth_param, Decrypt.iv)
                params = getkey.get_params()
                encSecKey = getkey.get_encSecKey()
                data = {
                    "params": params,
                    "encSecKey": encSecKey
                }
                headers = {
                    'Host': 'music.163.com',
                    'Connection': 'keep-alive',
                    #'Content-Length': '484',
                    'Cache-Control': 'max-age=0',
                    'Origin': 'http://music.163.com',
                    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.84 Safari/537.36',
                    'Content-Type': 'application/x-www-form-urlencoded',
                    'Accept': '*/*',
                    'DNT': '1',
                    'Accept-Encoding': 'gzip, deflate',
                    'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4',
                    'Cookie': 'JSESSIONID-WYYY=b66d89ed74ae9e94ead89b16e475556e763dd34f95e6ca357d06830a210abc7b685e82318b9d1d5b52ac4f4b9a55024c7a34024fddaee852404ed410933db994dcc0e398f61e670bfeea81105cbe098294e39ac566e1d5aa7232df741870ba1fe96e5cede8372ca587275d35c1a5d1b23a11e274a4c249afba03e20fa2dafb7a16eebdf6%3A1476373826753; _iuqxldmzr_=25; _ntes_nnid=7fa73e96706f26f3ada99abba6c4a6b2,1476372027128; _ntes_nuid=7fa73e96706f26f3ada99abba6c4a6b2; __utma=94650624.748605760.1476372027.1476372027.1476372027.1; __utmb=94650624.4.10.1476372027; __utmc=94650624; __utmz=94650624.1476372027.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)',
                }
                # json_text = Decrypt.get_json(music_comment_url, params, encSecKey)
                # json_dict = json.loads(json_text)
                # print(json_dict['data']['totalCount'])

                # 在headers 中加入Content-Length 会400 Bad Request
                yield scrapy.FormRequest(url=music_comment_url, callback=self.song_parse, headers=headers,
                                         formdata=data,meta={'dont_merge_cookies':True,'item':item})
                # yield scrapy.Request(url=music_comment_url, callback=self.song_parse,method='POST',
                #                      headers=headers, cookies=self.cookies,
                #                      meta={'dont_merge_cookies':True,'item':item},body=json.dumps(body_data))

    def song_parse(self, response):
        item = response.meta['item']
        json_text = response.body
        json_dict = json.loads(json_text)
        music_comment_num = json_dict['data']['totalCount']
        item['music_comment_num'] = music_comment_num
        yield item


from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import tensorflow as tf
import numpy as np
from tensorflow.python.framework import constant_op
from tensorflow.python.platform import test

def embeddingPad(w, input, padding=False, sum=False, name=None):
    if not padding:
        y = tf.gather(w, input, name=name)
    else:
        mask = tf.cast(tf.cast(input, tf.bool), w.dtype) # 由于tf里会将0当成false,其余非0当作true
        y_gather = tf.gather(w, input)
        mask_expand = tf.expand_dims(mask, -1)
        y = tf.multiply(y_gather, mask_expand, name=name) #这个是向量逐元素相乘,y_gather:[3,3,3] mask:(3,3) mask_expand:(3,3,1), 相乘时会自动广播
        print("y_gather:",y_gather, "mask:",mask, "mask_expand:",mask_expand)
    return y

class EmbeddingTest(test.TestCase):

    def testEmbeddingPadOnly(self):
        super(EmbeddingTest,self).setUp()
        with self.test_session(use_gpu=False):
            embedding = constant_op.constant([
                [1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]
            ], dtype=tf.int32)
            ids=np.array([0, 2, 1, 0]) # 相当于将那些没有选出来的embedding全都padding成0，但要求ids也要pad，无值的地方都填0
            mask_pre=tf.cast(ids, tf.bool)
            mask = tf.cast(mask_pre, embedding.dtype)
            result_pre = tf.gather(embedding, ids)
            result = tf.multiply(result_pre, tf.expand_dims(mask, -1))
            print("mask_pre:",mask_pre.eval())
            print("mask:",mask,mask.eval())
            print("result_pre:",result_pre.eval())
            print("result:",result.eval())

            """
            mask_pre: [False  True  True False]
            mask: Tensor("Cast_1:0", shape=(4,), dtype=int32, device=/device:CPU:0) [0 1 1 0]
            result_pre:
            [[1 2 3]
             [7 8 9]
             [4 5 6]
             [1 2 3]]

            result:
            [[0 0 0]
             [7 8 9]
             [4 5 6]
             [0 0 0]]
            """

    def testEmbeddingPad(self):
        super(EmbeddingTest,self).setUp()
        with self.test_session(use_gpu=False):
            embedding = constant_op.constant([
                [1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]
            ], dtype=tf.int32)
            ids=np.array([0, 2, 1, 0])
            result_no_pad=embeddingPad(embedding,ids,padding=False).eval()
            print("no pad:",result_no_pad)

            result_pad=embeddingPad(embedding,ids,padding=True).eval()
            print("pad:",result_pad)

    def testEmbeddingDetail(self):
        super(EmbeddingTest,self).setUp()
        with self.test_session(use_gpu=False):
            embedding = constant_op.constant([
                [1, 2, 3],
                [4, 5, 6],
                [7, 8, 9],
                [10,11,12]
            ], dtype=tf.int32)
            """
            ids为 tf.tf.FixedLenSequenceFeature([], tf.int64, True),tf会将一个batch里的所有的样本个数补齐，
            比如原始样本为：[[2],
                            [1,2],
                            [3,2,1]]
            那么将会补齐成3*3的矩阵, dim: batch*K

            """
            input_ids=np.array([
                         [0,2,0], # 每行的元素看成是行下标
                         [1,2,0],
                         [3,2,1]
                        ])
            result = embeddingPad(embedding, input_ids, padding=False).eval()
            print("result no padding:", result)
            """
            由于输入ids是2d，所以result是3d,即总的维数是embedding的维数加上ids的维数
            输入样本维度：batch*k, k: max feature instance number in batch
            embedding_w维度：vocab*embedding
            输出维度：batch*k*embedding
            result: [[[ 1  2  3]
                      [ 7  8  9]
                      [ 1  2  3]]

                     [[ 4  5  6]
                      [ 7  8  9]
                      [ 1  2  3]]

                     [[10 11 12]
                      [ 7  8  9]
                      [ 4  5  6]]]
            """
            result = embeddingPad(embedding, input_ids, padding=True).eval()
            print("result with padding:", result)
            """
            由于输入ids是2d，所以result是3d,即总的维数是embedding的维数加上ids的维数
            result: [[[ 0  0  0]  # padding会将无效值置0
                      [ 7  8  9]
                      [ 0  0  0]]

                     [[ 4  5  6]
                      [ 7  8  9]
                      [ 0  0  0]]

                     [[10 11 12]
                      [ 7  8  9]
                      [ 4  5  6]]]
            """

    def testEmbedding(self):
        super(EmbeddingTest,self).setUp()
        with self.test_session(use_gpu=False):
            embedding = constant_op.constant([
                [1, 2, 3],
                [4, 5, 6],
                [7, 8, 9]
            ],dtype=tf.int32)
            ids=np.array([0, 2, 1, 0])
            result = tf.nn.embedding_lookup(embedding,ids).eval()
            expect_result= constant_op.constant([[ 1,  2,  3],
                                                 [ 7, 8,  9],
                                                 [ 4,  5,  6],
                                                 [ 1,  2, 3]]).eval()
            print("result: \n", result)
            self.assertAllEqual(result,expect_result) #2+1-1=2

            gather_ids = np.array([0, 2, 1, 0])
            result = tf.nn.embedding_lookup(embedding,gather_ids).eval()
            print("gather_result: \n", result) # 可以验证gather 与embedding lookup的功能是一样的
            self.assertAllEqual(result,expect_result)

            """
            下面的例子中：
            由于输入ids是2d，所以result是3d,即总的维数是embedding的维数加上ids的维数 -1
            ids的每个元素均代码embedding里的一行，即embedding[i,:],
            [
              [embedding[0,:],embedding[2,:]],
              [embedding[1,:],embedding[0,:]]
            ]

            """
            ids=np.array([[0, 2],
                          [1, 0]])
            print("ids in 2D array: ",ids)
            result = tf.nn.embedding_lookup(embedding, ids).eval()
            #result = tf.gather(embedding,ids).eval() 与embedding_lookup是一样的功能
            print("result in 2D: \n", result)
            expect_result= constant_op.constant([[[ 1,  2,  3], [ 7, 8,  9]],
                                                 [[ 4,  5,  6], [ 1,  2, 3]]]).eval()
            self.assertAllEqual(result,expect_result)

    def testCountZero(self):
        super(EmbeddingTest,self).setUp()
        with self.test_session(use_gpu=False):
            features = constant_op.constant([
                [0, 1, 3],
                [4, 0, 6],
                [7, 0, 0],
                [0, 0, 0]
            ], dtype=tf.int32)
            feat_sum = tf.reduce_sum(features, axis=1)
            nonzero = tf.maximum(tf.count_nonzero(features,axis=1,dtype=features.dtype),1)
            feat_mean = feat_sum/nonzero
            print("nonzero:", nonzero.eval())
            print("feat_sum:", feat_sum.eval())
            print("feat_mean:", feat_mean.eval())
            """
            nonzero: [2 2 1 1]
            feat_sum: [ 4 10  7  0]
            feat_mean: [ 2.  5.  7.  0.]
            """


alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']

def caesar(text, shift_number, direction):
    if direction == "decode":
        shift_number *= -1
    result = ""
    for letter in text:
        if letter in alphabet:
            position = alphabet.index(letter)
            new_postion = position + shift_number
            result += alphabet[new_postion]
        else:
            result += letter
    return result

from art import logo
print(logo)

status = 1
while status:

    direction = input("Type 'encode' to encrypt, type 'decode' to decrypt:\n")
    user_input = input("Type your message:\n")

    shift_number = int(input("Type the shift number:\n"))
    shift_number = shift_number % 26

    result = caesar(user_input, shift_number, direction)
    print(f"Here's the encoded result: {result}")

    restart = input("Type 'yes' if you want to go again. Otherwise type 'no'.")
    if restart == 'no':
        print('Goodbye.')
        status = 0


from typing import Union, Tuple, Optional, TYPE_CHECKING
import struct

import claripy

try:
    import _md5 as md5lib
except ImportError:
    import hashlib as md5lib

if TYPE_CHECKING:
    from .expression import Expression

def get_bits(expr: Union[claripy.ast.Bits,'Expression',int]) -> Optional[int]:
    # delayed import
    from .expression import Expression

    if isinstance(expr, Expression):
        return expr.bits
    elif isinstance(expr, claripy.ast.Bits):
        return expr.size()
    elif hasattr(expr, 'bits'):
        return expr.bits
    else:
        return None

md5_unpacker = struct.Struct('4I')

def stable_hash(t: Tuple) -> int:
    cnt = _dump_tuple(t)
    hd = md5lib.md5(cnt).digest()
    v = md5_unpacker.unpack(hd)[0]
    return md5_unpacker.unpack(hd)[0]  # 32 bits

def _dump_tuple(t: Tuple) -> bytes:
    cnt = b""
    for item in t:
        if item is not None:
            type_ = type(item)
            if type_ in _DUMP_BY_TYPE:
                cnt += _DUMP_BY_TYPE[type_](item)
            else:
                # for TaggedObjects, hash(item) is stable
                # other types of items may show up, such as pyvex.expr.CCall and Dirty. they will be removed some day.
                cnt += struct.pack("<Q", hash(item) & 0xffff_ffff_ffff_ffff)
        cnt += b"\xf0"
    return cnt

def _dump_str(t: str) -> bytes:
    return t.encode('ascii')

def _dump_int(t: int) -> bytes:
    prefix = b"" if t >= 0 else b"-"
    t = abs(t)
    if t <= 0xffff:
        return prefix + struct.pack("<H", t)
    elif t <= 0xffff_ffff:
        return prefix + struct.pack("<I", t)
    elif t <= 0xffff_ffff_ffff_ffff:
        return prefix + struct.pack("<Q", t)
    else:
        cnt = b""
        while t > 0:
            cnt += _dump_int(t & 0xffff_ffff_ffff_ffff)
            t >>= 64
        return prefix + cnt

def _dump_type(t: type) -> bytes:
    return t.__name__.encode("ascii")

_DUMP_BY_TYPE = {
    tuple: _dump_tuple,
    str: _dump_str,
    int: _dump_int,
    type: _dump_type,
}


## python stream_simulator.py sns_topic_arn s3_bucket_name rekognition_role_arn path_to_uploader

import boto3
import os
from datetime import datetime
import uuid
import sys

rekognition_client = boto3.client('rekognition')
kvs_client = boto3.client('kinesisvideo')

video_list = os.listdir()
cwd = os.getcwd()

min_confidence_threshold = 75
supported_file_types = ['mp4']

args = sys.argv

sns_topic_arn = args[1]
s3_bucket_name = args[2]
rekognition_role_arn = args[3]
path_to_uploader = args[4]
def create_processor(kvs_stream_name, stream_processor_name):
    kvs_stream_arn = get_kvs_stream_arn(kvs_stream_name)
    response = rekognition_client.create_stream_processor(
        Input={
            'KinesisVideoStream': {
                'Arn': kvs_stream_arn
            }
        },
        Output={
            'S3Destination': {
                'Bucket': s3_bucket_name
            }
        },
        Name= stream_processor_name,
            Settings = {'ConnectedHome': {
                'Labels': ["PERSON", "PET", "PACKAGE","ALL"],
                'MinConfidence': min_confidence_threshold
            }
            },
        RoleArn=rekognition_role_arn,
        NotificationChannel={
            'SNSTopicArn': sns_topic_arn
        }
    )
    return response['StreamProcessorArn']

def kvs_upload_streamer(path_to_uploader, video_segment, kvs_stream_name):
    cmd = "{} {} {} $(date +%s)".format(path_to_uploader, kvs_stream_name, video_segment)
    os.system(cmd)

def process_stream(stream_processor_name, kvs_stream_name, start_time):
    stream_processor_arn = create_processor(kvs_stream_name, stream_processor_name)
    response = rekognition_client.start_stream_processor(
        Name=stream_processor_name,
        StartSelector={
            'KVSStreamStartSelector': {
                'ProducerTimestamp': start_time
            }
        },
        StopSelector={
            'MaxDurationInSeconds': 120
        }
    )

def get_kvs_stream_arn(stream_name):
    response = kvs_client.describe_stream(
        StreamName=stream_name,
    )
    return response['StreamInfo']['StreamARN']

def main():
    for video_segment in video_list:
        if video_segment.split('.')[-1] not in supported_file_types:
            continue
        start_time = round(datetime.now().timestamp())
        execution_id = str(uuid.uuid4())[:8]

        kvs_stream_name="sveStream{}".format(execution_id)

        kvs_upload_streamer(path_to_uploader, video_segment, kvs_stream_name)

        process_stream("sveProcessor{}".format(execution_id), kvs_stream_name, start_time)

if __name__ == '__main__':
    main()


from ... import Component, ComponentOption, PythonPackage

class wheelPlugin(Component):
    """ The wheel plugin.  This is designed to create multiple components. """

    # The list of components that, if specified, should be installed before
    # this one.
    preinstalls = ['Python']

    # The dict of parts provided by the component.
    @property
    def provides(self):
        return {
            self.name:
                PythonPackage(version=self.version, deps=self.dependencies,
                        exclusions=self.exclusions)
        }

    # The version will be extracted from the name of the wheel.
    version_is_optional = True

    def get_archive_name(self):
        """ Return the filename of the wheel. """

        return self.wheel

    def get_archive_urls(self):
        """ Return the list of URLs where the source archive might be
        downloaded from.
        """

        return self.get_pypi_urls(self.project)

    def get_options(self):
        """ Return a list of ComponentOption objects that define the components
        configurable options.
        """

        options = super().get_options()

        options.append(
                ComponentOption('dependencies', type=list,
                        help="The component:modules that this component "
                                "depends on."))

        options.append(
                ComponentOption('exclusions', type=list,
                        help="The files and directories of this component "
                                "that should be excluded."))

        options.append(
                ComponentOption('project', type=str, default=self.name,
                        help="The name of the PyPI project."))

        options.append(
                ComponentOption('wheel', type=str, required=True,
                        help="The name of the wheel."))

        return options

    def install(self):
        """ Install for the target. """

        self.unpack_wheel(self.get_archive())

    def verify(self):
        """ Verify the component. """

        wheel_version = self.parse_version_number(self.wheel.split('-')[1])

        if self.version is None:
            self.version = wheel_version
        elif self.version != wheel_version:
            self.error(
                    "v{0} is specified but the wheel is v{1}".format(
                            self.version, installed_version))


import sys
from pathlib import Path

values_1 = {
    "A X": 3 + 1,
    "A Y": 6 + 2,
    "A Z": 3,
    "B X": 1,
    "B Y": 3 + 2,
    "B Z": 6 + 3,
    "C X": 6 + 1,
    "C Y": 2,
    "C Z": 3 + 3,
}

values_2 = {
    "A X": 3,
    "A Y": 3 + 1,
    "A Z": 6 + 2,
    "B X": 1,
    "B Y": 3 + 2,
    "B Z": 6 + 3,
    "C X": 2,
    "C Y": 3 + 3,
    "C Z": 6 + 1,
}

def parse_input(path: str):
    p = Path(path)
    content = p.read_text()
    if content.endswith("\n"):
        content = content[:-1]
    return content.split("\n")

def main(input_, values):
    return sum(values[line] for line in input_)

if __name__ == "__main__":
    input_filepath = sys.argv[1]
    second_part = len(sys.argv) > 2 and sys.argv[2] == "--two"
    input_ = parse_input(input_filepath)
    if second_part:
        print(f"result: {main(input_, values_2)}", file=sys.stdout)
    else:
        print(f"result: {main(input_, values_1)}", file=sys.stdout)


class Solution(object):
    def removeDuplicates(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        i = 0
        if len(nums) < 2:
            return len(nums)
        while 1:
            if i == len(nums)-1:
                break
            if nums[i] == nums[i+1]:
                nums.remove(nums[i])
                continue
            i = i + 1
        return len(nums)

26. Remove Duplicates from Sorted Array.py


import torch
import torch.nn.functional as F

def max_shape(data):
    """Gets the maximum length along all dimensions in a list of Tensors"""
    shapes = torch.Tensor([_.shape for _ in data])
    return torch.max(shapes.transpose(0, 1), dim=1)[0].int()

def pad_data_to_same_shape(tensor_list, pad_value=0):
    target_shape = max_shape(tensor_list)

    padded_dataset_shape = [len(tensor_list)] + list(target_shape)
    padded_dataset = torch.Tensor(*padded_dataset_shape).type_as(
        tensor_list[0])

    for i, data in enumerate(tensor_list):
        # Get how much padding is needed per dimension
        padding = reversed(target_shape - torch.Tensor(list(data.shape)).int())

        # Add 0 every other index to indicate only right padding
        padding = F.pad(padding.unsqueeze(0).t(), (1, 0, 0, 0)).view(-1, 1)
        padding = padding.view(1, -1)[0].tolist()

        padded_data = F.pad(data, padding, value=pad_value)
        padded_dataset[i] = padded_data

    return padded_dataset

def fill_diagonally_(matrix,
                     diagonal_index,
                     fill_value=0,
                     fill_method='below'):
    """Destructively fills an nxm tensor somehow with respect to a diagonal.
    :param matrix:
    :type matrix: torch.Tensor
    :param diagonal_index:
    :param fill_value:
    :type fill_value: numeric
    :param fill_method:
    :type fill_method: str
    :return:
    """
    num_rows = matrix.shape[0]
    if fill_method == 'symmetric':
        mask = torch.ones(matrix.shape)
        fill_diagonally_(mask,
                         diagonal_index - 1,
                         fill_method='between',
                         fill_value=0)
        matrix[mask.byte()] = fill_value
        return

    for i in range(num_rows):
        if fill_method == 'below':
            left_bound = 0
            right_bound = min(num_rows, max(i - diagonal_index + 1, 0))
        elif fill_method == 'above':
            left_bound = min(num_rows, max(i - diagonal_index, 0))
            right_bound = num_rows
        elif fill_method == 'between':
            left_bound = min(num_rows, max(i - diagonal_index, 0))
            right_bound = min(num_rows, min(i + diagonal_index + 1, num_rows))
        else:
            msg = ('{} is an invalid fill_method. The fill_method must be in '
                   '\'below\', \'above\', \'symmetric\', \'between\'')
            raise ValueError(msg.format(fill_method))

        matrix[i, left_bound:right_bound] = fill_value


from django.utils import timezone
from rest_framework import viewsets, permissions, status, decorators
from rest_framework.response import Response

from .models import Video
from .serializers import VideoSerializer
from .queries import (
    get_video_queryset_by_query,
    get_video_queryset_by_title,
    get_video_queryset_by_description,
)
from .tasks import (
    run_periodic_background_task_and_update_db,
    fetch_and_save_youtube_videos_by_query_util,
)

class VideoViewSet(viewsets.ModelViewSet):
    queryset = Video.objects.none()
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
    serializer_class = VideoSerializer

    def list(self, request):
        query = request.query_params.get("query")
        qs = get_video_queryset_by_query(query)
        if qs.exists() is False:
            # first fetch youtube videos via non-async util
            count = fetch_and_save_youtube_videos_by_query_util(query)
            if count == 0:
                # quota exceeded, let's try again one more time with different token
                fetch_and_save_youtube_videos_by_query_util(query)

            qs = get_video_queryset_by_query(query)
        page = self.paginate_queryset(qs)
        serializer = VideoSerializer(page, many=True, context={"request": request})

        if query:
            # util to handle to periodic task, also it'll make sure to not create duplicate crons for same query
            run_periodic_background_task_and_update_db(query)

        return self.get_paginated_response(serializer.data)

    @decorators.action(
        detail=False, methods=["GET"], permission_classes=[permissions.AllowAny,]
    )
    def search(self, request):
        search_by_query = request.query_params.get("query")
        search_by_title = request.query_params.get("title")
        search_by_description = request.query_params.get("description")
        if search_by_query:
            qs = get_video_queryset_by_query(search_by_query)
        elif search_by_title:
            qs = get_video_queryset_by_title(search_by_title)
        else:
            qs = get_video_queryset_by_description(search_by_description)

        page = self.paginate_queryset(qs)
        serializer = VideoSerializer(page, many=True, context={"request": request})
        return self.get_paginated_response(serializer.data)


# 백준 1436번 문제
# 영화감독 숌
# https://www.acmicpc.net/problem/1436

import sys

n = int(sys.stdin.readline())
count = 0
i = 666

while(True):
    str_i = str(i)
    if '666' in str_i :
        count += 1
    if count == n:
        print(i)
        break
    i += 1


# Задача 2: Найдите сумму цифр трехзначного числа.
# *Пример:*
#
# 123 -> 6 (1 + 2 + 3)
# 100 -> 1 (1 + 0 + 0) |

n = int(input("Введите трехзначное число: "))
k = 0
sum = 0
for i in range(3):
    if n > 0:
        k = n % 10
        n = n // 10
        sum += k
print(f"сумма цифр равна {sum}")


# -*- coding: utf-8 -*-
"""
Created on Tue Jun 21 17:56:57 2016

@author: Comandini Leonardo, Nicoletti Antea, Schiavon Andrea
"""
#Library for Project9 including the functions that read and BOOTSTRAP the data

# 1) readXL_EONIA
# 2) readXL_BTP_info
# 3) readXL_BTP_data
# 4) bootstrap_EONIA

#Intro:
#The function in this library are suited for the data given for the project, a
#little change in the input files may lead to something unexpected or errors.
#The bootstrap is in this library because of two reasons: the first is its
#'need of customization' around the data and the second is that bootstrap
#results are needed to perform the very next computations.

#--start------------------------------import-----------------------------------
import os                                       # 1) 2) 3)
import numpy as np                              # 1)    3) 4)
import pandas as pd                             # 1) 2) 3) 4)
from p9_support import (xldate_to_datetime,     # 1)    3)
                        str_to_date,            #    2)
                        yearfrac)               #          4)
from p9_business import (monthdeltaMF,          #          4)
                         busday)                #          4)

#---end-------------------------------import-----------------------------------

#--start---------------------------readXL_EONIA--------------------------------
#Read the rates from an excel file and store in a dataframe 'rates'
#Remark: for a date, if at least one rate (before 10 years) is missing the
#        entire line is dropped. (few lines are actually dropped)

# INPUT:
#path = path of the file                       [string]
#file = name of the file                       [string]
#sheet = name of the sheet containing the data [string]
#old_col = list(16) of list(2) of the columns names in which the data are
#          stored                              [list of list of string]
#new_col = list(16) of the new columns names   [list of string]
# OUTPUT:
#rates = dataframe containing the rates        [dataframe]
#               1m   2m   3m   ... 10y
#  2012-4-6
#  2012-4-7
#    ...
#  2015-1-30
# USES:
#xldate_to_datetime

def readXL_EONIA(path,file,sheet,old_col,new_col):
    #join path and file
    path_file = os.path.join(path,file)

    #read the file
    EONIA = pd.read_excel(path_file,
                          sheetname=sheet,
                          header=[1],         #read from the second row
                          skiprows=[2],       #skip the third
                          index_col=None,)    #assign a new label to the rows
                                              #[0, 1, ...]
    #read the rates corresponding to 1 month and store them in 'rates'
    rates = EONIA.ix[EONIA.index,old_col[0]].copy()     #copy BY VALUE
    rates = rates.dropna()                              #drop the NaN cells
    rates.columns = ['Date',new_col[0]]                 #rename the columns

    #Read the rates corresponding to 2 months and store them in 'add',
    #then, using 'Date' as key, merge 'add' and 'rates' and put the result in
    #'rates',
    #'rates' will be now a dataframe with 3 columns: 'Dates','1m','2m'.
    #The new column 'Dates' will be the INTERSECTION of the two previous
    #'Dates' columns and the rows whose elements are outside the intersection
    #are dropped.
    #Then this procedure is iterated for 3 months,..., up to 10y
    for i in range(1,np.size(new_col)):  #from the SECOND to the last
        add = EONIA.ix[EONIA.index,old_col[i]].copy()   #copy BY VALUE
        add = add.dropna()                              #drop the NaN cells
        add.columns = ['Date',new_col[i]]               #rename the columns

        rates = pd.merge(rates,add,      #merge rates and add
                         on='Date',      #'Date' is used as key
                         how='inner')    #inner so an intersection is perfomed

    #Put the column 'Date' as index and drop it as a column
    new_index = rates['Date'].copy()         #copy by value of the column Date
    new_index = new_index.tolist()           #convert the dataframe to list
    new_index = [int(i) for i in new_index]  #convert from float to int
    new_index = [xldate_to_datetime(i) for i in new_index] #convert into datetime
    rates.index = new_index                  #assign Date as index
    del rates['Date']                        #delete the (now useless) column
                                             #of dates
    #REMARK:
    #The row indeces are not ordered, in case of need use:
    #rates=rates.sort_index()

    #rates were in percentage points
    rates = rates/100

    return rates #[dataframe]

#---end----------------------------readXL_EONIA--------------------------------

#--start--------------------------readXL_BTP_info------------------------------
#Read the BTP info from an excel file and store in a dataframe 'bond_info'
#Remark: the Zero-Coupon BTP are dropped

# INPUT:
#path = path of the file                        [string]
#file = name of the file                        [string]
#sheet = name of the sheet containing the data  [string]
# OUTPUT:
#bond_info = dataframe containing the bond info [dataframe]
# USES:
#str_to_date

def readXL_BTP_info(path,file,sheet):
    #join path and file
    path_file = os.path.join(path,file)

    #read the file
    bond_info = pd.read_excel(path_file,
                              sheetname=sheet,
                              header=[0],      #read from the first row
                              skiprows=[1],    #skip the second
                              index_col=[0])   #assign a new label to the rows
                                               #[0, 1, ...]

    #Cut the Zero-Coupon BTP since they are not used and so the conversion of
    #the date to datetime.date can be done also for the whole first coupon date
    #column
    bond_info = bond_info[bond_info.CPN_TYP != 'ZERO COUPON']

    #Convert the dates form string to 'datetime.date'
    bond_info.FIRST_SETTLE_DT=bond_info.FIRST_SETTLE_DT.apply(str_to_date)
    bond_info.MATURITY       =bond_info.MATURITY.apply(str_to_date)
    bond_info.FIRST_CPN_DT   =bond_info.FIRST_CPN_DT.apply(str_to_date)

    #REMARK:
    #The row indeces are not ordered, in case of need use:
    #bond_info=bond_info.sort_index()

    #coupon were *100
    bond_info.CPN = bond_info.CPN/100

    return bond_info #[dataframe]

#---end---------------------------readXL_BTP_info------------------------------

#--start--------------------------readXL_BTP_data------------------------------
#Read the BTP prices from an excel file and store in a dataframe 'bond_prices'
#The file is not 'well' written and the read is not as simple as bond_info.
#We procede as follows:
#STEP1:
#read the file without the first line and store it in 'Data'
#STEP2:
#read only the first line and store in 'BTP_names' the names of the bonds.
#STEP3:
#read bond per bond and merge them in 'bond_prices'
#STEP4:
#Put the column 'Date' as index and drop it (as a column)

def readXL_BTP_data(path,file,sheet):
    #join path and file
    path_file = os.path.join(path,file)

    #------STEP1: read the file without the first line
    #header=[0,1] would be the best but this problem would occur:
    #https://github.com/pydata/pandas/issues/11733
    #'MultiIndex vs index_col=None' problem
    Data = pd.read_excel(path_file,
                         sheetname=sheet,
                         header=[1],       #read from the second row
                         index_col=None)   #assign a new label to the rows
                                           #[0, 1, ...]

    #------STEP2: read only the first line
    row_to_skip = np.size(Data.index) #skip all the rows
    first_line = pd.read_excel(path_file,
                               sheetname=sheet,
                               header=[0],      #read from the first row
                               skip_footer=row_to_skip,
                               index_col=None) #assign a new label to the
                                               #rows [0, 1, ...]
    #Between two BTP names there are three empty cells, so:
    N_bond = 1+np.size(first_line.columns)//4            #Number of bond
    BTP_names = first_line.columns[0:4*N_bond:4]   #Names of the BTP
    #Need a list?
    #Use listBTP=BTP_names.copy().tolist()

    #------STEP3: read bond per bond and merge them in 'bondPrices'
    #Create a list(N_bond) of list(2) with the names of the columns in
    #which dates and prices of each bond are stored.
    #for the clean:
    #old_col = [['Date','PX_LAST']]
    #old_col += [['Date.'+str(i),'PX_LAST.'+str(i)] for i in range(1,N_bond)]
    #for the dirty:
    old_col = [['Date','PX_DIRTY_MID']]
    old_col += [['Date.'+str(i),'PX_DIRTY_MID.'+str(i)] for i in range(1,N_bond)]

    #read the prices corresponding to the first bond and store them in
    #'bond_prices'
    bond_prices = Data.ix[Data.index,old_col[0]].copy() #copy BY VALUE
    bond_prices = bond_prices.dropna()                  #drop the NaN cells
    bond_prices.columns = [['Date',BTP_names[0]]]       #rename the columns

    #Read the second bond prices and store them in 'add', then using 'Date' as
    #key, merge 'add' and 'bond_prices' and put the result in 'bond_prices',
    #'bond_prices' will be now a dataframe with 3 columns: 'Dates',
    #'name_of_first_bond','name_of_second_bond.
    #The new column 'Dates' will be the UNION of the two previous 'Dates'
    #columns and the rows whose elements are outside the intersection
    #are filled with NaN (the previous values are not overwritten).
    #Then this procedure is iterated up to the last bond.
    for i in range(1,N_bond):             #from the SECOND to the last
        add = Data.ix[Data.index,old_col[i]].copy()    #copy BY VALUE
        add = add.dropna()                             #drop the NaN cells
        add.columns = [['Date',BTP_names[i]]]          #Rename the columns

        bond_prices = pd.merge(bond_prices,add, #merge bond_prices and add
                               on='Date',       #'Date' is used as key
                               how='outer')     #outer so a union is perfomed
    #------STEP4:
    #Put the column 'Date' as index and drop it as a column
    new_index = bond_prices['Date'].copy()   #copy by value of the column Date
    new_index = new_index.tolist()           #convert the dataframe to list
    new_index = [int(i) for i in new_index]  #convert from float to int
    new_index = [xldate_to_datetime(i) for i in new_index] #convert into datetime
    bond_prices.index = new_index            #assign Date as index
    del bond_prices['Date']                  #delete the (now useless) column
                                             #of dates

    #REMARK:
    #The row indeces are not ordered, in case of need use:
    #bond_prices=bond_prices.sort_index()

    #prices were *100
    bond_prices = bond_prices/100

    return bond_prices #[dataframe]

#---end---------------------------readXL_BTP_data------------------------------

#--start--------------------------bootstrap_EONIA------------------------------
#Compute the dates corresponding to:
#[t0+1m  t0+2m  t0+3m  ...  t0+10y]
#Compute the corresponding discount factors and zero rates
#store them in 4 dataframes:
#'dates', 'rates', 'discount', 'zero_rates'
#with the same structure of rates

# INPUT:
#rates = dataframe of the EOINA rates            [dataframe]
#            1m   2m   3m   ... 10y
#2012-4-6
#    ...
#2015-1-30
#mta = list of months to add                     [list of int]
#    = [1,2,3,4,5,6,12,2*12,3*12,4*12,5*12,6*12,7*12,8*12,9*12,10*12]
# OUTPUT:
#dates, rates, discount, zero_rates              [dataframe]
# USES:
#yearfrac

def bootstrap_EONIA(rates,mta):
    col = rates.columns
    #initialize the new dataframes
    dates      = rates.copy()
    discount   = rates.copy()
    zero_rates = rates.copy()

    for i in rates.index:    #cycle on the value dates
        ST = busday(i,2)     #settlement = 2 business days after value date
        #compute the dates
        dt = [monthdeltaMF(ST,j) for j in mta]
        dates.loc[[i],:] = dt

        #I largelely 'abuse' of the fact that the last discount that is
        #computed with the 'easy' formula is the 7th
        for j in range(0,7):                 #up to 1y
            discount[col[j]][i]=1/(1+yearfrac(ST,dt[j],2)*
                                           rates[col[j]][i])    #act/360
        summa = discount[col[6]][i]*yearfrac(ST,dt[6],2)         #act/360
        for j in range(7,np.size(col)):  #behond 1y
            discount[col[j]][i]=(1-rates[col[j]][i]*summa)/(1+
                                         yearfrac(dt[j-1],dt[j],2)*
                                         rates[col[j]][i])      #act/360
            summa += discount[col[j]][i]*yearfrac(dt[j-1],dt[j],2)
                                                                #act/360
        zero_rates.loc[[i],:] = [-np.log(discount[k][i])/yearfrac(ST,dates[k][i],1) for k in col]

    return dates, rates, discount, zero_rates #[dataframe]

#---end---------------------------bootstrap_EONIA------------------------------


import random
SUITS = ["Hearts", "Diamonds", "Spades", "Clubs", ]
VALUES = ["Ace", "Two", "Three", "Four", "Five", "Six", "Seven",
          "Eight", "Nine", "Ten", "Jack", "Queen", "King"]

class Card:
    def __init__(self, suite, name, value):
        self.suite = suite
        self.value = value
        self.name = name

    def printMe(self):
        return f"{self.name} of {self.suite}"

class Deck:
    def __init__(self):
        self.deck = []
        self.reset()

    def printDeck(self):
        for i in range(0, 52):
            print(f"{self.deck[i].name} of {self.deck[i].suite}")

    def deal(self):
        ran = random.randint(0, (len(self.deck)-1))
        return self.deck.pop(ran)

    def shuffle(self):
        for i in range(0, 10000):
            for j in range(0, len(self.deck)):
                randomI = random.randint(0, (len(self.deck)-1))
                temp = self.deck[j]
                self.deck[j] = self.deck[randomI]
                self.deck[randomI] = temp

    def reset(self):
        self.deck = []
        for i in range(0, 4):
            for j in range(0, 13):
                if VALUES[j] == "Ten" or VALUES[j] == "Jack" or VALUES[j] == "Queen" or VALUES[j] == "King":
                    self.deck.append(Card(SUITS[i], VALUES[j], 10))
                elif VALUES[j] == "Ace":
                    self.deck.append(Card(SUITS[i], VALUES[j], 11))
                else:
                    self.deck.append(Card(SUITS[i], VALUES[j], j + 1))
        self.shuffle()

class Player:
    def __init__(self, name):
        self.name = name
        self.hand = []
        self.greet()

    def calculateHand(self):
        handValue = 0
        for card in self.hand:
            handValue += card.value
            print("This is the card value", card.value)
        print("Players hand value", handValue)
        return handValue

    def greet(self):
        print(f"Welcome {self.name}! Try not to cry when you lose.")

    def takeCard(self, deck):
        card = deck.deal()
        self.hand.append(card)
        print("You recieved a card.", card.printMe())

    # def discard(self, val):
        # if val <= 5 and val >= 0:
            # return self.hand.remove(val)

    def printHand(self):
        for i in range(0, len(self.hand)):
            print(f"{self.hand[i].name} of {self.hand[i].suite}")

class Dealer:
    def __init__(self):
        self.hand = []
        self.taunt()
        self.deck = Deck()

    def calculateHand(self):
        handValue = 0
        for card in self.hand:
            handValue += card.value
            print("Dealers card value:", card.value)
        print("Dealers hand value:", handValue)
        return handValue

    def taunt(self):
        print(f"Bring it.")

    def dealToSelf(self):
        card = self.deck.deal()
        self.hand.append(card)
        print("The dealer recieved one card", card.printMe())

    def printHand(self):
        for i in range(0, len(self.hand)):
            print(f"{self.hand[i].name} of {self.hand[i].suite}")

    def dealToPlayer(self, player):
        player.takeCard(self.deck)

    def newRound(self):
        self.deck.reset()

class Game:

    def __init__(self):
        self.isPlaying = False
        self.player = Player(input("Type your name:"))
        self.dealer = Dealer()

    def startRound(self):
        self.dealer.newRound()
        self.dealer.hand = []
        self.player.hand = []
        self.dealer.dealToPlayer(self.player)
        self.dealer.dealToSelf()
        self.dealer.dealToPlayer(self.player)
        self.dealer.dealToSelf()
        if not self.compareBothHands():
            self.endRound()
            return
        self.playerChoice()

# start round, give 2 cards and 2 cards to player
    def compareBothHands(self):
        handValuePlayer = self.player.calculateHand()
        handValueDealer = self.dealer.calculateHand()

        if handValuePlayer == 21 and handValueDealer == 21:
            print("Draw")
            return False
        if handValueDealer == 21:
            print("Dealer wins. Suckaaaaaaaaaaaa")
            return False
        if handValuePlayer == 21:
            print("Well played.... -_-")
            return False
        return True

    def playerChoice(self):
        value = input("Would you like to hit or stay?")
        count = 0
        while value.lower() != "hit" and value.lower() != "stay" and count != 5:
            count += 1
            value = input("You suck at spelling. Please re-take the 1st grade and try again. You must choose to HIT or STAY!")

        if value.lower() == "hit":
            self.dealer.dealToPlayer(self.player)
            playerScore = self.player.calculateHand()
            print(f"Your score is {playerScore}")
            if playerScore > 21:
                print("You suck and you lose")
                self.endRound()
            if playerScore == 21:
                print("You win.")
            if playerScore < 21:
                self.dealerChoice()
        if value.lower() == "stay":
            self.dealerChoice()

    def dealerChoice(self):

        self.dealer.dealToSelf()
        dealerScore = self.dealer.calculateHand()
        playerScore = self.player.calculateHand()
        print(f"Your score is {dealerScore}")
        choiceList = ["hit", "stay"]
        choiceGenerator = print(random.choice(choiceList))
        if choiceGenerator == "hit":
            self.dealer.dealToSelf()
        else:
            if dealerScore > 21:
                print("You have bested me, but It wont be so easy next time!")
                self.endRound()
            if dealerScore == 21:
                print("Dealer wins.")
                self.endRound()
            if dealerScore < 21:
                if dealerScore > playerScore:
                    print("You have been crushed!")
                    self.endRound()
                elif dealerScore < playerScore:
                    print("Player wins. But you still suck.")
                    self.endRound()
                elif dealerScore == playerScore:
                    print("Draw. You don't lose, but you also don't win.")
                    self.endRound()

    def endRound(self):
        count = 0
        playAgain = input("Would you like to play again? Yes or No.")
        while playAgain.lower() != "yes" and playAgain.lower() != "no" and count != 2:
            count += 1
            playAgain = input("Pleeeeeease learn how to spell. And then try again.")
        if playAgain.lower() == "yes":
            self.startRound()
        if playAgain.lower() == "no":
            print("You coward. Lol.")

        # round ends if both player and dealer have chosen to stay, if one of them busts, or if one of them gets 21

game = Game()
game.startRound()


# 수학 문제를 푸는 숙제가 있다
# 1. 수학 문제는 N개의 단어로 이루어져 있다
# 2 각 단어는 알파벳 대문자로 이루어져 있다
# 3. 각 알파벳 대문자를 0-9 숫자로 바꿔 N개의 수의 합을 구한다
# N 개의 단어가 주어졌을 때 그 수의 합을 최대로 만드는 프로그램을 작성하라
import sys
input = sys.stdin.readline

N = int(input())
alpha = [0] * 26
for _ in range(N):
    a = [*input()][:-1]
    n = len(a) - 1
    for l in a:
        alpha[ord(l) - 65] += 10 ** n
        n-=1
alpha.sort(reverse=True)
ans = 0
n = 9
for i in alpha:
    if i == 0: break
    ans += i * n
    n -= 1
print(ans)


import boto3
import json
import os
import pandas as pd
from botocore.exceptions import ClientError
from urllib.request import urlopen

def simple_function(url, sheet_name):
    file_name = url.split('/')[-1]
    print('file_name', file_name)
    with urlopen(url) as response, open(file_name, 'wb') as out_file:
        data = response.read()
        out_file.write(data)
    df = pd.read_excel(file_name, sheet_name=sheet_name)
    df.fillna('', inplace=True)
    data = list(df.T.to_dict().values())
    json_data = json.dumps(data)
    try:
        os.remove(file_name)
        print('removed file {}'.format(file_name))
    except OSError:
        pass
    try:
        s3 = boto3.resource('s3')
        s3.Bucket(S3_BUCKET_NAME).put_object(Key='data.json', Body=json_data)
        return True
    except ClientError as e:
        print(e)
        return False

simple_function(url=FILE_URL, sheet_name=SHEET_NAME)


def factorial(n):
    if(n == 0):
        return 1
    else:
        return n*factorial(n-1)

def combinations(n, r):
    return factorial(n)/(factorial(r)*factorial(n-r))

line = [float(inp) for inp in input().split()]
boy = line[0]
girl = line[1]

n = 6
x = 3
p = boy/(boy+girl)
q = 1 - p
at_least_3 = 0
for i in range(x, n+1):
    at_least_3 += combinations(n, i)*(p**i)*(q**(n-i))

print( "%.3f" % at_least_3 )   # P = P(3) + P(4) + P(5) + P(6)


# coding: utf-8
# This is Edje Electronics' code with some minor adjustments
# Credit goes to his repo: https://github.com/EdjeElectronics/TensorFlow-Lite-Object-Detection-on-Android-and-Raspberry-Pi

import tflite_runtime.interpreter as tflite
import os
import argparse
import cv2
import numpy as np
import sys
import time
from threading import Thread
import importlib.util
from datetime import datetime
from datetime import timedelta
import csv

parser = argparse.ArgumentParser()
parser.add_argument('--model', help='Provide the path to the TFLite file, default is models/model.tflite',
                    default='models/model.tflite')
parser.add_argument('--labels', help='Provide the path to the Labels, default is models/labels.txt',
                    default='models/labels.txt')
parser.add_argument('--video', help='Name of the video to perform detection on',
                    default='videos/2021-09-16-09-18-27.mp4')
parser.add_argument('--threshold', help='Minimum confidence threshold for displaying detected objects',
                    default=0.65)
parser.add_argument('--keepDetections', help='Saves detections (boxes, classes and scores) on frames',
                    default=False)

args = parser.parse_args()

# PROVIDE PATH TO MODEL DIRECTORY
PATH_TO_MODEL_DIR = args.model

# PROVIDE PATH TO LABEL MAP
PATH_TO_LABELS = args.labels

# PROVIDE PATH TO VIDEO DIRECTORY
VIDEO_PATH = args.video

# PROVIDE THE MINIMUM CONFIDENCE THRESHOLD
MIN_CONF_THRESH = float(args.threshold)

# Save detections on frames or not
keepDetections = args.keepDetections

import time
print('Loading model...', end='')
start_time = time.time()

# LOAD TFLITE MODEL
interpreter = tflite.Interpreter(model_path=PATH_TO_MODEL_DIR)
# LOAD LABELS
with open(PATH_TO_LABELS, 'r') as f:
    labels = [line.strip() for line in f.readlines()]
end_time = time.time()
elapsed_time = end_time - start_time
print('Done! Took {} seconds'.format(elapsed_time))

interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]

floating_model = (input_details[0]['dtype'] == np.float32)

input_mean = 127.5
input_std = 127.5

# Initialize frame rate calculation
frame_rate_calc = 1
freq = cv2.getTickFrequency()
print('Running inference for {}... '.format(VIDEO_PATH), end='')
# Initialize video
video = cv2.VideoCapture(VIDEO_PATH)
imW = video.get(cv2.CAP_PROP_FRAME_WIDTH)
imH = video.get(cv2.CAP_PROP_FRAME_HEIGHT)

# Variables propres à la vidéo
video_name = os.path.basename(VIDEO_PATH)
fps = video.get(cv2.CAP_PROP_FPS)
number_of_frames = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
print('\nNombre d\'images par secondes (FPS) : ', fps)
print('Total number of frames : ', number_of_frames)
print('Durée de la vidéo : ', number_of_frames/fps, ' secondes')

# Dossier pour sauvegarder les frames (le créé s'il n'existe pas) :
frame_path = os.getcwd() + '/saved_frames/'
if not os.path.exists(frame_path):
  os.mkdir(frame_path)

# Les frames sont sauvegardées dans un dossier qui a le même nom que la vidéo courante
frame_path += video_name
if not os.path.exists(frame_path):
  os.mkdir(frame_path)

# Converti la liste de labels en dictionnaire pour compter les occurences des espèces
counting_detections = dict.fromkeys(labels, 0)

# Garde les N frames denières détections pour supprimer les faux positifs
N_save = 5 # Par défaut, si on veut que l'oiseau y soit au moins 1 seconde, on fixe cette valeur à la variable "fps"

# Pour le fichier CSV, qui a pour nom : CSV_nomVidéo (sans .mp4)
CSV_path = os.getcwd() + '/CSV_' + video_name[:-4] + '.csv'
print('CSV_path :', CSV_path)
header = ['videotime', 'class', 'xmin', 'ymin', 'xmax', 'ymax']

# Créé le fichier CSV en écriture
with open(CSV_path, 'w', newline='') as f:
    # Entête du fichier CSV seulement à la création du fichier
    writer = csv.DictWriter(f, delimiter=';', fieldnames=header)
    writer.writeheader()

# Parcours de la vidéo frame par frame
while(video.isOpened()):
    # Start timer (for calculating frame rate)
    current_count=0
    t1 = cv2.getTickCount()

    # Grab frame from video stream
    ret, frame1 = video.read()

    # Si on a bien lu une frame
    if ret:
        # Acquire frame and resize to expected shape [1xHxWx3]
        frame = frame1.copy()
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        frame_resized = cv2.resize(frame_rgb, (width, height))
        input_data = np.expand_dims(frame_resized, axis=0)

        # Sauvegarde le temps de la frame courante en secondes
        milliseconds = video.get(cv2.CAP_PROP_POS_MSEC)
        timestamp = timedelta(milliseconds=milliseconds)

        # Numéro de la frame courante
        frame_number = video.get(cv2.CAP_PROP_POS_FRAMES)
        if frame_number % 50 == 0:
            print('Treating frame n°', frame_number)

        # Normalize pixel values if using a floating model (i.e. if model is non-quantized)
        if floating_model:
            input_data = (np.float32(input_data) - input_mean) / input_std

        # Perform the actual detection by running the model with the image as input
        interpreter.set_tensor(input_details[0]['index'],input_data)
        interpreter.invoke()

        # Retrieve detection results
        boxes = interpreter.get_tensor(output_details[0]['index'])[0] # Bounding box coordinates of detected objects
        classes = interpreter.get_tensor(output_details[1]['index'])[0] # Class index of detected objects
        scores = interpreter.get_tensor(output_details[2]['index'])[0] # Confidence of detected objects
        #num = interpreter.get_tensor(output_details[3]['index'])[0]  # Total number of detected objects (inaccurate and not needed)

        # Loop over all detections and draw detection box if confidence is above minimum threshold
        detected_classes = []
        detected_scores = []
        keep_frame = True

        # Pour le fichier CSV
        rows = []
        # Loop over all detections and draw detection box if confidence is above minimum threshold
        for i in range(len(scores)):
            if ((scores[i] > MIN_CONF_THRESH) and (scores[i] <= 1.0)):

                # Get bounding box coordinates and draw box
                # Interpreter can return coordinates that are outside of image dimensions, need to force them to be within image using max() and min()
                ymin = int(max(1,(boxes[i][0] * imH)))
                xmin = int(max(1,(boxes[i][1] * imW)))
                ymax = int(min(imH,(boxes[i][2] * imH)))
                xmax = int(min(imW,(boxes[i][3] * imW)))

                # Trace la bounding box sur l'image
                cv2.rectangle(frame, (xmin,ymin), (xmax,ymax), (10, 255, 0), 2)

                # Draw label
                object_name = labels[int(classes[i])] # Look up object name from "labels" array using class index
                score = int(scores[i]*100)
                label = '%s: %d%%' % (object_name, score) # Example: 'person: 72%'
                labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2) # Get font size
                label_ymin = max(ymin, labelSize[1] + 10) # Make sure not to draw label too close to top of window
                cv2.rectangle(frame, (xmin, label_ymin-labelSize[1]-10), (xmin+labelSize[0], label_ymin+baseLine-10), (255, 255, 255), cv2.FILLED) # Draw white box to put label text in
                cv2.putText(frame, label, (xmin, label_ymin-7), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2) # Draw label text
                current_count+=1

                # Mets à jour le compteur de la classe actuelle dans le dictionnaire
                counting_detections[object_name] += 1
                # Enregistre les noms de classes et scores détectés
                detected_classes.append(object_name)
                detected_scores.append(scores[i])
                # Vérifie si l'espèce détectée n'est pas présente sur au moins N frames, on ne la garde pas
                if counting_detections[object_name] < N_save :
                    keep_frame = False

                # Données pour la/les nouvelle(s) ligne(s) pour le CSV
                rows.append({'videotime': timestamp, 'class': object_name, 'xmin': xmin, 'ymin': ymin, 'xmax': xmax, 'ymax': ymax})

        # Calculate framerate
        t2 = cv2.getTickCount()
        time1 = (t2-t1)/freq
        frame_rate_calc= 1/time1

        # Draw framerate in corner of frame
        cv2.putText(frame,'FPS on Pi: {0:.2f}, Detection(s) count: {1}'.format(frame_rate_calc, str(current_count)),(15,25),cv2.FONT_HERSHEY_SIMPLEX,1,(0,255,55),2,cv2.LINE_AA)
        # Si on a détecté une espèce au moins :
        if detected_classes and keep_frame :
          # Sauvegarde la frame avec les détections et le temps sur la vidéo (si ce temps n'est pas nul)
          # TODO les 5 ou 6 dernières frames ont un temps égal à 0.0 avec cv2 ???
          if milliseconds != 0.0 and keepDetections:
            # temps de la frame ==> str(timestamp)
            saved_frame_name = 'frame_' + str(int(frame_number)) + '.jpg'
            cv2.imwrite(os.path.join(frame_path, saved_frame_name), frame)
          elif not keepDetections:
            # Affiche les détections à la volée
            cv2.imshow('Object detector', frame)

        # Ouverture du fichier CSV pour ajouter des données à la suite
        with open(CSV_path, 'a', newline='') as f:
            # Sauvegarde le nom de l'image, la/les espèce(s) et les coordonées des bounding boxes dans le CSV
            writer = csv.DictWriter(f, delimiter=';', fieldnames=header)
            # Si on a au moins une détection
            if rows != []:
                # Une ligne par espèce pour l'image courante
                for l in rows:
                    writer.writerow(l)

        # Press 'q' to quit
        if not keepDetections:
            # Attend moins de temps pour sauvegarder les images/frames
            if cv2.waitKey(1) == ord('q'):
                break
        else:
            # Affiche une image par seconde (1000ms)
            if cv2.waitKey(1000) == ord('q'):
                break

    # Si c'est la fin de la vidéo
    else:
        video.release()

# Affichage finaux
if os.path.exists(frame_path):
  print('Saved frames : ', len(os.listdir(frame_path)))

total_seconds = number_of_frames / frame_rate_calc
print('Average total time :', timedelta(seconds=total_seconds))
print('Detected species : ', counting_detections)

# Clean up
cv2.destroyAllWindows()
print("Done")


'''
How many steps does it take to chage one sting to another.
In this program you can only: change, insert, or delete
'''
from Functions import *
def countDifference(String1, String2, m, changes = []):
    # Check the first letter
    if String1[0] == String2[0]:
        changes.append(0)
    else:
        # run both checks
        insert = checkForInsert(String1, String2, 0)
        delete = checkForDelete(String1, String2, 0)
        if insert:  # if insert returned true add a black character to correct the indexes for fallowing charaters
            String1 = "_" + String1
        elif delete:  # if delete returned try remove a character to correct the indexes for the fallowing characters.
            String1 = String1[1:]

        # if both are false then a change needs to be made we don't have to check
        # if the letter isn't the same (doesn't matter what the change is) make one change
        changes.append(1)

    # print(changes[0])

    for index in range(1, m):
        try:
            #print(String1[index], String2[index])
            if String1[index] == String2[index]:
                changes.append(changes[index - 1])
            else:
                # run both checks
                insert = checkForInsert(String1, String2, index)
                delete = checkForDelete(String1, String2, index)
                if insert:  # if insert returned true add a black character to correct the indexes for fallowing charaters
                    String1 = String1[:index] + "_" + String1[index:]

                elif delete:  # if delete returned try remove a character to correct the indexes for the fallowing characters.
                    String1 = String1[:index] + String1[index + 1:]

                # if both are false then a change needs to be made we don't have to check
                # if the letter isn't the same (doesn't matter what the change is) make one change

                changes.append(1 + changes[index - 1])
                #print(String1)
        except IndexError:
            # While checking each letter
            # if either String1 or String2 is too short there needs to have a change made
            # whether is insert or delete add one to the count
            changes.append(1 + changes[index - 1])
            '''
            try:
                print(" ", String2[index])
            except IndexError:
                print(String1[index])
            print(changes)
            '''

    return changes[-1]

File_object = open(r"Tester.txt", "r")

for i in range(0,8):
    String1, String2 = setupFile(File_object)
    print(String1 + ",", String2 + ", m = " + str(max(len(String1), len(String2))))
    F = []
    changes = countDifference(String1, String2, max(len(String1), len(String2)), F )
    print("Number of Changes: ",changes, "\n")

File_object.close()


import numpy as np
import matplotlib.pyplot as plt
import time
import os

def get_cpg_values(mu, offset, omega, d, num_samples=1000):
    r = np.sqrt(mu)
    phi = np.pi * d
    o = offset
    gamma = 0.1
    dt = 0.001

    samples = []

    # startup_samples = 5000

    for sample in range(num_samples):
        for iteration in range(int(0.001 / dt)):
            d_r = gamma * (mu - r * r) * r
            d_phi = omega
            d_o = 0

            r += dt * d_r
            phi += dt * d_phi
            o += dt * d_o

        two_pi = 2 * 3.141592654

        phi_L = 0
        phi_2pi = phi % two_pi
        if phi_2pi < (two_pi * d):
            phi_L = phi_2pi / (2 * d)
        else:
            phi_L = (phi_2pi + two_pi * (1 - 2 * d)) / (2 * (1 - d))

        action = r * np.cos(phi_L) + o
        # if sample >= startup_samples:
        samples.append(action)

    return samples

def main():
    times = np.arange(0, 1, 0.001)
    amplitude = 30**2
    freq = 1
    cpg_values_1 = np.array(get_cpg_values(amplitude, 0, freq * 2 * np.pi, 0.1))
    cpg_values_3 = np.array(get_cpg_values(amplitude, 0, freq * 2 * np.pi, 0.5))
    cpg_values_5 = np.array(get_cpg_values(amplitude, 0, freq * 2 * np.pi, 0.9))

    plt.figure(figsize=(4,3))

    ax = plt.gca()
    ax.grid(False)

    ax.yaxis.set_ticks_position('left') # this one is optional but I still recommend it...
    ax.xaxis.set_ticks_position('bottom')

    # 1
    plt.plot(times, cpg_values_1, label='d=0.1', color='#78B833')
    plt.plot(times, cpg_values_3, label='d=0.5', color='#DD7611')
    plt.plot(times, cpg_values_5, label='d=0.9', color='#16A6C9')

    plt.plot(times, [0] * len(times), linestyle=':', color='#b0b0b0', linewidth=0.3)

    # 2
    # plt.plot(times, cpg_values_1, label='d=0.1', color='#763369')
    # plt.plot(times, cpg_values_3, label='d=0.5', color='#D84451')
    # plt.plot(times, cpg_values_5, label='d=0.9', color='#F7D302')

    plt.ylim(cpg_values_1.min()*1.1, cpg_values_1.max()*1.1)

    plt.xlabel('Time (seconds)')
    plt.ylabel('Motor position (degrees)')

    plt.legend(loc='upper left', frameon=False)
    plt.tight_layout()

    plt.savefig('/Users/Siebe/Dropbox/Thesis/presentation_plots/cpg_duty_factor.png', dpi=300)

if __name__ == '__main__':
    main()


from collections import deque

n,m = map(int, input().split())

graph = [[] for _ in range(n)]

for _ in range(m):
    u,v = map(int, input().split())
    graph[u-1].append(v-1)
    graph[v-1].append(u-1)

isTwoGraph = True
queue = deque([0])
colors = [0 for _ in range(n)]
colors[0] = 1

while queue:
    v = queue.popleft()
    for i in graph[v]:
        if colors[i]==0:
            queue.append(i)
            colors[i] = -1 * colors[v]
        elif colors[i]==colors[v]:
            isTwoGraph=False
            break

white = colors.count(1)
black = colors.count(-1)

if isTwoGraph:
    ans = n*(n-1)/2 - m - white*(white-1)/2 - black*(black-1)/2
    print(int(ans))
else:
    print(0)


#!/usr/bin/env python
# coding: utf-8

# In[ ]:

import numpy as np
import matplotlib.pyplot as plt
import xarray as xr

ds=xr.open_dataset("data_netcdf/subspace_trans.nc")
# print(ds)
# tau = 3.0

plt.style.use('../nature_style.txt')

fig=plt.figure(figsize=(3.3,4.5),dpi=600) # figsize=(width,height(inch)),dpi(dots per inch)
ax1=fig.add_subplot(211)
var=ds.jkee
# vmax=np.abs(var).max()
vmax=np.abs(ds.jkie+ds.jkei).max()*0.2
quad1=ax1.pcolormesh(ds.kx,ds.ky,var,cmap="seismic",shading="auto",vmin=-vmax,vmax=vmax)
fig.colorbar(quad1,shrink=0.83,aspect=10)
ax1.set_xlim(-4,4)
ax1.set_ylim(0,5)
ax1.set_xlabel(r"Radial wave number $k_x \rho_\mathrm{ti}$")
ax1.set_ylabel(r"Poloidal wave number $k_y \rho_\mathrm{ti}$")
ax1.set_aspect("equal")
ax1.set_title(r"Electron-scale, electron-scale coupling $J_{\bf k}^{\Omega_e,\Omega_e}$",fontsize=7)

ax2=fig.add_subplot(212)
var=ds.jkie+ds.jkei
# vmax=np.abs(var).max()
quad2=ax2.pcolormesh(ds.kx,ds.ky,var,cmap="seismic",shading="auto",vmin=-vmax,vmax=vmax)
fig.colorbar(quad2,shrink=0.83,aspect=10)
ax2.set_xlim(-4,4)
ax2.set_ylim(0,5)
ax2.set_xlabel(r"Radial wave number $k_x \rho_\mathrm{ti}$")
ax2.set_ylabel(r"Poloidal wave number $k_y \rho_\mathrm{ti}$")
ax2.set_aspect("equal")
ax2.set_title(r"Ion-scale, electron-scale coupling $2J_{\bf k}^{\Omega_i,\Omega_e}$",fontsize=7)

fig.text(0.06,0.87,"a",color="k", fontfamily="sans-serif", fontweight="bold", fontsize=8)
fig.text(0.06,0.455,"b",color="k", fontfamily="sans-serif", fontweight="bold", fontsize=8)

plt.savefig("fig5.jpg",dpi=600)
quad1.set_rasterized(True)
quad2.set_rasterized(True)
plt.savefig('fig5.svg',bbox_inches="tight")
import subprocess
subprocess.call('inkscape fig5.svg -M fig5.emf', shell=True)
subprocess.call('inkscape fig5.svg -E fig5.eps', shell=True)
subprocess.call('inkscape fig5.svg -A fig5.pdf', shell=True)
plt.show()

# In[ ]:


n = int(input())
data = []
for i in range(n):
    data.append(list(map(int, input().split())))

def ttt_pooling(data, n):
    if n == 2:
        temp_lst = []
        for i in range(2):
            for j in range(2):
                temp_lst.append(data[i][j])
        temp_lst.sort()
        return temp_lst[2]
    elif n != 2:
        temp_data = [[], []]
        pooled_data = []
        index = 0
        for i in range(0, n, 2):
            pooled_data.append([])
            for j in range(0, n, 2):
                temp_data[0].append(data[i][j])
                temp_data[0].append(data[i][j+1])
                temp_data[1].append(data[i+1][j])
                temp_data[1].append(data[i+1][j+1])
                pooled_data[index].append(ttt_pooling(temp_data, 2))
                temp_data = [[], []]
            index += 1
        return ttt_pooling(pooled_data, int(n/2))

print(ttt_pooling(data, n))