from sys import byteorder
from array import array
from struct import pack

import pyaudio
import wave
import datetime
import threading
import random

# thresholds defined as volume to consider between words.
different_thresholds = [1200, 1500, 1700, 1900, 2200]
volume_threshold = 1500
CHUNK_SIZE = 1024
FORMAT = pyaudio.paInt16
RATE = 44100
SILENCE_LENGTH = 1 # number of consecutive 'silent' audio chunks before we decide to cut the word.
WAIT_FOR_SND = 3 # number of samples we should 'keep' after the silence is detected (keeps a dying off voice)

def is_silent(snd_data):
    "Returns 'True' if below the 'silent' threshold"
    return max(snd_data) < volume_threshold

def normalize(snd_data):
    "Average the volume out"
    MAXIMUM = 16384
    times = float(MAXIMUM)/max(abs(i) for i in snd_data)

    r = array('h')
    for i in snd_data:
        r.append(int(i*times))
    return r

def trim(snd_data):
    "Trim the blank spots at the start and end"
    def _trim(snd_data):
        snd_started = False
        r = array('h')

        for i in snd_data:
            if not snd_started and abs(i)>volume_threshold:
                snd_started = True
                r.append(i)

            elif snd_started:
                r.append(i)
        return r

    # Trim to the left
    snd_data = _trim(snd_data)

    snd_data.reverse()
    snd_data = _trim(snd_data)
    snd_data.reverse()
    return snd_data

def add_silence(snd_data, seconds):
    "Add silence to the start and end of 'snd_data' of length 'seconds' (float)"
    r = array('h', [0 for i in range(int(seconds*RATE))])
    r.extend(snd_data)
    r.extend([0 for i in range(int(seconds*RATE))])
    return r

def record(stream):
    """
    Record a word or words from the microphone and
    return the data as an array of signed shorts.

    Normalizes the audio, trims silence from the
    start and end, and pads with 0.5 seconds of
    blank sound to make sure VLC et al can play
    it without getting chopped off.
    """

    num_silent = 0
    snd_started = False

    r = array('h')

    wait_for_snd = 0
    while 1:
        # little endian, signed short
        snd_data = array('h', stream.read(CHUNK_SIZE))
        if byteorder == 'big':
            snd_data.byteswap()
        r.extend(snd_data)

        silent = is_silent(snd_data)
        if silent and wait_for_snd:
            wait_for_snd -= 1
        if silent and snd_started:
            num_silent += 1
        elif not silent and not snd_started:
            snd_started = True
            wait_for_snd = WAIT_FOR_SND

        if snd_started and num_silent > SILENCE_LENGTH:
            break

    sample_width = p.get_sample_size(FORMAT)

    # format the data to be normalized and trimmed.
    r = normalize(r)
    r = trim(r)
    # randomly adds silence and silence thresholds on 20 percent of the data.
    # this helps varying amounts of silence to sounds and still classifying them correctly
    if random.random() < 0.2:
        r = add_silence(r, 0.2)
    volume_threshold = random.choice(different_thresholds)
    return sample_width, r

def record_to_file(path, stream):
    "Records from the microphone and outputs the resulting data to 'path'"
    sample_width, data = record(stream)
    data = pack('<' + ('h'*len(data)), *data)

    filename = str(datetime.datetime.now()).replace('.', '').replace(':', '_') + ".wav"
    wf = wave.open(path + filename, 'wb')
    wf.setnchannels(1)
    wf.setsampwidth(sample_width)
    wf.setframerate(RATE)
    wf.writeframes(data)
    wf.close()

if __name__ == '__main__':
    """
    Main program asks you to speak rich and not rich, and places words it detects into files.
    """
    p = pyaudio.PyAudio()
    stream = p.open(format=FORMAT, channels=1, rate=RATE,
        input=True, output=True,
        frames_per_buffer=CHUNK_SIZE)

    finished_recording = False
    def check_key_press():
        global finished_recording
        finished_recording = False
        input('')
        finished_recording = True

    print("please say RICH words into the microphone. press enter when finished.")
    threading.Thread(target = check_key_press).start()
    richs_gained = 0
    while not finished_recording:
        richs_gained += 1
        print('richs gained:', richs_gained, end='\r')
        record_to_file('rich/', stream)
    print("done - results written to 'rich' folder")

    print("please say NON RICH words into the microphone. press enter when finished.")
    threading.Thread(target = check_key_press).start()
    not_richs_gained = 0
    while not finished_recording:
        not_richs_gained += 1
        print('not riches gained:', not_richs_gained, end='\r')
        record_to_file('notrich/', stream)

    stream.stop_stream()
    stream.close()
    p.terminate()

    print("done - results written to 'notrich' folder")
    print('Goodbye.')


import time

class Solution:
    def isIsomorphic(self, s: str, t: str) -> bool:
        d = {}
        values_set = set()
        for i in range(0, len(s)):
            l = s[i]
            if l in d:
                if d[l] != t[i]:
                    return False
            else:
                v = t[i]
                if v in values_set:
                    return False
                d[l] = v
                values_set.add(v)

        return True

if __name__ == "__main__":
    st = time.time()

    s = Solution()
    print(s.isIsomorphic("egg", "add"))
    print(s.isIsomorphic("foo", "bar"))
    print(s.isIsomorphic("paper", "title"))
    print(s.isIsomorphic("badc", "baba"))  # false

    et = time.time()
    elapsed_time = et - st
    print('Execution time:', elapsed_time, 'seconds')

    print("Time complexity: O(s+t)")
    print("Space complexity: O(1)")


# -*- coding: utf-8 -*-
# @Author  : Zhirong Tang
# @Time    : 2022/2/26 10:49 AM
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
#
# 代码中的类名、方法名、参数名已经指定，请勿修改，直接返回方法规定的值即可
#
#
# @param root TreeNode类
# @param p int整型
# @param q int整型
# @return int整型
#
class Solution:
    def lowestCommonAncestor(self , root: TreeNode, p: int, q: int):
        # write code here
        # method-1: DFS
        curr = root
        while True:
            if p < curr.val and q < curr.val:
                # both in left subtree
                curr = curr.left
            elif p > curr.val and q > curr.val:
                # both in right subtree
                curr = curr.right
            else:
                break
        return curr.val

JZ/JZ68.二叉搜索树的最近公共祖先.py

JZ68.二叉搜索树的最近公共祖先.py


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Sep  9 14:16:05 2020

@author: pageot
"""

import os
import sqlite3
import geopandas as geo
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import cm
import csv
import numpy as np
import pandas as pd
import seaborn as sns
import TEST_ANALYSE_SIGNATURE
import shapely.geometry as geom
import descartes
import pickle
import datetime
from scipy import *
from scipy import stats
from pylab import *
from sklearn.metrics import *
from sklearn.linear_model import LinearRegression
from math import log10, cos, sin, asin, sqrt, exp,acos
from collections import namedtuple
import scipy.io
def predict(x):
   return slope * x + intercept

def select_color_date(x):
    couleurs=[]
    for i in range(len(x)):
        if x.date.iloc[i].strftime('%m-%d')<= "04-01" :
            couleurs.append("r")
        else :
            couleurs.append("b")
    return couleurs

    """Calculates reference ET0 based on the Penman-Monteith model.

     This routine calculates the potential evapotranspiration rate from
     a reference crop canopy (ET0) in mm/d. For these calculations the
     analysis by FAO is followed as laid down in the FAO publication
     `Guidelines for computing crop water requirements - FAO Irrigation
     and drainage paper 56 <http://www.fao.org/docrep/X0490E/x0490e00.htm#Contents>`_

    Input variables::

        DAY   -  Python datetime.date object                   -
        LAT   -  Latitude of the site                        degrees
        ELEV  - Elevation above sea level                      m
        TMIN  - Minimum temperature                            C
        TMAX  - Maximum temperature                            C
        AVRAD - Daily shortwave radiation                   J m-2 d-1
        VAP   - 24 hour average vapour pressure               hPa
        WIND2 - 24 hour average windspeed at 2 meter          m/s

    Output is:

        ET0   - Penman-Monteith potential transpiration
                rate from a crop canopy                     [mm/d]
    """
    global DAYL
    # psychrometric instrument constant (kPa/Celsius)
    PSYCON = 0.665
    # albedo and surface resistance [sec/m] for the reference crop canopy
    REFCFC = 0.23; CRES = 70.
    # latent heat of evaporation of water [J/kg == J/mm] and
    LHVAP = 2.45E6
    # Stefan Boltzmann constant (J/m2/d/K4, e.g multiplied by 24*60*60)
    STBC = 4.903E-3
    # Soil heat flux [J/m2/day] explicitly set to zero
    G = 0.

    # mean daily temperature (Celsius)
    TMPA = (TMIN+TMAX)/2.

    # Vapour pressure to kPa
    VAP = hPa2kPa(VAP)
    # atmospheric pressure (kPa)
    T = Celsius2Kelvin(TMPA)
    PATM = 101.3 * pow((T - (0.0065*ELEV))/T, 5.26)

    # psychrometric constant (kPa/Celsius)
    GAMMA = PSYCON * PATM * 1.0E-3

    # Derivative of SVAP with respect to mean temperature, i.e.
    # slope of the SVAP-temperature curve (kPa/Celsius);
    SVAP_TMPA = SatVapourPressure(TMPA)
    DELTA = (4098. * SVAP_TMPA)/pow((TMPA + 237.3), 2)

    # Daily average saturated vapour pressure [kPa] from min/max temperature
    SVAP_TMAX = SatVapourPressure(TMAX)
    SVAP_TMIN = SatVapourPressure(TMIN)
    SVAP = (SVAP_TMAX + SVAP_TMIN) / 2.
    # measured vapour pressure not to exceed saturated vapour pressure
    VAP = np.minimum(VAP, SVAP)

    # Longwave radiation according at Tmax, Tmin (J/m2/d)
    # and preliminary net outgoing long-wave radiation (J/m2/d)
    STB_TMAX = STBC * pow(Celsius2Kelvin(TMAX), 4)
    STB_TMIN = STBC * pow(Celsius2Kelvin(TMIN), 4)
    RNL_TMP = ((STB_TMAX + STB_TMIN) / 2.) * (0.34 - 0.14 * np.sqrt(VAP))

    # Clear Sky radiation [J/m2/DAY] from Angot TOA radiation
    # the latter is found through a call to astro()
    r = astro(doy, LAT, AVRAD)
    CSKYRAD = (0.75 + (2e-05 * ELEV)) * r.ANGOT
    # if CSKYRAD > 0:
        # Final net outgoing longwave radiation [J/m2/day]
    RNL = RNL_TMP * (1.35 * (AVRAD/CSKYRAD) - 0.35)

    # radiative evaporation equivalent for the reference surface
    # [mm/DAY]
    RN = ((1-REFCFC) * AVRAD - RNL)/LHVAP

    # aerodynamic evaporation equivalent [mm/day]
    EA = ((900./(TMPA + 273)) * WIND2 * (SVAP - VAP))

    # Modified psychometric constant (gamma*)[kPa/C]
    MGAMMA = GAMMA * (1. + (CRES/208.*WIND2))

    # Reference ET in mm/day
    ET0 = (DELTA * (RN-G))/(DELTA + MGAMMA) + (GAMMA * EA)/(DELTA + MGAMMA)
        # ET0 = np.maximum(0., ET0)
    # else:
    #     ET0 = np.nan
    return ET0

    """python version of ASTRO routine by Daniel van Kraalingen.

    This subroutine calculates astronomic daylength, diurnal radiation
    characteristics such as the atmospheric transmission, diffuse radiation etc.

    :param day:         date/datetime object
    :param latitude:    latitude of location
    :param radiation:   daily global incoming radiation (J/m2/day)

    output is a `namedtuple` in the following order and tags::

        DAYL      Astronomical daylength (base = 0 degrees)     h
        DAYLP     Astronomical daylength (base =-4 degrees)     h
        SINLD     Seasonal offset of sine of solar height       -
        COSLD     Amplitude of sine of solar height             -
        DIFPP     Diffuse irradiation perpendicular to
                  direction of light                         J m-2 s-1
        ATMTR     Daily atmospheric transmission                -
        DSINBE    Daily total of effective solar height         s
        ANGOT     Angot radiation at top of atmosphere       J m-2 d-1

    Authors: Daniel van Kraalingen
    Date   : April 1991

    Python version
    Author      : Allard de Wit
    Date        : January 2011
    """
    global DAYL
    global ANGOT
    global DAYLP
    global SINLD
    global COSLD
    global DIFPP
    global ATMTR
    global DSINBE
    # Check for range of latitude
    # if abs(latitude) > 90.:
    #     msg = "Latitude not between -90 and 90"
    #     raise RuntimeError(msg)
    LAT = latitude

    # Determine day-of-year (IDAY) from day
    IDAY = doy

    # reassign radiation
    AVRAD = radiation

    # Test if variables for given (day, latitude, radiation) were already calculated
    # in a previous run. If not (e.g. KeyError) calculate the variables, store
    # in cache and return the value.
    # try:
    #     return _cache[(IDAY, LAT, AVRAD)]
    # except KeyError:
    #     pass

    # constants
    RAD = 0.0174533
    PI = 3.1415926
    ANGLE = -4.

    # map python functions to capitals
    SIN = sin
    COS = cos
    ASIN = asin
    REAL = float
    SQRT = np.sqrt
    ABS = abs

    # Declination and solar constant for this day
    DEC = -ASIN(SIN(23.45*RAD)*COS(2.*PI*(REAL(IDAY)+10.)/365.))
    SC  = 1370.*(1.+0.033*COS(2.*PI*REAL(IDAY)/365.))

    # calculation of daylength from intermediate variables
    # SINLD, COSLD and AOB
    SINLD = SIN(RAD*LAT)*SIN(DEC)
    COSLD = COS(RAD*LAT)*COS(DEC)
    AOB = SINLD/COSLD

    # For very high latitudes and days in summer and winter a limit is
    # inserted to avoid math errors when daylength reaches 24 hours in
    # summer or 0 hours in winter.

    # Calculate solution for base=0 degrees
    if abs(AOB) <= 1.0:
        DAYL  = 12.0*(1.+2.*ASIN(AOB)/PI)
        # integrals of sine of solar height
        DSINB  = 3600.*(DAYL*SINLD+24.*COSLD*SQRT(1.-AOB**2)/PI)
        DSINBE = 3600.*(DAYL*(SINLD+0.4*(SINLD**2+COSLD**2*0.5))+
                 12.*COSLD*(2.+3.*0.4*SINLD)*SQRT(1.-AOB**2)/PI)
        ANGOT = SC*DSINB
    else:
        if AOB >  1.0:
            DAYL=24.0
            DSINB = 3600.0*(24.0*SINLD)
            DSINBE = 3600.0*(24.0*(SINLD+0.4*(SINLD**2+COSLD**2*0.5)))
            ANGOT = SC*3600.0*(24.0*SINLD)
        elif AOB < -1.0:
            DAYL=0.0
            DSINB = 3600.0*(0.0*SINLD)
            DSINBE = 3600.0*(0.0*(SINLD+0.4*(SINLD**2+COSLD**2*0.5)))
            ANGOT = SC*3600.0*(0.0*SINLD)
        # integrals of sine of solar height

    # Calculate solution for base=-4 (ANGLE) degrees
    AOB_CORR = (-SIN(ANGLE*RAD)+SINLD)/COSLD
    if abs(AOB_CORR) <= 1.0:
        DAYLP = 12.0*(1.+2.*ASIN(AOB_CORR)/PI)
    elif AOB_CORR > 1.0:
        DAYLP = 24.0
    elif AOB_CORR < -1.0:
        DAYLP = 0.0

    # extraterrestrial radiation and atmospheric transmission
    # ANGOT = SC*DSINB
    # Check for DAYL=0 as in that case the angot radiation is 0 as well
    if DAYL > 0.0:
        ATMTR = AVRAD/ANGOT
    else:
        ATMTR = 0.

    # estimate fraction diffuse irradiation
    if (ATMTR > 0.75):
        FRDIF = 0.23
    elif (ATMTR <= 0.75) and (ATMTR > 0.35):
        FRDIF = 1.33-1.46*ATMTR
    elif (ATMTR <= 0.35) and (ATMTR > 0.07):
        FRDIF = 1.-2.3*(ATMTR-0.07)**2
    else:  # ATMTR <= 0.07
        FRDIF = 1.

    DIFPP = FRDIF*ATMTR*0.5*SC

    # Pack return values in namedtuple, add to cache and return
    astro_nt = namedtuple("AstroResults","DAYL, DAYLP, SINLD, COSLD, DIFPP, "
                                         "ATMTR, DSINBE, ANGOT")
    retvalue = astro_nt(DAYL, DAYLP, SINLD, COSLD, DIFPP, ATMTR, DSINBE, ANGOT)
    _cache[(IDAY, LAT, AVRAD)] = retvalue

    return retvalue

def et0_pm_simple(day1,alt,hmes,lat,tmoy,tmin,tmax,vv,hrmoy,hrmin,hrmax,rs):
    """
    Parameters
    ----------
    day1 : date
        DESCRIPTION.
    alt : Altitude
        DESCRIPTION.
    hmes : Hauteurs de la mesure
        DESCRIPTION.
    lat : latitude (43-lam)
        DESCRIPTION.
    tmoy : Tmepérature moyenne
        DESCRIPTION.
    tmin : Température min
        DESCRIPTION.
    tmax : Température max
        DESCRIPTION.
    vv : vitesse du vent (WS)
        DESCRIPTION.
    hrmoy : humidité relative moyenne
        DESCRIPTION.
    hrmin : humidité relative min
        DESCRIPTION.
    hrmax : humidité relative max
        DESCRIPTION.
    rs : rayonnement solaire
        DESCRIPTION.

    Returns
    -------
    None.

    """
    if ((hrmax-hrmin)<.1 or tmin==tmax):
        return(0)
    try:
        conv_rad=lat * pi / 180.
        u2= vv * 4.87 / log(67.8*hmes-5.42) # hmes ?? dans formule u2 = fait intervenir l'altitude
        rs_mj= rs*24*3600*0.000001
        dr= 1+0.033*cos(2*pi*day1/365)
        d= 0.409*sin((2*pi*day1/365)-1.39)
        ws= acos(-tan(conv_rad)*tan(d))
        ra= (24*60/pi)*0.082*dr*(ws*sin(conv_rad)*sin(d)+cos(conv_rad)*cos(d)*sin(ws))
        rso= ra*(0.75+0.00002*alt)
        es= (0.6108*exp(17.27*tmin/(tmin+237.3))+0.6108*exp(17.27*tmax/(tmax+237.3)))/2
        ea= (hrmin*0.6108*exp(17.27*tmax/(tmax+237.3))+hrmax*0.6108*exp(17.27*tmin/(tmin+237.3)))/(2*100)
        rnl= 4.9*pow(10,-9)*0.5*(pow((tmin+273),4)+pow((tmax+273),4))*(0.34-0.14*sqrt(ea))*(1.35*(rs_mj/rso)-0.35)
        rn=(1-0.23)*rs_mj-rnl
        delta= 4098*0.6108*exp(17.27*tmoy /(tmoy +237.3))/pow((tmoy +237.3),2)
        et0= (0.408*delta*(rn)+(900*0.063/(tmoy+273))*u2*(es-ea))/(delta+0.063*(1+0.34*u2))
        return(et0)
    except:
        return(0)

def et0_pm_simple_kelv(day1,alt,hmes,lat,tmoy,tmin,tmax,vv,hrmoy,hrmin,hrmax,rs):
    """

    """
    if ((hrmax-hrmin)<.1 or tmin==tmax):
        return(0)
    try:
        conv_rad=lat * pi / 180.
        u2= vv * 4.87 / log(67.8*hmes-5.42) # hmes ?? dans formule u2 = fait intervenir l'altitude
        rs_mj= rs*24*3600*0.000001
        dr= 1+0.033*cos(2*pi*day1/365)
        d= 0.409*sin((2*pi*day1/365)-1.39)
        ws= acos(-tan(conv_rad)*tan(d))
        ra= (24*60/pi)*0.082*dr*(ws*sin(conv_rad)*sin(d)+cos(conv_rad)*cos(d)*sin(ws))
        rso= ra*(0.75+0.00002*alt)
        es= (0.6108*exp(17.27*tmin-273.3/(tmin))+0.6108*exp(17.27*tmax-273.3/(tmax)))/2
        ea= (hrmax/100*0.6108*exp(17.27*tmin-273.3/(tmin))+hrmin/100*0.6108*exp(17.27*tmax-273.3/(tmax)))/2
        rnl= 4.9*pow(10,-9)*0.5*(pow((tmin),4)+pow((tmax),4))*(0.34-0.14*sqrt(ea))*(1.35*(rs_mj/rso)-0.35)
        rn=(1-0.23)*rs_mj-rnl
        delta= 4098*0.6108*exp(17.27*tmoy-273.3 /(tmoy ))/pow((tmoy ),2)
        et0= (0.408*delta*(rn)+(900*0.063/(tmoy))*u2*(es-ea))/(delta+0.063*(1+0.34*u2))
        return(et0)
    except:
        return(0)

if __name__ == '__main__':
    d={}
    d["path_labo"]="/datalocal/vboxshare/THESE/BESOIN_EAU/"
    d["path_PC"]="D:/THESE_TMP/"
    d["PC_disk"]="H:/Yann_THESE/BESOIN_EAU/BESOIN_EAU/"
    Celsius2Kelvin = lambda x: x + 273.16
    hPa2kPa = lambda x: x/10.
    # Saturated Vapour pressure [kPa] at temperature temp [C]
    SatVapourPressure = lambda temp: 0.6108 * exp((17.27 * temp) / (237.3 + temp))
# =============================================================================
# Validation modelisation ETR
# =============================================================================
    # Prépartion des datas Eddy-co au format journalière
      # Pour 2017 et autre année

    for y in os.listdir(d["PC_disk"]+"/DONNEES_RAW/PARCELLE_LABO/FLUX_ETR/Corr_fluxes/"):
        print(y)
        # LE_lam=pd.read_csv("H:/Yann_THESE/BESOIN_EAU/BESOIN_EAU/DONNEES_RAW/PARCELLE_LABO/FLUX_ETR/Corr_fluxes/"+y,encoding = 'utf-8',delimiter=",")
        LE_lam=pd.read_csv(d["PC_disk"]+"/DONNEES_RAW/PARCELLE_LABO/FLUX_ETR/Corr_fluxes/"+y,encoding = 'utf-8',delimiter=",")
        LE_lam.drop(0,inplace=True)
        LE_lam["time"]=LE_lam["Time"].astype(str)
        LE_lam["LE_Bowen"]=LE_lam["LE Bowen"].astype(float)
        LE_lam["date"]=LE_lam["time"].apply(lambda x:x[0:10])
        LE_lam["time_hours"]=LE_lam["time"].apply(lambda x:x[10:-3]).replace(":",'.')
        LE_lam["date"]=pd.to_datetime(LE_lam["date"],format="%d/%m/%Y")
        LE_lam.drop(columns=["Time"],inplace=True)
        # Suppression des flux nocture
        LE_lam=LE_lam.loc[(LE_lam.time_hours >=' 06:00') & (LE_lam.time_hours <=' 21:00')]
        LE_lam_day=LE_lam.groupby("date")["LE_Bowen"].mean()
        l=54000/2264000
        ETR_lam_day=LE_lam_day*l
        ETR_lam_day[ETR_lam_day < -1]=pd.NaT
        ETR_lam_day=pd.DataFrame(ETR_lam_day)
        # ETR_lam_day.plot()
        # ETR_lam_day["date"]=LE_lam.date
        ETR_lam_day.to_csv(d["PC_disk"]+"/TRAITEMENT/DATA_VALIDATION/DATA_ETR_CESBIO/DATA_ETR_corr_maize_irri/ETR_maize_irri"+str(y[:-4])+".csv")

        #  Flux non corrigées
    for y in os.listdir(d["PC_disk"]+"/DATA_ETR_CESBIO/DATA_LAM_lec_python/"):
        print(y)
        if "eddy" in y:
            years='2019'
            LE_lam=pd.read_csv(d["PC_disk"]+"/DATA_ETR_CESBIO/DATA_LAM_lec_python/"+str(y),encoding = 'utf-8',delimiter=",")
            LE_lam.drop(0,inplace=True)
            LE_lam["time"]=LE_lam["time"].astype(str)
            LE_lam["LE"]=LE_lam["LE"].astype(float)
            LE_lam["date"]=pd.to_datetime(LE_lam["date"],format="%Y-%m-%d")
            # Suppression des flux nocture
            LE_lam=LE_lam.loc[(LE_lam.time >='06:00') & (LE_lam.time <='21:00')]
            LE_lam_day=LE_lam.groupby("date")["LE"].mean()
            # inter=LE_lam_day*46800
            l=54000/2264000
            ETR_lam_day=LE_lam_day*l
            # ETR_lam_day=LE_lam_day*0.0352
            ETR_lam_day[ETR_lam_day < -1]=pd.NaT
            ETR_lam_day=pd.DataFrame(ETR_lam_day)
            # ETR_lam_day["date"]=LE_lam.date
            ETR_lam_day.to_csv(d["PC_disk"]+"/TRAITEMENT/DATA_VALIDATION/DATA_ETR_CESBIO/DATA_ETR_maize_irri/ETR_maize_irri"+str(years)+".csv")

        else:
            years=y[5:9]
            LE_lam=pd.read_csv(d["PC_disk"]+"/DATA_ETR_CESBIO/DATA_LAM_lec_python/"+str(y),encoding = 'utf-8',delimiter=",")
            LE_lam.drop(0,inplace=True)
            LE_lam["time"]=LE_lam["TIMESTAMP"].astype(str)
            LE_lam["LE"]=LE_lam["LE"].astype(float)
            LE_lam["date"]=LE_lam["time"].apply(lambda x:x[0:10])
            LE_lam["time_hours"]=LE_lam["time"].apply(lambda x:x[10:-3]).replace(":",'.')
            LE_lam["date"]=pd.to_datetime(LE_lam["date"],format="%d/%m/%Y")
            LE_lam.drop(columns=["TIMESTAMP"],inplace=True)
            # Suppression des flux nocture
            LE_lam=LE_lam.loc[(LE_lam.time_hours >=' 06:00') & (LE_lam.time_hours <=' 21:00')]
            LE_lam_day=LE_lam.groupby("date")["LE"].mean()
            l=54000/2264000
            ETR_lam_day=LE_lam_day*l
            # ETR_lam_day=LE_lam_day*0.0352
            ETR_lam_day[ETR_lam_day < -1]=pd.NaT
            ETR_lam_day=pd.DataFrame(ETR_lam_day)
            # ETR_lam_day.plot()
            # ETR_lam_day["date"]=LE_lam.date
            ETR_lam_day.to_csv(d["PC_disk"]+"/TRAITEMENT/DATA_VALIDATION/DATA_ETR_CESBIO/DATA_ETR_maize_irri/ETR_maize_irri"+str(years)+".csv")
#
    for y in ["2008","2010","2012","2014","2015","2019"]:
        ETR_lam_day=pd.read_csv(d["PC_disk"]+"/TRAITEMENT/DATA_VALIDATION/DATA_ETR_CESBIO/DATA_ETR_corr_maize_irri/ETR_maize_irri"+str(y)+".csv")
        ETR_lam_day.date=pd.to_datetime(ETR_lam_day.date,format="%Y-%m-%d",)
        LE_lam_nn_corr=pd.read_csv(d["PC_disk"]+"/TRAITEMENT/DATA_VALIDATION/DATA_ETR_CESBIO/DATA_ETR_maize_irri/ETR_maize_irri"+str(y)+".csv",encoding = 'utf-8',delimiter=",")
        LE_lam_nn_corr.date=pd.to_datetime(LE_lam_nn_corr.date,format="%Y-%m-%d")
        LE_nn_corr=LE_lam_nn_corr.loc[(LE_lam_nn_corr.date >=str(y)+"-04-01") & (LE_lam_nn_corr.date <= str(y)+"-09-30")]
        # plt.scatter(ETR_lam_day.LE_Bowen,LE_nn_corr.LE)
        plt.figure(figsize=(7,7))
        plt.plot(ETR_lam_day.date,ETR_lam_day.LE_Bowen,label='LE_Bowen')
        plt.plot(LE_nn_corr.date,LE_nn_corr.LE,label="LE_nn_corr")
        plt.legend()
        plt.title(str(y))
        plt.savefig(d["PC_disk"]+'/RESULT/PLOT/Comparaison_ETR_lam/plot_LE_corr_vsLE_Bowen_dynamique_'+str(y)+'.png')
        plt.figure(figsize=(7,7))
        plt.scatter(LE_nn_corr.LE,ETR_lam_day.LE_Bowen)
        plt.plot([0.0, 14], [0.0, 14], 'r-', lw=2)
        plt.title(str(y))
        plt.ylabel("ETR corrigés")
        plt.xlabel("ETR non corrigés")
        plt.savefig(d["PC_disk"]+'/RESULT/PLOT/Comparaison_ETR_lam/plot_scatter_LE_corr_vsLE_Bowen_dynamique_large_window'+str(y)+'.png')

        # diff=ETR_lam_day.LE_Bowen.to_list()-LE_nn_corr.LE
        # plt.figure(figsize=(7,7))
        # plt.plot(ETR_lam_day.index,diff)
    ##### mesu diff ratio Bowen et LE nn corr

  # Pour la station de Grignon gestion des LE en ETR
#     for y in ["2019"]:
#         print (y)
#         # df=pd.read_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/DONNEES_RAW/DATA_PARCELLE_GRIGNON/RAW_DATA/DATA_ICOS_ECO/EFDC_L2_Flx_FRGri_"+str(y)+"_30m.txt",sep=',')
#         # df["time"]=df["TIMESTAMP_START"].astype(str)
#         # df["date"]=df["time"].apply(lambda x:x[0:8])
#         # df["time_hours"]=df["time"].apply(lambda x:x[8:]).astype(int)
#         df=pd.read_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/DONNEES_RAW/DATA_PARCELLE_GRIGNON/RAW_DATA/DATA_ICOS_ECO/FR-Gri_Flux_2019.csv")
#         df["time"]=df["TIMESTAMP"].astype(str)
#         df["date"]=df["time"].apply(lambda x:x[0:8])
#         df["time_hours"]=df["time"].apply(lambda x:x[8:])
#         df["date"]=pd.to_datetime(df["date"],format="%Y%m%d")
#         df.drop(columns=["TIMESTAMP"],inplace=True)
#         # Suppression des flux nocture
#         df=df.loc[(df.time_hours >='0600.0') & (df.time_hours <='1900.0')]
#         df=df.groupby('date').mean()
#         df["LE"]=df.eval("LE_1_1_1*0.0352")
#         df[df.LE < -1]=np.nan
#         df.drop(columns=['CO2_1_1_1', 'H2O_1_1_1', 'ZL_1_1_1', 'FC_1_1_1', 'FC_SSITC_TEST',
#         'H_1_1_1', 'H_SSITC_TEST', 'LE_1_1_1', 'LE_SSITC_TEST', 'TAU_1_1_1',
#         'TAU_SSITC_TEST', 'MO_LENGTH_1_1_1', 'USTAR_1_1_1', 'U_SIGMA_1_1_1',
#         'V_SIGMA_1_1_1', 'W_SIGMA_1_1_1', 'WS_1_2_1', 'WD_1_2_1', 'SC_1_1_1'],inplace=True)
#         df.LE.plot()
#         df.to_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/DATA_ETR_CESBIO/DATA_ETR_GRIGNON/DATA_ETR_GRIGNON_ICOS/ETR_GRIGNON"+str(y)+".csv")

# #    Pour 2019
#     ETR_lam=pd.read_csv(d["path_labo"]+"/DATA_ETR_CESBIO/DATA_LAM_lec_python/eddypro_FR-Lam_full_output_2020-01-28T012345_adv.csv")
#     ETR_lam["date"]=pd.to_datetime(ETR_lam["date"],format='%Y-%m-%d')
#     ETR_lam=ETR_lam.loc[(ETR_lam.time >='06:00') & (ETR_lam.time <='19:00')]
#     ETR_lam_day=ETR_lam.groupby("date")["LE"].mean()
#     ETR_lam_day=ETR_lam_day*0.0352
#     ETR_lam_day[ETR_lam_day < -1]=pd.NaT
#     ETR_lam_day.plot()
#     ETR_lam_day.to_csv(d["path_labo"]+"/DATA_ETR_CESBIO/DATA_ETR_LAM/ETR_LAM2019.csv")

#     ## Récuparation date végétation sur ETR
# # =============================================================================
# # Pluvio satation mise en forme
# # =============================================================================
# #  # LAM
#     meteo_lam_station=pd.read_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/DATA_ETR_CESBIO/DATA_LE_LAM_original/eddypro_FR-Lam_biomet_2020-01-28T012345_adv_ss_unit.csv")
#     meteo_lam_station=meteo_lam_station.iloc[:-49]
#     Meteo=meteo_lam_station[["date","P_1_1_1"]]
#     Meteo=Meteo.iloc[1:]
#     Meteo["Prec"]=Meteo.P_1_1_1.astype(float)
#     Meteo[Meteo.Prec<=-9998]=np.nan
#     Meteo["Prec"]=Meteo.Prec*1000
#     Meteo_lam=Meteo.groupby("date").sum()
#     Meteo_lam=Meteo_lam.iloc[:-2]
#     Meteo_lam.to_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/TRAITEMENT/INPUT_DATA/DATA_METEO_BV/PARCELLE_LAM/Meteo_station_2019.csv")

#     # PLUVIO_STAT LAM autres anénes
    # for y in ["2006","2008","2010","2012","2014","2015"]:
    #     mat = scipy.io.loadmat('/datalocal/vboxshare/THESE/BESOIN_EAU/DONNEES_RAW/PARCELLE_LABO/DATA_METEO_LAM/LAM_'+y+'_IS.mat')
    #     Plui=pd.DataFrame(mat["Rain"])
    #     Plui["date"]=pd.to_datetime(np.arange(0,Plui.shape[0]), unit='D',origin=pd.Timestamp(str(y)+'-01-01'))
    #     Plui.columns=["Prec",'date']
    #     Plui.to_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/TRAITEMENT/INPUT_DATA/DATA_METEO_BV/PARCELLE_LAM/Meteo_station_"+y+".csv")
    # df=pd.read_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/DONNEES_RAW/PARCELLE_LABO/DATA_METEO_LAM/LAM_MTO_N3_2005-2016_GP.csv",encoding = 'utf-8',sep=',')
    # df["time"]=df["TEMPS"].astype(str)
    # df["date"]=df["time"].apply(lambda x:x[0:10])
    # # df["time_hours"]=df["time"].apply(lambda x:x[10:])
    # df["Date"]=pd.to_datetime(df["date"],format="%j/%m/%Y")
    # for y in ["2006","2008"]:
    #     a=df.loc[(df.Date >=str(y)+str('-01-01')) & (df.Date <= str(y)+str('-12-31'))]
    #     a.groupby("Date").sum()

    #### Rayonement
    # Rn_lam=meteo_lam_station[["date","time","Rn_1_1_1"]].iloc[1:]
    # # Suppression des flux nocture
    # Rn_lam=Rn_lam.loc[(Rn_lam.time >='06:00') & (Rn_lam.time <='19:00')]
    # Rn_lam=Rn_lam.iloc[1:]
    # Rn_lam["ray"]=Rn_lam.Rn_1_1_1.astype(float)
    # Rn_lam[Rn_lam.ray<=-500]=np.nan
    # Rn_lam_jour=Rn_lam.groupby("date").mean()
    ############ ET0 station
    # meteo_lam_station=meteo_lam_station.iloc[1:]
    # meteo_lam_station["date"]=pd.to_datetime(meteo_lam_station["date"],format='%Y-%m-%d')
    # meteo_lam_station=meteo_lam_station.loc[(meteo_lam_station.time >='06:00') & (meteo_lam_station.time <='19:00')]
    # meteo_lam_station.replace("-9999",np.nan,inplace=True)
    # meteo_lam_station['Ta_1_1_1'] = meteo_lam_station['Ta_1_1_1'].astype(float)
    # meteo_lam_station['Rn_1_1_1'] = meteo_lam_station['Rn_1_1_1'].astype(float)
    # meteo_lam_station['Pa_1_1_1'] = meteo_lam_station['Pa_1_1_1'].astype(float)
    # meteo_lam_station['WS_1_1_1'] = meteo_lam_station['WS_1_1_1'].astype(float)
    # meteo_lam_station['RH_1_1_1'] = meteo_lam_station['RH_1_1_1'].astype(float)
    # meteo_lam_station['DOY'] = meteo_lam_station['DOY'].astype(float)
    # meteo_lam_station["doy"]=round(meteo_lam_station.DOY).astype(int)
    # meteo_lam_station.reset_index(inplace=True)
    # Meteo_lam=meteo_lam_station.groupby("date").mean()
    # Meteo_lam["doy"]=round(Meteo_lam.doy).astype(int)
    # ET0_stat=pd.DataFrame()
    # for i in np.arange(2,366):
    #     Tmax=meteo_lam_station.Ta_1_1_1[meteo_lam_station.doy==i].max()
    #     Tmin=meteo_lam_station.Ta_1_1_1[meteo_lam_station.doy==i].min()
    #     Rhmin=meteo_lam_station.RH_1_1_1[meteo_lam_station.doy==i].min()
    #     Rhmax=meteo_lam_station.RH_1_1_1[meteo_lam_station.doy==i].max()
    #     ET0=et0_pm_simple_kelv(Meteo_lam.doy.iloc[i],5,2,43,Meteo_lam.Ta_1_1_1.iloc[i],Tmin,Tmax,Meteo_lam.WS_1_1_1.iloc[i],Meteo_lam.RH_1_1_1.iloc[i],Rhmin,Rhmax,Meteo_lam.Rn_1_1_1.iloc[i])
    #     print("Michel :%s"%ET0)
    #     ET0_stat=ET0_stat.append([ET0])
    # ET0_stat.reset_index(inplace=True)
    #     ET0_p=penman_monteith(meteo_lam_station.doy.iloc[i],43,5,meteo_lam_station.Ta_1_1_1.iloc[i]-273,meteo_lam_station.Ta_1_1_1.iloc[i]-273.15,meteo_lam_station.Rn_1_1_1.iloc[i],meteo_lam_station.Pa_1_1_1.iloc[i],meteo_lam_station.WS_1_1_1.iloc[i])
    #     # ET0_p=penman_monteith(Meteo_lam.doy.iloc[i],43,5,Meteo_lam.Ta_1_1_1.iloc[i]-273,Meteo_lam.Ta_1_1_1.iloc[i]-273.15,Meteo_lam.Rn_1_1_1.iloc[i],Meteo_lam.Pa_1_1_1.iloc[i],Meteo_lam.WS_1_1_1.iloc[i])
    #     # print(Meteo_lam.doy.iloc[i])
    #     # print(ET0_p)
    #     ET0_stat=ET0_stat.append([ET0_p])
    # ET0_stat.reset_index(inplace=True)
    # ET0_stat["date"]=meteo_lam_station.doy
    # ET0_stati_j=ET0_stat.groupby("date").sum()
    # ETO_SAFRAN=pd.read_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/TRAITEMENT/INPUT_DATA/DATA_METEO_BV/PARCELLE_LAM/meteo_lam_2019.csv")
    # ETO_SAFRAN.date=pd.to_datetime(ETO_SAFRAN.date,format="%Y-%m-%d")
    # ETO_SAFRAN.set_index('date',inplace=True)
    # ETO_SAFRAN.reset_index(inplace=True)
    # ETO_SAFRAN.drop(columns=["Unnamed: 0"],inplace=True)

    # ## Plot
    # Rn_lam_jour.index=pd.to_datetime(Rn_lam_jour.index,format="%Y-%m-%d")
    # Meteo_lam.index=pd.to_datetime(Meteo_lam.index,format="%Y-%m-%d")
    # plt.figure(figsize=(12,10))
    # plt.bar(Meteo_lam.iloc[150:250].index,Meteo_lam.Prec.iloc[150:250],width=1)
    # plt.plot(Rn_lam_jour.iloc[150:250].index,Rn_lam_jour.ray.iloc[150:250],color="r")
    # #### Test détection Irrigation recherche #####
    # # Seuil Rn 150
    # a=Meteo_lam.Prec.where((Rn_lam_jour.ray>350)&(Meteo_lam.Prec>10))
    # a.dropna(inplace=True)
# Gri
    # meteo_lam_station=pd.read_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/DONNEES_RAW/DATA_PARCELLE_GRIGNON/RAW_DATA/DATA_ICOS_ECO/FR-Gri_Meteo_2019.csv")
    # Meteo=meteo_lam_station[["TIMESTAMP","P_1_1_1"]]
    # Meteo["time"]=Meteo["TIMESTAMP"].astype(str)
    # Meteo["date"]=Meteo["time"].apply(lambda x:x[0:8])
    # Meteo["date"]=pd.to_datetime(Meteo["date"],format="%Y%m%d")
    # Meteo.drop(columns=["time","TIMESTAMP"],inplace=True)
    # Meteo["Prec"]=Meteo.P_1_1_1.astype(float)
    # Meteo[Meteo.Prec<=-9998]=np.nan
    # Meteo_Gri=Meteo.groupby("date").sum()
    # Meteo_Gri.drop(columns="P_1_1_1",inplace=True)
    # Meteo_Gri.to_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/TRAITEMENT/INPUT_DATA/DATA_METEO_BV/PARCELLE_GRI/Meteo_station_2019.csv")
# =============================================================================
# Fcover_sigmo
# =============================================================================
    # for i in os.listdir("/datalocal/vboxshare/THESE/BESOIN_EAU/TRAITEMENT/INPUT_DATA/FCOVER_parcelle/FCOVER_Raw/Fcover_sigmo/"):
    #     print(i)
    #     Fcover_sig=pd.read_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/TRAITEMENT/INPUT_DATA/FCOVER_parcelle/FCOVER_Raw/Fcover_sigmo/"+i)
    #     Fcov_sigmo=Fcover_sig.T
    #     Fcov_sigmo=Fcov_sigmo.iloc[2:]
    #     date=pd.date_range(start="2019-01-01",end="2019-12-31")
    #     Fcov_sigmo["date"]=date
    #     Fcov_sigmo.columns=["FCOVER","date"]
    #     Fcov_sigmo.to_csv("/datalocal/vboxshare/THESE/BESOIN_EAU/TRAITEMENT/INPUT_DATA/FCOVER_parcelle/FCOVER_sigmo/"+i)
    #     Fcov_sigmo.plot()
# =============================================================================
# Data Laurent Bi
# =============================================================================
    # for file in os.listdir("/run/media/pageot/PROJET_YP/TS_SWC_NDVI_Lonzee_Yann"):
    #     print(file)
    #     if "NDVI" in file:
    #         df=pd.read_csv("/run/media/pageot/PROJET_YP/TS_SWC_NDVI_Lonzee_Yann/"+file,sep=";")
    #     else:
    #         df=pd.read_csv("/run/media/pageot/PROJET_YP/TS_SWC_NDVI_Lonzee_Yann/"+file)
    #     df["time"]=df["Date"].astype(str)
    #     df["date"]=df["time"].apply(lambda x:x[0:8])
    #     df["date"]=pd.to_datetime(df["date"],format="%d/%m/%y")
    #     df.replace("NaN !",np.nan,inplace=True)
    #     if 'TS' in file:
    #         df["Mean_TS_X-1_float"]=df["Mean_TS_X-1"].astype(float)
    #         df.drop(columns=["Mean_TS_X-1"],inplace=True)
    #     elif 'SWC' in file:
    #         df.replace("#DIV/0 !",np.nan,inplace=True)
    #         df["Mean_SWC_X-4_float"]=df["Mean_SWC_X-4"].astype(float)
    #         df.drop(columns=["Mean_SWC_X-4"],inplace=True)
    #     df=df.groupby("date").mean()
    #     print(df.columns)
    #     df.to_csv("/run/media/pageot/PROJET_YP/TS_SWC_NDVI_Lonzee_Yann/modif_V2_%s.csv"%(file[:-4]))


#!/usr/bin/env python
#-*- coding:utf-8 _*-
"""
@author: Selonsy
@file: common.py
@time: 2019-01-09

公用的一些方法

"""

import os
import requests
import click
from utils import glovar
from utils import echo
from utils.customlog import CustomLog

logger = CustomLog(__name__).getLogger()

def get_unique_outfile(outdir, filename):
    ''' 判断文件是否已存在，并返回一个唯一名称 '''
    outfile = os.path.abspath(os.path.join(outdir, filename))
    if os.path.exists(outfile):
        name, ext = filename.rsplit('.', 1)
        names = [x for x in os.listdir(outdir) if x.startswith(name)]
        names = [x.rsplit('.', 1)[0] for x in names]
        suffixes = [x.replace(name, '') for x in names]
        # filter suffixes that match ' (x)' pattern
        suffixes = [x[2:-1] for x in suffixes
                       if x.startswith(' (') and x.endswith(')')]
        indexes  = [int(x) for x in suffixes
                       if set(x) <= set('0123456789')]
        idx = 1
        if indexes:
            idx += sorted(indexes)[-1]
        outfile = os.path.abspath(os.path.join(outdir, '%s (%d).%s' % (name, idx, ext)))
    return outfile

def music_download(music):
    ''' 下载音乐保存到本地 '''
    echo.info(music)
    outfile = get_unique_outfile(glovar.get_option('outdir'), music['name'])
    try:
        r = requests.get(music['url'], stream=True,
                         headers=glovar.WGET_HEADERS,
                         proxies=glovar.get_option('proxies'))
        total_size = int(r.headers['content-length'])
        with click.progressbar(length=total_size, label='Downloading...') as bar:
            with open(outfile, 'wb') as f:
                for chunk in r.iter_content(chunk_size=1024):
                    if chunk:
                        f.write(chunk)
                        bar.update(len(chunk))
        print('已保存到：%s\n' % outfile)
    except Exception as e:
        print('')
        logger.error('下载音乐失败：')
        logger.error('URL：%s' % music['url'])
        logger.error('位置：%s\n' % outfile )
        if glovar.get_option('verbose'):
            logger.error(e)

def url_available(url) -> bool:
    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    r = s.head(url)
    return r.status_code == requests.codes.ok

def content_length(url) -> int:
    s = requests.Session()
    s.headers.update(glovar.FAKE_HEADERS)
    try:
        r = s.head(url)
        if r.status_code == requests.codes.ok:
            return int(r.headers.get('Content-Length', 0))
    except:
        pass
    return 0

def music_list_merge(music_list) -> list:
    ''' 搜索结果合并 '''
    # 先排序
    music_list.sort(key=lambda music: (music['singer'], music['title'], music['size']), reverse=True)
    result_list = []
    for i in range(len(music_list)):
        # 如果名称、歌手都一致的话就去重，保留最大的文件
        if i != 0 \
            and music_list[i]['size'] <= music_list[i-1]['size'] \
            and music_list[i]['title'] == music_list[i-1]['title'] \
            and music_list[i]['singer'] == music_list[i-1]['singer']:
            continue
        result_list.append(music_list[i])

    return result_list


from math import pi
from typing import Union, Optional

import numpy as np
import pandas as pd
from pandas import DatetimeIndex
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.utils.validation import check_is_fitted

from gtime.base import FeatureMixin, add_class_name

__all__ = ["PeriodicSeasonal", "Constant"]

# TODO: add something like 'make_periodic_feature' or 'make_sinusoid'
class PeriodicSeasonal(BaseEstimator, TransformerMixin, FeatureMixin):
    """Create a sinusoid from a given date and with a given period and amplitude.

    Parameters
    ----------
    period : Union[pd.Timedelta, str], optional, default: ``'365 days'``
        The period of the generated time series.

    amplitude : float, optional, default: ``0.5``
        The amplitude of the time series.

    start_date : Union[pd.Timestamp, str], optional, default: ``None``
        The date from which to start generating the feature. This is used only if X is
        not passed in the ``transform`` method, otherwise the start date is inferred
        from it.

    length : int, optional, default: ``50``
        The length of the sinusoid. This is used only if X is not passed in the
        ``transform`` method, otherwise the length is inferred from it.

    index_period : Union[DatetimeIndex, int], optional, default: ``None``
        The period of the index of the output ``DataFrame``. This is used only if X is
        not passed in the ``transform`` method, otherwise the index period is taken
        from it.

    Examples
    --------
    >>> import pandas as pd
    >>> from gtime.feature_generation import PeriodicSeasonal
    >>> X = pd.DataFrame(range(0, 10), index=pd.date_range(start='2019-04-18',  end='2019-04-27', freq='d'))
    >>> periodic = PeriodicSeasonal()
    >>> periodic.fit_transform(X)
                0__PeriodicSeasonal
    2019-04-18             0.000000
    2019-04-19             0.008607
    2019-04-20             0.017211
    2019-04-21             0.025810
    2019-04-22             0.034401
    2019-04-23             0.042982
    2019-04-24             0.051551
    2019-04-25             0.060104
    2019-04-26             0.068639
    2019-04-27             0.077154

    """

    def __init__(
        self,
        period: Union[pd.Timedelta, str] = "365 days",
        amplitude: float = 0.5,
        start_date: Optional[Union[pd.Timestamp, str]] = None,
        length: Optional[int] = 50,
        index_period: Optional[Union[DatetimeIndex, int]] = None,
    ):
        self.start_date = start_date
        self.period = period
        self.amplitude = amplitude
        self.length = length
        self.index_period = index_period

    def fit(self, X: pd.DataFrame, y=None) -> "PeriodicSeasonal":
        """Fit the estimator.

        Parameters
        ----------
        X : pd.DataFrame, shape (n_samples, n_features), required
            Input data.

        y : None
            There is no need of a target in a transformer, yet the pipeline API
            requires this parameter.

        Returns
        -------
        self : PeriodicSeasonal
            Returns self.

        """
        self.columns_ = X.columns.values
        return self

    @add_class_name
    def transform(self, time_series: Optional[pd.DataFrame] = None) -> pd.DataFrame:
        """Generate a sinusoid, with the given ``period``, ``amplitude`` and ``length``,
        starting from the selected ``start_date``. If ``time_series`` is not ``None``,
        the ``start_date`` is replaced by the start date of the time series and the
        output sinusoid will have the same index as ``time_series``.

        Parameters
        ----------
        time_series : pd.DataFrame, shape (n_samples, 1), optional, default: ``None``
            The input DataFrame, If passed, the output DataFrame is going to have the
            same index as ``time_series``. If is not passed, then the ``start_date`` and
            ``index_period`` must have been passed in the constructor when the object
            was instantiated.

        Returns
        -------
        periodic_feature : pd.DataFrame, shape (n_samples, 1)
            The DataFrame containing the generated period feature.

        Raises
        ------
        ValueError
            Raised if ``time_series`` is not passed and the ``start_date`` or the
            ``index_period`` are not present.

        """
        self._validate_input(time_series)
        self._transform_inputs(time_series)
        datetime_index = self._get_time_index(time_series)

        periodic_feature_values = self._compute_periodic_feature(datetime_index)
        if time_series is not None:
            periodic_feature = pd.DataFrame(
                index=time_series.index, data=periodic_feature_values
            )

        else:
            periodic_feature = pd.DataFrame(data=periodic_feature_values[: self.length])

        return periodic_feature

    def _validate_input(self, X: pd.DataFrame) -> None:
        if X is None:
            if self.start_date is None:
                raise ValueError(
                    f"If X is not provided, the 'start_date' variable "
                    f"must be provided, but instead was "
                    f"{self.start_date}."
                )
            if self.index_period is None:
                raise ValueError(
                    f"If X is not provided, the 'index_period' variable "
                    f"must be provided, but instead was "
                    f"{self.index_period}."
                )

    def _transform_inputs(self, X: pd.DataFrame) -> None:
        if isinstance(self.period, str):
            self.period = pd.to_timedelta(self.period)

        if X is not None:
            self.start_date = X.index.values[0]
        else:
            if isinstance(self.start_date, str):
                self.start_date = pd.to_datetime(self.start_date)

    def _get_time_index(self, X: pd.DataFrame) -> pd.DatetimeIndex:
        if X is not None:
            datetime_index = X.index
        else:
            if isinstance(self.index_period, int):
                datetime_index = pd.date_range(
                    start=self.start_date, periods=self.index_period
                )
            else:
                datetime_index = self.index_period

        self._check_sampling_frequency(datetime_index)

        return datetime_index

    def _check_sampling_frequency(self, datetime_index: pd.DatetimeIndex) -> None:
        if isinstance(datetime_index, pd.PeriodIndex):
            datetime_index = datetime_index.to_timestamp()
        sampling_frequency = pd.Timedelta(datetime_index[1] - datetime_index[0])

        if self.period < 2 * sampling_frequency:
            raise ValueError(
                f"Sampling frequency must be at least two times"
                f"the period to obtain meaningful results. "
                f"Sampling frequency = {sampling_frequency},"
                f"period = {self.period}."
            )

    def _compute_periodic_feature(self, datetime_index: pd.DatetimeIndex):
        return (
            np.sin(2 * pi * (datetime_index - self.start_date) / self.period)
        ) * self.amplitude

class Constant(BaseEstimator, TransformerMixin, FeatureMixin):
    """Generate a ``pd.DataFrame`` with one column, of the same length as the input
    ``X`` and containing the value ``constant`` across the whole column.

    Parameters
    ----------
    constant : int, optional, default: ``2``
        The value to use to generate the constant column of the ``pd.DataFrame``.

    length : int, optional, default: ``50``
        The length of the DataFrame to generate. This is used only if X is not passed in
        the ``transform`` method, otherwise the length is inferred from it.

    Examples
    --------
    >>> import pandas as pd
    >>> from gtime.feature_generation import Constant
    >>> X = pd.DataFrame(range(0, 5), index=pd.date_range(start='2019-04-18',  end='2019-04-22', freq='d'))
    >>> constant = Constant(constant=3)
    >>> constant.fit_transform(X)
                0__Constant
    2019-04-18          3.0
    2019-04-19          3.0
    2019-04-20          3.0
    2019-04-21          3.0
    2019-04-22          3.0

    """

    def __init__(self, constant: int = 0, length: int = None):
        super().__init__()
        self.length = length
        self.constant = constant

    def get_feature_names(self):
        """Return feature names for output features.

        Returns
        -------
        output_feature_names : ndarray, shape (n_output_features,)
            Array of feature names.

        """

        return [self.__class__.__name__]

    def fit(self, X: pd.DataFrame, y=None) -> "Constant":
        """Fit the estimator.

        Parameters
        ----------
        X : pd.DataFrame, shape (n_samples, n_features)
            Input data.

        y : None
            There is no need of a target in a transformer, yet the pipeline API
            requires this parameter.

        Returns
        -------
        self : Constant
            Returns self.

        """
        self.columns_ = X.columns.values
        self.rows_ = X.shape[0]
        self.length_ = (
            np.min([self.length, self.rows_]) if self.length is not None else self.rows_
        )
        return self

    @add_class_name
    def transform(self, time_series: Optional[pd.DataFrame] = None) -> pd.DataFrame:
        """Generate a ``pd.DataFrame`` with one column with the same length as
        ``time_series`` and with the same index, containing a value equal to
        ``constant``.

        Parameters
        ----------
        time_series : pd.DataFrame, shape (n_samples, 1), optional, default: ``None``
            The input DataFrame. If passed, the output DataFrame is going to have the
            same index as ``time_series``.

        Returns
        -------
        constant_series_renamed : pd.DataFrame, shape (length, 1)
            A constant series, with the same length of ``X`` and with the same index.

        """
        check_is_fitted(self)

        constants = np.full(self.rows_, np.nan)
        constants[: self.length_] = self.constant
        if time_series is not None:
            constant_series = pd.Series(
                data=constants, index=time_series.index
            ).to_frame()
        else:
            constant_series = pd.Series(data=constants).to_frame()

        return constant_series


"""
    Documentação - https://spacy.io/api/token

    Atributos do objeto token

    text = O texto do token
    head = Qual é o token "pai"
    i = Qual posição o token está
    lemma_ = Token lemmatizado
    lower_ = Token em minusculo
    shape_ = Formato do texto

    like_num = se representa um número
    is_alpha = se é alfanúmerico
    is_digit = se é número
    is_upper = se está em maíusculo
    is_punct = se é um ponto

"""
import spacy

nlp = spacy.load("pt_core_news_sm")

doc = nlp("João pulou o rio sujo dez vezes.")

for token in doc:
    print(token.text, "|", token.i, "|", token.lemma_, "|", token.is_alpha, "|", token.is_punct, "|", token.is_digit, "|", token.like_num)


# -*- coding: utf-8 -*-

from gwadoc.inventories import (
    PROJECTS,
    LANGUAGES,
    RELATIONS,
    PARTS,
    FORMAL_ATTRIBUTES
)
import gwadoc.base

relations = gwadoc.base.Relations(RELATIONS)

def set_preferred_language(lg):
    """
    Set the default language to *lg*.

    The preferred language determines which string is returned when a
    language is not specified. If a field is not defined for the
    preferred language, it backs off to English. For instance:

    >>> print(relations.hypernym.name.en)
    Hypernym
    >>> print(relations.hypernym.name.ja)
    上位語
    >>> print(relations.hypernym.name)
    Hypernym
    >>> gwadoc.set_preferred_language('ja')
    >>> print(relations.hypernym.name)
    上位語
    """
    LANGUAGES[lg]  # check for KeyError
    gwadoc.base.preferred_language = lg

# Import these last to avoid potential import cycles

# import gwadoc.doc_basic to load general and project-level information
import gwadoc.doc_basic
# import language-specific modules to get names, definitions, etc.
import gwadoc.doc_en
import gwadoc.doc_pl
import gwadoc.doc_ja
# add your language module here

### CLEAN UP

import textwrap

def _cleanup(obj, key):
    s = obj.get(key)
    if isinstance(s, str):
        if s.strip() == '':
            obj[key] = ''
        else:
            obj[key] = textwrap.dedent(obj[key].strip('\n'))

for rel_id in RELATIONS:
    rel = relations[rel_id]
    for part in PARTS:
        if part == 'fa':
            for fa in FORMAL_ATTRIBUTES:
                _cleanup(rel[part], fa)
        elif part == 'proj':
            for proj in PROJECTS:
                _cleanup(rel[part], proj)
        else:
            for lg in LANGUAGES:
                _cleanup(rel[part], lg)


from setuptools import setup, find_packages
from codecs import open
from os import path

here = path.abspath(path.dirname(__file__))

with open("README.md", "r") as f:
    long_description = f.read()

setup(
    name='Crow-IRCServer',
    version='1.0.0',
    description='IRC Server implemented in Python via the Twisted framework.',
    url='https://github.com/AWilliams17/Crow-IRCServer/',
    author='Austin Williams',
    author_email='awilliams17412@gmail.com',
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Intended Audience :: Developers',
        'Framework :: Twisted'
        'License :: Freeware'
        'Topic :: Communications :: Chat :: Internet Relay Chat'
        'Programming Language :: Python :: 3.7',
    ],

    keywords='twisted twisted-irc irc-server',
    packages=find_packages(exclude=['tests']),

    install_requires=['twisted, sentryconfig'],

    entry_points={
        'console_scripts': [
            'server=bin.main:main',
        ],
    },

    project_urls={
        'Bug Reports': 'https://github.com/AWilliams17/Crow-IRCServer/issues',
        'Source': 'https://github.com/AWilliams17/Crow-IRCServer/',
    },
)


def applyBoardTexture(board_cards, hand_cards, original_data):
    if board_cards == ['']:
        original_data['BoardPairs'] = []
        original_data['BoardColor'] = []
        original_data['BoardStraight'] = []
        for i in range(len(original_data['Action'])):
            original_data['BoardPairs'].append(0)
            original_data['BoardColor'].append(0)
            original_data['BoardStraight'].append(0)
        return original_data

    cards, suits = extractCardsSuit(board_cards)
    hands_by_situation = [0,0,0,0]
    for situation in original_data['Situation']:
        hands_by_situation[situation] += 1

    color_ranks, color_block = getBoardColors(suits)

    pairs_rank, cards_frequency = getBoardPairs(cards)
    sequence_rank = getBoardSequence(cards)

    original_data['BoardPairs'] = []
    original_data['BoardColor'] = []
    original_data['BoardStraight'] = []
    for i in range(len(original_data['Action'])):
        if original_data['Situation'][i] == 0:
            original_data['BoardPairs'].append(0)
            original_data['BoardColor'].append(0)
            original_data['BoardStraight'].append(0)
        if original_data['Situation'][i] == 1:
            original_data['BoardPairs'].append(pairs_rank['flop'])
            original_data['BoardColor'].append(color_ranks['flop'])
            original_data['BoardStraight'].append(sequence_rank['flop'])
        if original_data['Situation'][i] == 2:
            original_data['BoardPairs'].append(pairs_rank['turn'])
            original_data['BoardColor'].append(color_ranks['turn'])
            original_data['BoardStraight'].append(sequence_rank['turn'])
        if original_data['Situation'][i] == 3:
            original_data['BoardPairs'].append(pairs_rank['river'])
            original_data['BoardColor'].append(color_ranks['river'])
            original_data['BoardStraight'].append(sequence_rank['river'])

    return original_data

def extractCardsSuit(board_cards):
    cards = []
    suits = []
    for i, group in enumerate(board_cards):

        if i == 0:
            cards.append([group[0], group[2], group[4]])
            suits.append([group[1], group[3], group[5]])
        elif i == 1:
            cards.append(group[0])
            suits.append(group[1])
        else:
            cards.append(group[0])
            suits.append(group[1])

    return (cards, suits)

def extractCardValue(card):
    """
    Turn cards in numeric values
    """
    if card == 'A':
        return 14
    elif card == 'K':
        return 13
    elif card == 'Q':
        return 12
    elif card == 'J':
        return 11
    elif card == 'T':
        return 11
    else:
        return int(card)

def getTableCardsValues(cards):
    """
    Get numeric values from table cards
    """
    cards_values = []
    for i, group in cards:
        if i == 0:
            for flopCard in group:
                value = extractCardValue(flopCard)
                cards_values.append(value)
        else:
            value = extractCardValue(group)
            cards_values.append(value)
    return cards_values

def getBoardLength(cards):
    board_length = {}
    for i, card in enumerate(cards):
        if i == 0:
            board_length['flop'] = 0
            for flopCard in card:
                board_length['flop'] += extractCardValue(flopCard)

        if i == 1:
            board_length['turn'] = board_length['flop'] +  extractCardValue(card)

        if i == 2:
            board_length['river'] = board_length['turn'] + extractCardValue(card)

    return board_length

def getBoardColors(suits):
    """
    Rank the board by the suits:
    Flop:
    - 111 = 0
    - 21 = 2
    - 3 = 4
    Turn:
    - 1111 = 0
    - 211 = 1
    - 31 = 3
    - 4 = 6
    River:
    -2111 = 0
    -221 = 0
    -311 = 2
    -32 = 2
    -41 = 5
    -5 = 7

    Returns the rank and the block suit
    """
    suits_cnt = {
                's':0,
                'd':0,
                'h':0,
                'c':0}

    color_ranks = {
            'flop' : 0,
             'turn' : 0,
             'river' : 0}

    color_block = {
                'flop' : '',
                'turn' : '',
                'river' : ''}

    for i, cards in enumerate(suits):
        #FLOP
        if i == 0:
            for suit in cards:
                suits_cnt[suit] += 1
            values = list(suits_cnt.values())
            values.sort(reverse=True)
            if values[0] == 1:
                color_ranks['flop'] = 0
                color_block['flop'] = ''
            elif values[0] == 2:
                color_ranks['flop'] = 2
                color_block['flop'] = list(suits_cnt.keys())[list(suits_cnt.values()).index(2)]
            elif values[0] == 3:
                color_ranks['flop'] = 4
                color_block['flop'] = list(suits_cnt.keys())[list(suits_cnt.values()).index(3)]

        #TURN
        elif i == 1:
            suits_cnt[cards] += 1
            values = list(suits_cnt.values())
            values.sort(reverse=True)
            if values[0] == 1:
                color_ranks['turn'] = 0
                color_block['turn'] = ''
            elif values[0] == 2:
                color_ranks['turn'] = 1
                color_block['turn'] = ''
            elif values[0] == 3:
                color_ranks['turn'] = 3
                color_block['turn'] = list(suits_cnt.keys())[list(suits_cnt.values()).index(3)]
            elif values[0] == 4:
                color_ranks['turn'] = 6
                color_block['turn'] = list(suits_cnt.keys())[list(suits_cnt.values()).index(4)]

        #RIVER
        elif i == 2:
            suits_cnt[cards] += 1
            values = list(suits_cnt.values())
            values.sort(reverse=True)
            if values[0] == 2:
                color_ranks['river'] = 0
            elif values[0] == 3:
                color_ranks['river'] = 2
                color_block['river'] = list(suits_cnt.keys())[list(suits_cnt.values()).index(3)]
            elif values[0] == 4:
                color_ranks['river'] = 5
                color_block['river'] = list(suits_cnt.keys())[list(suits_cnt.values()).index(4)]
            elif values[0] == 5:
                color_ranks['river'] = 7
                color_block['river'] = list(suits_cnt.keys())[list(suits_cnt.values()).index(5)]

    return color_ranks, color_block

def getBoardPairs(board_cards):
    """
    Return pairs strength on hand:
    Flop:
    1 pair = 2
    1 Triple = 4

    Turn:
    1 pair = 1
    1 triple = 3
    2 pairs = 5
    Four = 8

    River:
    1 pair = 1
    1 triple = 3
    2 pairs = 5
    pair+triple = 6
    Four = 8
    """

    #Separating  card frequency by turns
    frequency = { 'flop':{},
                  'turn':{},
                  'river':{}}
    for i, group in enumerate(board_cards):
        if i == 0:
            for flop_card in group:
                if flop_card in frequency['flop']:
                    frequency['flop'][flop_card] += 1
                else:
                    frequency['flop'][flop_card] = 1
        if i == 1:
            frequency['turn'] = frequency['flop']
            if group in frequency['turn']:
                frequency['turn'][group] += 1
            else:
                frequency['turn'][group] = 1

        if i == 2:
            frequency['river'] = frequency['turn']
            if group in frequency['river']:
                frequency['river'][group] += 1
            else:
                frequency['river'][group] = 1

    #Calculating rank and getting the block cards
    #Get the most repetion of the turn and verify by it
    pair_rank = {'flop':0, 'turn':0, 'river':0}
    #FLOP:
    card_frequencys_flop = list(frequency['flop'].values())
    card_frequencys_flop.sort(reverse=True)
    if card_frequencys_flop[0] == 1:
        pair_rank['flop'] = 0
    elif card_frequencys_flop[0] == 2:
        pair_rank['flop'] = 2
    elif card_frequencys_flop[0] == 3:
        pair_rank['flop'] = 4

    if len(board_cards) > 1:
        #TURN:
        card_frequencys_turn = list(frequency['turn'].values())
        card_frequencys_turn.sort(reverse=True)
        if card_frequencys_turn[0] == 1:
            pair_rank['turn'] = 0
        elif card_frequencys_turn[0] == 2:
            #case of two pairs
            if card_frequencys_turn[1] == 2:
                pair_rank['turn'] = 5
            else:
                pair_rank['turn'] = 1
        elif card_frequencys_turn[0] == 3:
            pair_rank['turn'] = 3
        elif card_frequencys_turn[0] == 4:
            pair_rank['turn'] = 8

    if len(board_cards) > 2:
        #RIVER:
        card_frequencys_river = list(frequency['river'].values())
        card_frequencys_river.sort(reverse=True)
        if card_frequencys_river[0] == 1:
            pair_rank['river'] = 0
        elif card_frequencys_river[0] == 2:
            #case of two pairs
            if card_frequencys_river[1] == 2:
                pair_rank['river'] = 5
            else:
                pair_rank['river'] = 1
        elif card_frequencys_river[0] == 3:
            if card_frequencys_river[1] == 2:
                    pair_rank['river'] = 6
            else:
                pair_rank['river'] = 3
        elif card_frequencys_river[0] == 4:
            pair_rank['river'] = 8

    return pair_rank, frequency

def getBoardSequence(board_cards):
    """
    Rank the board by the suits:
    00gap: 100
    0gap+:
        1 80
        2 60
        3.. 50
    1gap+:
        1
        2
        3...

    resto zero
    River:
    -2111 = 0
    -221 = 0
    -311 = 2
    -32 = 2
    -41 = 5
    -5 = 7

    Returns the rank and the block suit
    """
    flop_vector = []
    rank_straight = {'flop':0, 'turn':0, 'river':0}

    for flop_cards in board_cards[0]:
        flop_vector.append(extractCardValue(flop_cards))

    flop_vector.sort()

    #Removing Flop pairs:
    if flop_vector[1] == flop_vector[2]:
        flop_vector.pop(2)

    if flop_vector[0] == flop_vector[1]:
        flop_vector.pop(0)

    #Treating AceDeuce Problem
    ace_flag = False
    deuce_flag = False
    both_flag = False
    if 14 in flop_vector or 2 in flop_vector:
        if 14 in flop_vector and 2 not in flop_vector:
            ace_flag = True
        elif 14 not in flop_vector and 2 in flop_vector:
            deuce_flag = True
        else:
            both_flag = True

    #Getting flop gap scores
    size_flop = len(flop_vector)
    if  size_flop == 1:
        rank_straight['flop'] = 0
    elif size_flop == 2:
        if both_flag:
            rank_straight['flop'] = 50
        else:
            only_gap = flop_vector[1] - flop_vector[0]
            rank_straight['flop'] = getGapScore(only_gap)
    else:
        first_gap = flop_vector[1] - flop_vector[0]
        second_gap = flop_vector[2] - flop_vector[1]
        rank_straight['flop'] = getGapScore(second_gap) + getGapScore(first_gap)
        if both_flag:
            rank_straight['flop'] += 50

    if len(board_cards) > 1:
        #Verifying Turn pairs
        turn_value = extractCardValue(board_cards[1])

        #Setting Turn rank
        turn_vector = flop_vector
        if turn_value in flop_vector:
            rank_straight['turn'] = rank_straight['flop']
        else:
            turn_vector.append(turn_value)
            turn_vector.sort()
            size_turn = len(turn_vector)
            if size_turn == 2:
                only_gap = turn_vector[1] - turn_vector[0]
                rank_straight['turn'] = getGapScore(only_gap)

            elif size_turn == 3:
                first_gap = turn_vector[1] - turn_vector[0]
                second_gap = turn_vector[2] - turn_vector[1]
                rank_straight['turn'] = getGapScore(second_gap) + getGapScore(first_gap)

            elif size_turn == 4:
                first_gap = turn_vector[1] - turn_vector[0]
                second_gap = turn_vector[2] - turn_vector[1]
                third_gap = turn_vector[3] - turn_vector[2]
                rank_straight['turn'] = getGapScore(third_gap) + getGapScore(second_gap) + getGapScore(first_gap)

            #New ace with deuce in turn treat
            if turn_value == 14 and deuce_flag and not both_flag:
                rank_straight['turn'] += 50
            elif turn_value == 2 and deuce_flag and not both_flag:
                rank_straight['turn'] += 50

            #New Ace or Deuce in Turn treat
            if turn_value == 14 and not ace_flag:
                ace_flag = True
                if deuce_flag:
                    both_flag = True
            elif turn_value == 2 and not deuce_flag:
                deuce_flag = True
                if ace_flag:
                    both_flag = True

    if len(board_cards) > 2:
        #Verifying river pairs
        river_value = extractCardValue(board_cards[2])

        #Setting river rank
        river_vector = turn_vector
        if river_value in turn_vector:
            rank_straight['river'] = rank_straight['turn']
        else:
            river_vector.append(river_value)
            river_vector.sort()
            size_river = len(river_vector)
            if size_river == 2:
                only_gap = river_vector[1] - river_vector[0]
                rank_straight['river'] = getGapScore(only_gap)

            elif size_river == 3:
                first_gap = river_vector[1] - river_vector[0]
                second_gap = river_vector[2] - river_vector[1]
                rank_straight['river'] = getGapScore(second_gap) + getGapScore(first_gap)

            elif size_river == 4:
                first_gap = river_vector[1] - river_vector[0]
                second_gap = river_vector[2] - river_vector[1]
                third_gap = river_vector[3] - river_vector[2]
                rank_straight['river'] = getGapScore(third_gap) + getGapScore(second_gap) + getGapScore(first_gap)

            elif size_river == 5:
                first_gap = river_vector[1] - river_vector[0]
                second_gap = river_vector[2] - river_vector[1]
                third_gap = river_vector[3] - river_vector[2]
                forth_gap = river_vector[4] - river_vector[3]
                rank_straight['river'] = getGapScore(forth_gap) + getGapScore(third_gap) + getGapScore(second_gap) + getGapScore(first_gap)

            #New ace with deuce in river treat
            if river_value == 14 and deuce_flag and not both_flag:
                rank_straight['river'] += 50
            elif river_value == 2 and deuce_flag and not both_flag:
                rank_straight['river'] += 50

    return rank_straight

def getGapScore(gap):
    if gap == 1:
        return 50
    if gap == 2:
        return 30
    if gap == 3:
        return 10
    if gap >= 4:
        return 0


from collections import deque

'''2. Написать программу сложения и умножения двух шестнадцатеричных чисел. При этом каждое число представляется как
массив, элементы которого — цифры числа. Например, пользователь ввёл A2 и C4F. Нужно сохранить их как [‘A’,
‘2’] и [‘C’, ‘4’, ‘F’] соответственно. Сумма чисел из примера: [‘C’, ‘F’, ‘1’], произведение - [‘7’, ‘C’, ‘9’, ‘F’,
‘E’]. '''

# декодер
# чтобы получить числовое выражение - .index(str)
# чтобы получить строковой литерал - обращаемся по индексу числового выражения
decoder = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F']
base = 16

def _sum(x, y):
    result = deque()
    higher_order_num = 0  # остаток, который идёт в разряд выше

    if len(x) > len(y):
        x, y = deque(x), deque(y)
    else:
        x, y = deque(y), deque(x)

    while x:
        if y:
            current = decoder.index(x.pop()) + decoder.index(y.pop()) + higher_order_num
        else:
            current = decoder.index(x.pop()) + higher_order_num

        higher_order_num = 0  # сбрасываем остаток, здесь он больше не нужен

        if current < base:
            result.appendleft(decoder[current])
        else:
            result.appendleft(decoder[current - base])
            higher_order_num = 1

    if higher_order_num:
        result.appendleft('1')

    return list(result)

def _mul(x, y):
    result = deque()
    higher_order_num = 0
    spam = deque(deque() for _ in range(len(y)))

    y = deque(y)

    for i in range(len(y)):
        n = decoder.index(y.pop())

        for j in x[::-1]:
            k = decoder.index(j)
            spam[i].appendleft(n * k)

        for _ in range(i):
            spam[i].append(0)  # когда мы умножали столбиком, сдвигали элементы суммирования

    for _ in range(len(spam[-1])):
        res = higher_order_num

        for k in spam:
            if k:
                res += k.pop()

        if res < base:
            result.appendleft(decoder[res])
        else:
            result.appendleft(decoder[res % base])
            higher_order_num = res // base

    if higher_order_num:
        result.appendleft(decoder[higher_order_num])

    return list(result)

a = list(input('Введите первое число: ').upper())
b = list(input('Введите второе число: ').upper())

print(_sum(a, b), 'sum')
print(_mul(a, b), 'multiply')