import os
import re
import pytest
import pandas as pd
from os.path import join
from battetl.extract import Extractor
from battetl import Constants

BASE_DATA_PATH = os.path.join(os.path.dirname(__file__), 'data')
MACCOR_PATH = os.path.join(BASE_DATA_PATH, 'maccor_cycler_data')
MACCOR_SIMPLE_PATH = os.path.join(MACCOR_PATH, 'simple_data')
MACCOR_FRA_PATH = os.path.join(MACCOR_PATH, 'fra_data')
MACCOR_FASTWAVE_PATH = os.path.join(MACCOR_PATH, 'fastwave_data')
MACCOR_TYPE2_PATH = os.path.join(MACCOR_PATH, 'type2_data')
ARBIN_PATH = os.path.join(BASE_DATA_PATH, 'arbin_cycler_data')
ARBIN_SINGLE_PATH = os.path.join(ARBIN_PATH, 'single_data_file')
ARBIN_MULTIPLE_PATH = os.path.join(ARBIN_PATH, 'multiple_data_files')
ARBIN_CAN_PATH = os.path.join(ARBIN_PATH, 'can_data_files')
ARBIN_SIMULATION_PATH = os.path.join(ARBIN_PATH, 'simulation_data_files')

@pytest.mark.extract
def test_bad_path():
    path = join(
        BASE_DATA_PATH,
        'fake/data/path - 079.txt',
    )

    extractor = Extractor()

    with pytest.raises(TypeError):
        df_extracted = extractor.data_from_files(path)

@pytest.mark.extract
@pytest.mark.maccor
def test_extract_maccor_test_data():
    path = join(MACCOR_SIMPLE_PATH, 'BG_Maccor_Testdata - 079.txt')

    extractor = Extractor()
    extractor.data_from_files([path])
    df_extracted = extractor.raw_test_data

    df_loaded = pd.read_csv(
        path,
        sep='\t',
        header=2,
        skipinitialspace=True,
        index_col=False
    )

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'maccor')

@pytest.mark.extract
@pytest.mark.maccor
def test_extract_maccor_test_data_type2():
    path = join(MACCOR_TYPE2_PATH, 'BG_Maccor_Type2 - 075.txt')

    extractor = Extractor()
    extractor.data_from_files([path])
    df_extracted = extractor.raw_test_data

    df_loaded = pd.read_csv(
        path,
        sep='\t',
        header=3,
        skipinitialspace=True,
        index_col=False
    )

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'maccor')

@pytest.mark.extract
@pytest.mark.maccor
def test_extract_maccor_stats_data():
    path = join(MACCOR_SIMPLE_PATH, 'BG_Maccor_TestData - 079 [STATS].txt')

    extractor = Extractor()
    extractor.data_from_files([path])
    df_extracted = extractor.raw_cycle_stats

    df_loaded = pd.read_csv(
        path, sep='\t',
        skiprows=8,
        skipinitialspace=True,
        index_col=False)

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'maccor')

@pytest.mark.extract
@pytest.mark.maccor
def test_extract_maccor_stats_data_pickle():
    path_pkl = join(MACCOR_SIMPLE_PATH, 'BG_Maccor_TestData - 079.pkl')
    path_txt = join(MACCOR_SIMPLE_PATH, 'BG_Maccor_Testdata - 079.txt')

    extractor = Extractor()
    df_extracted = extractor.from_pickle(path_pkl)

    df_loaded = pd.read_csv(
        path_txt,
        sep='\t',
        header=2,
        skipinitialspace=True,
        index_col=False)

    assert (df_extracted.equals(df_loaded))

@pytest.mark.extract
@pytest.mark.arbin
def test_extract_arbin_single_data_file():
    path = join(ARBIN_SINGLE_PATH,
                'BG_Arbin_TestData_Single_File_Channel_26_Wb_1.CSV')

    extractor = Extractor()
    extractor.data_from_files([path])
    df_extracted = extractor.raw_test_data

    df_loaded = pd.read_csv(path, index_col=False)

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'arbin')

@pytest.mark.extract
@pytest.mark.arbin
def test_extract_arbin_multiple_data_files():
    paths = [
        join(ARBIN_MULTIPLE_PATH,
             'BG_Arbin_TestData_Multiple_Files_Channel_16_Wb_1.CSV'),
        join(ARBIN_MULTIPLE_PATH,
             'BG_Arbin_TestData_Multiple_Files_Channel_16_Wb_2.CSV'),
        join(ARBIN_MULTIPLE_PATH,
             'BG_Arbin_TestData_Multiple_Files_Channel_16_Wb_3.CSV'),
        join(ARBIN_MULTIPLE_PATH,
             'BG_Arbin_TestData_Multiple_Files_Channel_16_Wb_4.CSV')
    ]

    extractor = Extractor()
    extractor.data_from_files(paths)
    df_extracted = extractor.raw_test_data

    df_1 = pd.read_csv(paths[0], index_col=False)
    df_2 = pd.read_csv(paths[1], index_col=False)
    df_3 = pd.read_csv(paths[2], index_col=False)
    df_4 = pd.read_csv(paths[3], index_col=False)
    df_loaded = pd.concat([df_1, df_2, df_3, df_4], ignore_index=True)

    assert (df_extracted.equals(df_loaded))
    assert (extractor.cycler_make == 'arbin')

@pytest.mark.extract
@pytest.mark.arbin
def test_extract_arbin_globalinfo():
    path = join(ARBIN_SINGLE_PATH,
                'BG_Arbin_TestData_Single_File_Channel_26_GlobalInfo.CSV')

    extractor = Extractor()
    extractor.data_from_files([path])

    assert (
        extractor.raw_test_data_meta_data[0] == {
            'Test Name': 'BG_Characterization_25R_Cell_2',
            'Export Time': '06/01/2022 14:47:10',
            'Serial Number': '213079',
            'Channel': '26',
            'Start DateTime': '05/22/2022 12:42:59',
            'Schedule File Name': 'BG\\BG_25R_Characterization+BG_25R.sdx',
            'Creator': 'admin',
            'Comments': '',
            'Software Version': 'Mits8 PV Build: 202110',
            'Schedule Version': 'Schedule Version 8.00.11',
            'MASS(g)': '0',
            'Specific Capacity(Ah/g)': '0',
            'Capacity(Ah)': '2.5',
            'BarCode': '',
            'Has Aux': '512',
            'Has Specail': '0',
            'Log Aux Data Flag': 'True',
            'Log Special Flag': 'False'
        }
    )

@pytest.mark.extract
@pytest.mark.maccor
@pytest.mark.schedules
def test_extract_maccor_simple_procedure():
    procedure_file_name = 'BG_Maccor_Schedule.000'
    path = join(MACCOR_SIMPLE_PATH, procedure_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([path])
    assert (extractor.schedule['file_name'] == path)
    procedure_extracted = extractor.schedule['schedule']

    assert (extractor.cycler_make == Constants.MAKE_MACCOR)

    schedule_check_dict = {
        'step_types': ['Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'AdvCycle', 'Dischrge', 'Rest', 'Charge', 'Rest',
                       'End'],
        'chg_steps': [2, 7, 12, 17, 22, 27, 32, 37],
        'dsg_steps': [5, 10, 15, 20, 25, 30, 35],
        "rest_steps": [1, 3, 6, 8, 11, 13, 16, 18, 21, 23, 26, 28, 31, 33, 36, 38]
    }

    # Check that all step types are correctly defined
    for i, step_type in enumerate(schedule_check_dict['step_types']):
        assert (procedure_extracted['MaccorProcedure']['ProcSteps']
                ['TestStep'][i]['StepType'] == step_type)

    assert (extractor.schedule['steps']['chg']
            == schedule_check_dict['chg_steps'])
    assert (extractor.schedule['steps']['dsg']
            == schedule_check_dict['dsg_steps'])
    assert (extractor.schedule['steps']['rst']
            == schedule_check_dict['rest_steps'])

@pytest.mark.extract
@pytest.mark.maccor
@pytest.mark.schedules
def test_extract_maccor_fra_files():
    procedure_file_name = 'BG_EIS.000'
    fra_file_1 = 'BG_EIS_5mV_BaselineCycle.FRA'
    fra_file_2 = 'BG_EIS_10mV_Pot_DQ1.FRA'
    procedure_path = join(MACCOR_FRA_PATH, procedure_file_name)
    fra_path_1 = join(MACCOR_FRA_PATH, fra_file_1)
    fra_path_2 = join(MACCOR_FRA_PATH, fra_file_2)

    extractor = Extractor()
    extractor.schedule_from_files([procedure_path, fra_path_1, fra_path_2])
    assert (extractor.schedule['file_name'] == procedure_path)
    schedule_extracted = extractor.schedule['schedule']

    fra_dict_1 = schedule_extracted['fra_files'][0][fra_file_1]
    fra_dict_2 = schedule_extracted['fra_files'][1][fra_file_2]

    # Check a sample of values.
    assert (fra_dict_1['General']['fratype'] == '3')
    assert (fra_dict_1['Setup']['range'] == '200 mA')
    assert (fra_dict_1['Sweep']['endfreq'] == '.001')

    assert (fra_dict_2['General']['fratype'] == '3')
    assert (fra_dict_2['Setup']['range'] == '200 mA')
    assert (fra_dict_2['Sweep']['endfreq'] == '1')

@pytest.mark.extract
@pytest.mark.maccor
@pytest.mark.schedules
def test_extract_maccor_fastwave_files():
    procedure_file_name = 'BG_ProfileCycling_MP_CVP_MBC2.000'
    fastwave_file_1 = 'MP_CVP_MBC2.MWF'
    fastwave_file_2 = 'other.MWF'
    procedure_path = join(MACCOR_FASTWAVE_PATH, procedure_file_name)
    fastwave_path_1 = join(MACCOR_FASTWAVE_PATH, fastwave_file_1)
    fastwave_path_2 = join(MACCOR_FASTWAVE_PATH, fastwave_file_2)

    extractor = Extractor()
    extractor.schedule_from_files(
        [procedure_path, fastwave_path_1, fastwave_path_2])
    assert (extractor.schedule['file_name'] == procedure_path)
    schedule_extracted = extractor.schedule['schedule']

    fastwave_string_1 = schedule_extracted['fastwave_files'][0][fastwave_file_1]
    fastwave_string_2 = schedule_extracted['fastwave_files'][1][fastwave_file_2]

    # Check the first and last lines
    assert (re.split('\n', fastwave_string_1)[
            0] == 'C\tI\t6.749\tV\t4.2\t1\tV\t>=\t4.2\tT\t1\tA')
    assert (re.split('\n', fastwave_string_1)
            [-1] == 'C\tI\t1.858\tV\t4.2\t3600\tI\t<=\t0.15\tT\t1\tA')

    assert (re.split('\n', fastwave_string_2)[
            0] == 'C\tI\t6.555\tV\t4.2\t1\tV\t>=\t4.2\tT\t1\tA')
    assert (re.split('\n', fastwave_string_2)
            [-1] == 'C\tI\t1.858\tV\t4.2\t3600\tI\t<=\t0.16\tT\t1\tA')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_simple_schedule():
    schedule_file_name = 'BG_25R_Characterization+BG_25R.sdx'
    path = join(ARBIN_SINGLE_PATH, schedule_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([path])
    assert (extractor.schedule['file_name'] == path)
    schedule_extracted = extractor.schedule['schedule']

    schedule_check_dict = {
        'step_types': ['Rest', 'Internal Resistance', 'Current(A)', 'Rest'
                       'Set Variable(s)', 'Internal Resistance', 'Current(A)', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Internal Resistance', 'CCCV', 'Rest', 'Current(A)', 'Rest',
                       'Set Variable(s)', 'Current(A)', 'Rest'],
        "chg_steps": [7, 13, 19, 25, 31, 37, 43, 48],
        "dsg_steps": [3, 9, 15, 21, 27, 33, 39, 45],
        "rest_steps": [1, 4, 8, 10, 14, 16, 20, 22, 26, 28, 32, 34, 38, 40, 44, 46, 49]
    }

    # Check that all step types were correctly loaded.
    steps = {key: val for key, val in schedule_extracted['ArbinSchedule']['Schedule'].items()
             if key.startswith('step')}
    for i, step in enumerate(steps):
        assert (steps[step]['m_szStepCtrlType'] ==
                schedule_check_dict['step_types'][i])

    assert (extractor.schedule['steps']['chg']
            == schedule_check_dict['chg_steps'])
    assert (extractor.schedule['steps']['dsg']
            == schedule_check_dict['dsg_steps'])
    assert (extractor.schedule['steps']['rst']
            == schedule_check_dict['rest_steps'])

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_object_file():
    schedule_file_name = 'BG_25R_Characterization+BG_25R.sdx'
    object_file_name = 'BG_25R.to'
    schedule_path = join(ARBIN_SINGLE_PATH, schedule_file_name)
    object_path = join(ARBIN_SINGLE_PATH, object_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, object_path])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    object_dict = schedule_extracted['object_file'][object_file_name]['Content']

    assert (object_dict['m_bautocalcncapacity'] == '0')
    assert (object_dict['m_fmass'] == '0')
    assert (object_dict['m_fmaxcurrentcharge'] == '10')
    assert (object_dict['m_fmaxvoltagecharge'] == '4.2')
    assert (object_dict['m_fminvoltagecharge'] == '2.5')
    assert (object_dict['m_fnorminalcapacitor'] == '0')
    assert (object_dict['m_fnorminalcapacity'] == '2.5')
    assert (object_dict['m_fnorminalir'] == '0')
    assert (object_dict['m_fnorminalvoltage'] == '0')
    assert (object_dict['m_fspecificcapacity'] == '0')
    assert (object_dict['ser'] == '508182206')
    assert (object_dict['ver'] == '27265537')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_can_bms_file():
    schedule_file_name = 'BG_MBC_Cycling_ZN_TEST+BG_ATL-GC-SDC-2854A6-020H+model_control_channel_29.sdx'
    can_file_name = 'model_control_channel_29.can'
    schedule_path = join(ARBIN_CAN_PATH, schedule_file_name)
    can_path = join(ARBIN_CAN_PATH, can_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, can_path])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    can_dict = schedule_extracted['can_bms_file'][can_file_name]['CANConfig']

    # Just spot check a few because the file is big
    assert (can_dict['Creator'] == 'admin')
    assert (can_dict['CANBaudRate'] == '2')
    assert (can_dict['DataEntryItemList']['DataEntryItem']
            [0]['VariableName'] == 'CAN_MV_RX1')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_can_formula_file():
    schedule_file_name = 'BG_MBC_Cycling_ZN_TEST+BG_ATL-GC-SDC-2854A6-020H+model_control_channel_29.sdx'
    can_fm_file_name = 'model_control_channel_29.fm'
    schedule_path = join(ARBIN_CAN_PATH, schedule_file_name)
    formula_path = join(ARBIN_CAN_PATH, can_fm_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, formula_path])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    can_fm_dict = schedule_extracted['can_formula_file'][can_fm_file_name]

    # Just spot check a few because the file is big
    assert (can_fm_dict['CAN_AuxDataMaxRow']['datamaxrow'] == '0')
    assert (can_fm_dict['BaudRate']['baudrate'] == '2')
    assert (can_fm_dict['CAN_Formalu1']['lableformalu'] == 'F_A')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_mapping_file():
    schedule_file_name = 'BG_MBC_Cycling_ZN_TEST+BG_ATL-GC-SDC-2854A6-020H+model_control_channel_29.sdx'
    batch_file_name = 'ArbinSys.bth'
    schedule_path = join(ARBIN_CAN_PATH, schedule_file_name)
    batch_path = join(ARBIN_CAN_PATH, batch_file_name)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, batch_path])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    batch_dict = schedule_extracted['mapping_file'][batch_file_name]

    # Just spot check a few because the file is big
    assert (batch_dict['Version Section']
            ['current_version'] == 'Map Version 8.00.02')
    assert (batch_dict['Batch_Test29']['m_uglobalcanbmschanidx'] == '-1')
    assert (batch_dict['Batch']['m_szcreator'] == 'admin')

@pytest.mark.extract
@pytest.mark.arbin
@pytest.mark.schedules
def test_extract_arbin_simulation_files():
    schedule_file_name = 'BG_MBC_eta0p025_25R+BG_25R.sdx'
    sim_file_1 = 'MWT_MBC_eta0p025.txt'
    sim_file_2 = 'sim_file_2.txt'
    schedule_path = join(ARBIN_SIMULATION_PATH, schedule_file_name)
    sim_path_1 = join(ARBIN_SIMULATION_PATH, sim_file_1)
    sim_path_2 = join(ARBIN_SIMULATION_PATH, sim_file_2)

    extractor = Extractor()
    extractor.schedule_from_files([schedule_path, sim_path_1, sim_path_2])
    assert (extractor.schedule['file_name'] == schedule_path)
    schedule_extracted = extractor.schedule['schedule']

    sim_string_1 = schedule_extracted['simulation_files'][0][sim_file_1]
    sim_string_2 = schedule_extracted['simulation_files'][1][sim_file_2]

    # Check the first and last lines in the simulation files
    assert (re.split('\n', sim_string_1)[0] == '1\t7.5')
    assert (re.split('\n', sim_string_1)[-1] == '2059\t0.1')

    assert (re.split('\n', sim_string_2)[0] == '1\t8.5')
    assert (re.split('\n', sim_string_2)[-1] == '2059\t0.2')


import numpy as np
import scipy.io
import scipy.signal
from scipy.linalg import toeplitz
import matplotlib.pyplot as plt

# Filtrado Wiener:

print("Condicionamiento")

A = np.array([[2, 4, 5], [6, 9, 8], [4, 5, 3]])
b = np.array([[220], [490], [274]])

print(A)
print(b)

# vamos a hacerlo de una con la libreria (El numero de condicionamiento):
cond_A = np.linalg.cond(A)
print("El numero de condicionamiento de A es: " + str(cond_A))

# LA ECUACION QUE ESTOS PENSANDO ES:
# A * x = b ===> ¿Se podra?

# Veamos algunas caracteristicas de A

det_A = np.linalg.det(A)
print("Determinante de A:" + str(det_A))

# Lo podemos calcular a mano:

U, S, V = np.linalg.svd(A)
c1 = max(S) / min(np.abs(S))
print("Numero de condicionamiento a mano: " + str(c1))

# podemos hacerlo con los autovalores:

avals_A = np.linalg.eigvals(A)
print("Autovalores: ", avals_A)
c2 = max(avals_A) / min(np.abs(avals_A))
print("El numero de condicionamiento por autovalores: ", c2)
# Esto ultimo fue una aproximacion,

# Calculamos la inversa:

A_inv = np.linalg.inv(A)
x = A_inv.dot(b)
print(x)  # rresultado

# El condicionamiento indica como esta distribuida la energia
# en un sistema

# En el analisis vamos a despejar "b" y asegurar que R este condicionada

# La ecuacion tiene esta forma => R * b = r_xy

# Nos tiene que quedar: b = inv(r)*rxy

def wiener_hopf(x, d, maxlags):  # x:entrada  d:deseada  maxlags:cantidad de retrasos
    rxx = plt.acorr(x, maxlags=maxlags)[1]  # nos vamos a quedar con el segundo parametro
    rxx = rxx[maxlags:-1]  # nos vamos a quedar con el final
    R = toeplitz(rxx)

    rxy = plt.xcorr(x, d, maxlags=maxlags)[1]  # vector con las correlaciones cruzadas
    rxy = rxy[maxlags:-1]

    R_inv = scipy.linalg.inv(R)
    b = R_inv.dot(rxy)

    return b

def sig_noise(f_in, SNR, N):
    fs = 1000
    Ts = 1 / fs

    time = np.arange(0, N) * Ts
    noise = np.random.randn(1, N)

    RMS_noise = np.sqrt(np.mean(noise ** 2))
    t = f_in * np.arange(0, N) * 2 * np.pi / fs
    SNR_n = 10 ** (SNR / 20)
    A = SNR_n * RMS_noise + 1.414
    x = A * np.sin(t)
    x_noise = x + noise

    return x_noise[0], time, x

t_end = 2
fs = 1000
N = t_end * fs
L = 256
SNR = -8
frec = 2

x_noise, t, x = sig_noise(frec, SNR, N)

plt.plot(t, x_noise)
plt.plot(t, x)
plt.show()

b = wiener_hopf(x_noise, x, L)  # Max lags es el orden del filtro
plt.show()

filtrada = scipy.signal.lfilter(b, 1, x_noise)
plt.plot(t, filtrada)
plt.plot(t, x)
plt.show()
plt.xlabel("Time [s]")

print("\n")
print("Filtro Adaptativo!!")

# Tiene un feedback que ayuda a mejorar la salida
# tenemos que usar el gradiente para encontrar el
# camino mas cercano a cero!

# Los coeficientes del filtro van a cambiar y se actualizan
# en forma recursiva con un Delta (Saltos) ===> que vamos a buscar
# para que los pesos sean optimos

# CONFIGURACIONES

# ANC ==> CANCELAR RUIDO (EEG y oculograma) Tengo que aprender cual es el ruido y de esta forma eliminarlo

# ALE ==> Disminuir el ruido en ciertas frecuencias (Como el ruido de linea)

# Esto es tode con analisis estadistico

# INPUT = señal con ruido ==> x[n] + noise[n]
# Canal de referencia = Ruido[n] ==> mediciones en otras partes del cuerpo (ojos, corazon, etc)

# Porque no puedo restar el input al canal de referencia?
# Lo que pasa es que lo que esta en el canal de referencia no es el ruido total

# lo que hace el filtro es aprender la relacion que existe entre las señales

# Armanos la funcion:

# Atencion al DELTA, porque vamos tener que buscar este valor para tener el mejor resultado posible.

def lms(entrada, deseada, L,delta):  # L ==> orden, ir modificando en valor de Delta para obtener el mejor valor posible

    # ERROR CUADRATICO MEDICO

    # La salida es:
    # y = b * x
    # e = deseado - y
    # b = b[-1] + delta * e * x

    # LMS significa error cuadratico medio
    # least mean squares
    # Quiero eliminar el ruido lPM
    M = entrada.shape[0]
    b = np.zeros([1, L])
    y = np.zeros([1, M])
    e = np.zeros([1, M])

    for i in range(L, M):  # tengo que recorrer la señal
        x1 = entrada[i: i - L: -1]  # empiezo desde atras
        # al principio va a ser como la comun y despues va a ir mejorando
        y[0, i] = b.dot(x1)
        e[0, i] = deseada[i] - y[0, i]
        b = b + delta * e[0, i] * x1
    return b  # en este caso con que devuelva b es suficiente porque estamos buscando la optimizacion

t_end = 5
fs = 1000
N = t_end * fs
L = 256
SNR = -8

x_noise, time, x = sig_noise(2, SNR, N)

# LMS     ====>   a las 5 de la tarde!

# 0 < delta < (1/10*L*px)
a = 0.05  # que tanto pesa lo que aprendi para hacer cada iteracion ! ==> Vamos modificando
px = np.mean(x_noise ** 2)
delta = a * (1 / (10 * L * px))

b = lms(x_noise, x, L, delta)

filtrada = scipy.signal.filtfilt(b[0], 1, x_noise)  # filfilt saca el desfazaje

plt.plot(time, filtrada)
plt.plot(time, x)
plt.show()
plt.xlabel("Tiempo [s]")


import asyncio
from typing import AsyncIterator

class OppoStreamIterator:
  def __init__(self, reader: asyncio.StreamReader):
    self._reader = reader

  def __aiter__(self):
    return self

  async def __anext__(self):
    val = await self._reader.readuntil(b'\r')
    if val == b'':
      raise StopAsyncIteration
    return val

async def CancellableAsyncIterator(async_iterator: AsyncIterator, cancellation_event: asyncio.Event) -> AsyncIterator:
  cancellation_task = asyncio.create_task(cancellation_event.wait())
  result_iter = async_iterator.__aiter__()
  while not cancellation_event.is_set():
    done, pending = await asyncio.wait(
      [cancellation_task, asyncio.create_task(result_iter.__anext__())],
      return_when=asyncio.FIRST_COMPLETED
    )
    for done_task in done:
      if done_task == cancellation_task:
        for pending_task in pending:
          await pending_task
        break
      else:
        yield done_task.result()


import datetime
from django.db.models import Q
from django.shortcuts import redirect, render
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator,EmptyPage
from django.contrib import messages
from django.urls import reverse_lazy
from applicants.models import Applications, Interviews
from base.models import Jobs
from users.models import ApplicantProfile
from django.contrib.auth.views import PasswordChangeView
from django.contrib.messages.views import SuccessMessageMixin

class AppPasswordChangeView(SuccessMessageMixin,PasswordChangeView):
   template_name = 'applicant/applicant_password_change.html'
   success_message = "Password Changed"
   success_url = reverse_lazy('applicant-password-change')

# list view of jobs

def jobs(request):
         today = datetime.date.today()
         jobs = Jobs.objects.filter(withdraw_date__gte=today).order_by('-posted_on')
         if request.method == "POST":
            value = request.POST['search_jobs']
            jobs = Jobs.objects.filter(Q (job_title__icontains=value) | Q(location__icontains = value)).filter(withdraw_date__gte=today).order_by('-posted_on')
         count = jobs.count()

         if count == 0:
            messages.info(request, f'No results found')
            return render(request, 'applicant/jobview.html')

         else:

            p = Paginator(jobs,5)  # second argument is no of items to be displayed
            page_num = request.GET.get('page',1 ) #get the page no by url  and 1 is default
            try:
               page = p.page(page_num)
            except EmptyPage:
               page = p.page(1)
            return render(request, 'applicant/jobview.html',{'jobs': page})

# detailed view of jobs

def job_detail(request, job_id):
    job_id = Jobs.objects.get(id=job_id)
    context = { 'job_id':job_id }
    return render(request,'applicant/jobdetail.html',context)

def applied_details(request, job_id):
    job_id = Jobs.objects.get(id=job_id)
    context = { 'job_id':job_id }
    return render(request,'applicant/applied_details.html',context)

@login_required
def apply_confirmation(request,job_id):
   profile = ApplicantProfile.objects.filter(user=request.user)
   if profile:
         job = Jobs.objects.get(id=job_id)
         return render(request, "applicant/apply_confirmation.html",{'job':job })
   else:
         return redirect('filterlogin')

@login_required
def apply_now(request,job_id):

         application = Applications()
         job = Jobs.objects.get(pk=job_id)  #select the Jobs instance using job id
         profile = ApplicantProfile.objects.get(user=request.user) #select the appliant profile for setting last applied

      # this checks last job apply of the user
         if profile.last_apply is not None:
            diff = datetime.date.today() - profile.last_apply
            diff = diff.days                                   #convert the date field to days
         else:
            diff = 90

         if diff >= 90:
            application.user = request.user
            application.job = job   #save the foreign key using the selected instance
            application.save()
            profile.last_apply = datetime.date.today()  #changes the last apply date to current date in applicant profile
            profile.save()
            applied = Applications.objects.filter(user=request.user).order_by('-applied_date')
            messages.success(request, f'Your application has been submitted successfully')
            return render(request, 'applicant/applied.html',{'applied':applied})
         else:
            messages.warning(request, f'You can only apply for a new job after {90-diff} days')
            return redirect('jobs')

@login_required
def save_applicant_profile(request):
   profile = ApplicantProfile.objects.filter(user = request.user).count() #check if profile for user exists or not
   if profile:
      applicant = ApplicantProfile.objects.get(user = request.user)
   if request.method == "POST":
         addressline1 = request.POST['addressline1']
         place = request.POST['place']
         city = request.POST['city']
         state = request.POST['state']
         mobile = request.POST['mobile']
         pin = request.POST['pin']
         dob = request.POST['dob']
         gender = request.POST['gender']
         if request.FILES:
            cv = request.FILES['cv']
            if cv.size > 2000000:
               messages.warning(request, f'File size should be less than 2 mb')
               if profile:
                 return render(request, "applicant/fillprofile.html",{'applicant':applicant})
               else:
                 return render(request, 'applicant/fillprofile.html')

         if len(mobile)!=10:
            messages.warning(request, f'Phone number must be 10 digits')
            if profile:
               return render(request, "applicant/fillprofile.html",{'applicant':applicant})
            else:
               return render(request, 'applicant/fillprofile.html')
         elif len(pin) != 6:
            messages.warning(request, f'Postcode must be 6 digits')
            if profile:
               return render(request, "applicant/fillprofile.html",{'applicant':applicant})
            else:
               return render(request, 'applicant/fillprofile.html')
         else:
            if not profile:
               applicant = ApplicantProfile()
               applicant.user = request.user

            applicant.addressline1 = addressline1
            applicant.place = place
            applicant.city = city
            applicant.state = state
            applicant.phone = mobile
            applicant.pin = pin
            applicant.dob = dob
            applicant.gender = gender
            if request.FILES:
               applicant.cv = cv
            applicant.save()
            return redirect('filterlogin')
   else:
      if profile:
         applicant = ApplicantProfile.objects.get(user = request.user)
         return render(request, "applicant/fillprofile.html",{'applicant':applicant})
      else:
         return render(request, 'applicant/fillprofile.html')

@login_required
def view_applicant_profile(request):
   profile = ApplicantProfile.objects.filter(user = request.user).count()
   if profile:
      applicant = ApplicantProfile.objects.get(user = request.user)
      return render(request, "applicant/viewprofile.html",{'applicant':applicant})
   else:
      return redirect('filterlogin')

@login_required
def applied(request):
   applied = Applications.objects.filter(user=request.user).order_by('-applied_date')
   if applied:
      return render(request, "applicant/applied.html",{'applied':applied})
   else:
      messages.warning(request, f"You haven't applied for any jobs")
      return render(request, "applicant/applied.html")

@login_required
def interviews(request):
   applications = Applications.objects.filter(user = request.user,selected = 'accepted')
   interviews = Interviews.objects.filter()
   context = {
      'applications':applications,
      'interviews':interviews
   }
   return render(request, "applicant/interviews.html",context)


import torch
from torch import  nn
from easydict import  EasyDict
import yaml
config = './configs/train_res.yml'
config = load_config(config)

def load_config(path):
    with open(path, 'r') as f:
        return EasyDict(yaml.safe_load(f))

def get_optimizer(cfg, model):
    if cfg.type == 'adam':
        return torch.optim.Adam(
            model.parameters(),
            lr=cfg.lr,
            weight_decay=cfg.weight_decay,
            betas=(cfg.beta1, cfg.beta2, )
        )
    else:
        raise NotImplementedError('Optimizer not supported: %s' % cfg.type)

def get_scheduler(cfg, optimizer):
    if cfg.type == 'plateau':
        return torch.optim.lr_scheduler.ReduceLROnPlateau(
            optimizer,
            factor=cfg.factor,
            patience=cfg.patience,
            min_lr=cfg.min_lr
        )
    else:
        raise NotImplementedError('Scheduler not supported: %s' % cfg.type)

model = nn.Linear(12,24)
optimizer = get_optimizer(config.train.optimizer, model)
scheduler = get_scheduler(config.train.scheduler, optimizer)


import numpy as np
from collections import Counter

# множество ребер
edges = set()
with open('teapot.obj', 'r') as f:
    for line in f:
        if 'f' in line:
            a = line.split()
            # попарно добавляем вершины из граней в множество ребер, добавляя в пару сначала вершину с меньшим индексом,
            # чтобы сет убрал повторяющиеся ребра
            edges.add((min(a[1], a[2]), max(a[1], a[2])))
            edges.add((min(a[2], a[3]), max(a[2], a[3])))
            edges.add((min(a[1], a[3]), max(a[1], a[3])))

with open('teapot.obj', 'r') as f:
    L = f.readlines()
    edges_sum = 0
    for e in edges:
        v1_index = int(e[0]) - 1
        v2_index = int(e[1]) - 1
        # переходим к строке с нужным индексом
        v1 = L[v1_index]
        v2 = L[v2_index]

        v1 = v1.split()
        v2 = v2.split()

        del v1[0]
        del v2[0]

        v1 = [float(i) for i in v1]
        v2 = [float(i) for i in v2]
        edges_sum += np.sqrt(np.power((v2[0] - v1[0]), 2) + np.power((v2[1] - v1[1]), 2) + np.power((v2[2] - v1[2]), 2))
print('Суммарная длина всех ребер: ' + str(edges_sum))

# список из индексов вершин
vertexes_index = list()
with open('teapot.obj', 'r') as f:
    for line in f:
        if 'f' in line:
            b = line.split()
            del b[0]
            b = [int(i) for i in b]
            vertexes_index.append(b[0])
            vertexes_index.append(b[1])
            vertexes_index.append(b[2])

counts = Counter(vertexes_index)
# макс число граней
max_count = counts.most_common(1)[0][1]
out = [value for value, count in counts.most_common() if count == max_count]

print('Вершины, принадлежащие максимальному количеству граней: ' + str(out))
print('Количество граней: ' + str(max_count))
# через L обращение к строке по индексу со сдвигом -1
vert1 = L[out[0] - 1]
vert2 = L[out[1] - 1]
print('Координаты первой вершины: ' + vert1)
print('Координаты второй вершины: ' + vert2)


import argparse
import struct
import json
import fileinput

def unpack(packet):
    attempts, unverified, verified = struct.unpack(
        "<HHH", bytearray.fromhex(packet[0:12])
    )
    return [
        {
            "attempts": attempts,
            "unverified": unverified,
            "verified": verified,
        }
    ]

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Unpack hexadecimal data from rx_packet example",
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    )
    parser.add_argument(
        "-x", "--hex", type=str, default="-", help="RxStats in hexadecimal format"
    )
    args = parser.parse_args()

    try:
        if args.hex == "-":
            for line in fileinput.input():
                try:
                    print(json.dumps(unpack(line.strip())))
                except Exception as e:
                    print(line.strip(), e)
        else:
            print(json.dumps(unpack(args.hex)))
    except KeyboardInterrupt as e:
        exit(e)
    except Exception as e:
        exit(e)


import logging
import random
import sys
import time

import pytest

@pytest.fixture
def clear_cached_vault():
    from robocorp import vault

    vault._get_vault.cache_clear()
    yield
    vault._get_vault.cache_clear()

def test_vault_api(monkeypatch, datadir, clear_cached_vault):
    from robocorp import vault

    monkeypatch.setenv("RC_VAULT_SECRET_MANAGER", "FileSecrets")
    monkeypatch.setenv("RC_VAULT_SECRETS_FILE", str(datadir / "secrets.json"))

    secret_container = vault.get_secret("windows")
    secret_container[10] = 10

    # Key types are always converted to str internally.
    assert 10 in secret_container
    assert "10" in secret_container
    assert secret_container[10] == 10

    vault.set_secret(secret_container)
    vault._get_vault.cache_clear()

    secret_container = vault.get_secret("windows")
    assert 10 in secret_container
    assert "10" in secret_container
    assert secret_container[10] == 10

    vault.create_secret(
        "generated",
        {"a-key": "a-value"},
        description="Some sort of secret",
    )

    secret_container = vault.get_secret("generated")
    assert secret_container.name == "generated"
    assert len(secret_container) == 1
    assert secret_container["a-key"] == "a-value"

    with pytest.raises(vault.RobocorpVaultError):
        vault.create_secret("generated", {})

    vault.create_secret("generated", {"a-key": "another-value"}, exist_ok=True)
    secret_container = vault.get_secret("generated")
    assert secret_container["a-key"] == "another-value"

@pytest.fixture
def log_to_stderr():
    handler = logging.StreamHandler(stream=sys.stderr)
    handler.setLevel(logging.ERROR)  # logging.DEBUG would actually print the token...
    logger = logging.getLogger()
    logger.addHandler(handler)
    logger.setLevel(logging.DEBUG)
    yield
    logger.removeHandler(handler)

def test_vault_integrated(
    monkeypatch, clear_cached_vault, ci_credentials, rcc, log_to_stderr
):
    monkeypatch.delenv("RC_VAULT_SECRET_MANAGER", None)
    monkeypatch.delenv("RC_VAULT_SECRETS_FILE", None)

    result = rcc.add_credentials(ci_credentials)
    assert result.success
    assert rcc.credentials_valid()

    result = rcc.cloud_list_workspaces()
    assert result.success

    workspaces = result.result
    if not workspaces:
        raise AssertionError("Expected to have CI Workspace available.")
    workspaces = [ws for ws in workspaces if ws.workspace_name == "CI workspace"]
    if not workspaces:
        raise AssertionError("Expected to have CI Workspace available.")

    ws = workspaces[0]

    action_result_authorize = rcc.cloud_authorize_token(ws.workspace_id)

    assert len(action_result_authorize.result["token"]) > 10
    assert len(action_result_authorize.result["endpoint"]) > 10

    from robocorp import vault

    monkeypatch.setenv("RC_API_SECRET_HOST", action_result_authorize.result["endpoint"])
    monkeypatch.setenv("RC_API_SECRET_TOKEN", action_result_authorize.result["token"])
    monkeypatch.setenv("RC_WORKSPACE_ID", ws.workspace_id)
    secret_container = vault.get_secret("ROBOCORP_VAULT_TEST")

    assert "VAULT_KEY1" in secret_container
    assert "vault_key2" in secret_container
    for i in range(3):
        new_value = secret_container["vault_key3"] = str(time.time())
        vault.set_secret(secret_container)

        vault._get_vault.cache_clear()
        found = vault.get_secret("ROBOCORP_VAULT_TEST")["vault_key3"]

        # This is more complicated because when running in the ci we have a test
        # on linux/window/mac os at the same time and a single resource (the vault)
        # so, if we don't have the same value wait a bit and retry.
        if found == new_value:
            break
        if i == 2:
            # Fail in the last attempt.
            assert found == new_value
        else:
            # Sleep up to 3 seconds before retrying.
            time.sleep(random.random() * 3)


from config import config
from flask import Flask
from flask_cors import CORS, cross_origin

# Routes
from routes.auth import Auth
from routes.subject import Subject
from routes.user import User
from routes.Advice import Advice

app = Flask(__name__)
app.config['CORS_HEADERS'] = ['Content-Type']
CORS(app)
cors = CORS(app, resources={r"*": {"origins": "*"}})

UPLOADED_FOLDER = 'static/files/'

app.config['UPLOADED_FOLDER'] = UPLOADED_FOLDER

def page_not_found(error):
    return "<h1>Not found page </h1>", 404

@app.route('/')
def index():
    return 'Health up'

# Routes
app.register_blueprint(Auth.main, url_prefix='/auth')
app.register_blueprint(Subject.main, url_prefix='/subject')
app.register_blueprint(User.main, url_prefix='/user')
app.register_blueprint(Advice.main, url_prefix='/advice')

# Errors
app.register_error_handler(404, page_not_found)

if __name__ == '__main__':
    app.config.from_object(config['development'])

    app.run(host = 'localhost', debug = True)


from typing import List
class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        if sum(gas)<sum(cost): return -1
        start_station=0
        idx=0
        tank=0
        while start_station<len(gas)-1:
            tank=tank+gas[idx]-cost[idx]
            if tank>=0:
                idx+=1
                if idx==len(gas):
                    idx=0
                if start_station==idx:
                    break
            else:
                tank=0
                idx+=1
                start_station=idx
        return start_station if tank>=0 else -1
s=Solution()
gas =  [5,1,2,3,4]
cost = [4,4,1,5,1]
print(s.canCompleteCircuit(gas,cost))


import dash
import dash.dcc as dcc
import dash.html as html
from dash.dependencies import Input, Output, State

from model import *
from figure_creation import *

# Create initial objects
CogCtrl = None
LingKnow = None
Stroop = None

# Define the app layout
app = dash.Dash(__name__)
server = app.server

app.layout = html.Div([
    html.H1("Cognitive Control Simulation Dashboard"),
    html.Div([
        html.H3("Parameters"),
        html.Label("For an explanation, Hover over a parameter's name"),
        html.Br(),
        html.Label("Represetations Decay Rate  ", title="The number of activation units lost every iteration, from each Stroop/LanguageKnowledge node"),
        dcc.Input(id='decay-rate', type='number', value=0.01),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Cognitive Control Decay Rate  ", title="The number of activation units lost every iteration, from each Cognitive Control node)"),
        dcc.Input(id='control-decay-rate', type='number', value=0.001),
        html.Br(),
        html.Label("Activation Rate  ", title="The relation between unit activation and the activation it exerts through excitatory connections"),
        dcc.Input(id='activation-rate', type='number', value=0.1),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Monitoring to Biasing Activation Rate  ", title='The relation between the activation of Conflict Monitoring and the activation it exerts to the Biasing Unit (a value of 1 models a case in which Monitoring is "inside" Biasing)'),
        dcc.Input(id='monitor-bias-activation-rate', type='number', value=0.1),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Inhibition Rate  ", title="The relation between unit activation and the inhibition it exerts through inhibitory connections"),
        dcc.Input(id='inhibition-rate', type='number', value=0.01),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Biasing Multiplier  ", title="The relation between Biasing unit activation level and how strongly it activates Stroop/LanguageKnowledge high-level nodes in proportion to their activation levels"),
        dcc.Input(id='biasing-mult', type='number', value=0.000005),
        html.Br(),
        html.Label("Activation Threshold  ", title='When a lower-level unit\'s activation level reaches this threshold, it "wins" and is cosidered the final interpratation'),
        dcc.Input(id='activation-threshold', type='number', value=1000),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Maximum Iterations  ", title="Maximum number of iterations per trial. If reached, the lower-level unit with highest activation level is cosidered the final interpratation"),
        dcc.Input(id='max-iter', type='number', value=5000),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Between Trials Interval  ", title="Time (in seconds) between consecutive trials"),
        dcc.Input(id='between-trials-interval', type='number', value=1.5),
    ]),
    html.Div([html.Br(),
        html.Label("Input Activations:", title= "Input activations for each trial type (order: WK,MSK_ing,MSK_ed,Text_blue,Text_red,FontColor)"),
        html.Br(),
        html.Label("Congruent Stroop  ", title= "Input activations (order: WK,MSK_ing,MSK_ed,Text_blue,Text_red,FontColor). For a congruent Stroop, activation of FontColor that supports Blue & Text_blue that supports Blue"),
        dcc.Input(id='input-congruent-stroop', type='text', value='0,0,0,10,0,15'),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Incongruent Stroop  ", title= "Input activations (order: WK,MSK_ing,MSK_ed,Text_blue,Text_red,FontColor). For an Incongruent Stroop, activation of FontColor that supports Blue & Text_red that supports red "),
        dcc.Input(id='input-incongruent-stroop', type='text', value='0,0,0,0,10,15'),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Congruent Sentence  ", title= "Input activations (order: WK,MSK_ing,MSK_ed,Text_blue,Text_red,FontColor). For a Congruent Sentence, activation of WorldKnowledge that supports SubjIsTheme & MorphosyntacticKnowledge_ed that supports SubjIsTheme"),
        dcc.Input(id='input-congruent-sentence', type='text', value='15,0,10,0,0,0'),
        html.Span(style={'margin-right': '40px'}),
        html.Label("Anomalous Sentence  ", title= "Input activations (order: WK,MSK_ing,MSK_ed,Text_blue,Text_red,FontColor). For an Anomalous Sentence, activation of WorldKnowledge that supports SubjIsTheme & MorphosyntacticKnowledge_ing that supports SubjIsAgent"),
        dcc.Input(id='input-anomalous-sentence', type='text', value='15,10,0,0,0,0'),
    ]),
    html.Div([html.Br(),
        html.Button('Run Simulations', id='run-button', n_clicks=0),
    ]),
    html.Div([
        html.H3("Simulation Results"),
        html.Div([dcc.Graph(id='stroop-w\wo-CC-graph')],
                 style={'width': '50%', 'display': 'inline-block'}),
        html.Div([dcc.Graph(id='language-w\wo-CC-graph')],
                 style={'width': '50%', 'display': 'inline-block'}),
        html.Div(dcc.Graph(id='cross-task-adaptation-graph'),
                 style={'width': '50%', 'margin': '0 auto'}),
        html.Label("Activation plots - Congruent sentence:"),
        html.Br(),
        html.Div([dcc.Graph(id='activations-cong-bias-graph')],
                 style={'width': '33%', 'display': 'inline-block'}),
        html.Div([dcc.Graph(id='activations-cong-agent-graph')],
                 style={'width': '33%', 'display': 'inline-block'}),
        html.Div([dcc.Graph(id='activations-cong-theme-graph')],
                 style={'width': '33%', 'display': 'inline-block'}),
        html.Label("Activation plots - Incongruent sentence:"),
        html.Br(),
        html.Div([dcc.Graph(id='activations-incong-bias-graph')],
                 style={'width': '33%', 'display': 'inline-block'}),
        html.Div([dcc.Graph(id='activations-incong-agent-graph')],
                 style={'width': '33%', 'display': 'inline-block'}),
        html.Div([dcc.Graph(id='activations-incong-theme-graph')],
                 style={'width': '33%', 'display': 'inline-block'}),
    ])
])

# Define callback functions
@app.callback(
    [Output('stroop-w\wo-CC-graph', 'figure'),
     Output('language-w\wo-CC-graph', 'figure'),
     Output('cross-task-adaptation-graph', 'figure'),
     Output('activations-cong-bias-graph', 'figure'),
     Output('activations-cong-agent-graph', 'figure'),
     Output('activations-cong-theme-graph', 'figure'),
     Output('activations-incong-bias-graph', 'figure'),
     Output('activations-incong-agent-graph', 'figure'),
     Output('activations-incong-theme-graph', 'figure')],
    [Input('run-button', 'n_clicks')],
    [State('decay-rate', 'value'),
     State('control-decay-rate', 'value'),
     State('activation-rate', 'value'),
     State('monitor-bias-activation-rate', 'value'),
     State('inhibition-rate', 'value'),
     State('biasing-mult', 'value'),
     State('max-iter', 'value'),
     State('activation-threshold', 'value'),
     State('between-trials-interval', 'value'),
     State('input-congruent-stroop', 'value'),
     State('input-incongruent-stroop', 'value'),
     State('input-congruent-sentence', 'value'),
     State('input-anomalous-sentence', 'value')])
def run_simulation(n_clicks, decay_rate_input, control_decay_rate_input, activation_rate_input, monitor_bias_activation_rate_input, inhibition_rate_input, biasing_mult_input,
                   max_iter_input, activation_threshold_input, between_trials_interval_input,
                   congruent_stroop_input, incongruent_stroop_input, congruent_sentence_input, anomalous_sentence_input):

    congruent_stroop_input = tuple(map(int,congruent_stroop_input.split(',')))
    incongruent_stroop_input = tuple(map(int,incongruent_stroop_input.split(',')))
    congruent_sentence_input = tuple(map(int,congruent_sentence_input.split(',')))
    anomalous_sentence_input = tuple(map(int,anomalous_sentence_input.split(',')))

    global represetations_decay_rate, cognitive_control_decay_rate, activation_rate, monitor_bias_activation_rate, inhibition_rate, biasing_mult, max_iter, activation_threshold, between_trials_interval, congruent_stroop, incongruent_stroop, congruent_sentence, anomalous_sentence
    represetations_decay_rate, cognitive_control_decay_rate, activation_rate, monitor_bias_activation_rate, inhibition_rate, biasing_mult, max_iter, activation_threshold, between_trials_interval, congruent_stroop, incongruent_stroop, congruent_sentence, anomalous_sentence = decay_rate_input, control_decay_rate_input, activation_rate_input, monitor_bias_activation_rate_input ,inhibition_rate_input, biasing_mult_input, max_iter_input, activation_threshold_input, between_trials_interval_input, congruent_stroop_input, incongruent_stroop_input, congruent_sentence_input, anomalous_sentence_input
    params = (represetations_decay_rate, cognitive_control_decay_rate, activation_rate, monitor_bias_activation_rate, inhibition_rate, biasing_mult, max_iter, activation_threshold, between_trials_interval, congruent_stroop, incongruent_stroop, congruent_sentence, anomalous_sentence)
    iteration_graph = create_fig_with_withoutCC_stroop(params)
    accuracy_graph,act_cong_bias_graph,act_cong_agent_graph,act_cong_theme_graph,act_incong_bias_graph,act_incong_agent_graph,act_incong_theme_graph = create_fig_with_withoutCC_lang(params)
    reaction_time_graph = create_fig_crosstask_adapt(params)
    return iteration_graph, accuracy_graph, reaction_time_graph, act_cong_bias_graph,act_cong_agent_graph,act_cong_theme_graph,act_incong_bias_graph,act_incong_agent_graph,act_incong_theme_graph

if __name__ == '__main__':
    app.run_server(debug=True)


# coding: utf-8

import os
import unittest
from selenium import webdriver

class PythonMarketSearch(unittest.TestCase):
    """We make 2 tests for yandex.market products"""

    def setUp(self):
        """Initialization of driver."""
        self.driver = webdriver.Chrome('{}\chromedriver'.format(os.getcwd()))
        self.driver.maximize_window()
        self.driver.get('https://yandex.ru')

    def click_to_hidden(self, title):
        """Control of click to hidden element"""
        element = self.driver.find_element_by_xpath('//*[@class="topmenu__subwrap"]')
        self.driver.execute_script('arguments[0].style.display="block"', element)
        self.driver.find_element_by_xpath('//a[contains(text(), "{}")]'.format(title)).click()

    def submit_form(self, inputs, checkboxes, btn):
        """Submit form with passed parameters"""
        for key, value in inputs.items():
            input_ = self.driver.find_element_by_xpath(key)
            input_.send_keys(value)

        for checkbox in checkboxes:
            self.driver.find_element_by_xpath(checkbox).click()

        self.driver.find_element_by_xpath(btn).click()

    def make_click(self, xpath):
        """Control of click to element by xpath"""

        self.driver.find_element_by_xpath(xpath).click()

    def test_search_in_yandex_market(self):
        """
        Test case 1: we go to Market page and try to get information
        about TVs filtered by price
        """
        driver = self.driver

        self.make_click('//a[@data-id="market"]')
        self.click_to_hidden('Телевизоры')
        self.make_click('//a[contains(text(), "Расширенный поиск")]')

        self.submit_form(
            {'//input[@id="gf-pricefrom-var"]': 20000},
            ('//input[@id="gf-1801946-1871075"]', '//input[@id="gf-1801946-1871447"]'),
            '//button[contains(./span/text(), "Применить")]'
        )

        goods = driver.find_elements_by_xpath(
            '//div[contains(@class, "snippet-card ") and @data-id]//h3'
        )

        if len(goods) == 10:
            first_product = goods[0].text

            self.submit_form(
                {'//input[@id="header-search"]': first_product},
                (),
                '//button[contains(./span/text(), "Найти")]'
            )

            title = driver.find_element_by_xpath('//h1[contains(@class, "title")]').text
            self.assertEqual(first_product, title)

    def test_search_in_yandex_market2(self):
        """
        Test case 1: we go to Market page and try to get information
        about headsets filtered by price
        """

        driver = self.driver

        self.make_click('//a[@data-id="market"]')
        self.click_to_hidden('Плееры')
        self.make_click('//a[text()="Наушники"]')
        self.make_click('//a[contains(text(), "Расширенный поиск")]')

        self.submit_form(
            {'//input[@id="gf-pricefrom-var"]': 5000},
            ('//input[@id="gf-1801946-8455647"]',),
            '//button[contains(./span/text(), "Применить")]'
        )

        goods = driver.find_elements_by_xpath(
            '//div[contains(@class, "snippet-card ") and @data-id]//h3'
        )

        if len(goods) == 10:
            first_product = goods[0].text

            self.submit_form(
                {'//input[@id="header-search"]': first_product},
                (),
                '//button[contains(./span/text(), "Найти")]'
            )

            title = driver.find_element_by_xpath('//h1[contains(@class, "title")]').text
            self.assertEqual(first_product, title)

    def tearDown(self):
        self.driver.close()

if __name__ == "__main__":
    unittest.main()


"""
=================================================
VB coordinate descent for Mixture of Multinomials
=================================================

"""
import bnpy
import numpy as np
import os

from matplotlib import pylab
import seaborn as sns

FIG_SIZE = (3, 3)
SMALL_FIG_SIZE = (1,1)
pylab.rcParams['figure.figsize'] = FIG_SIZE

top_word_kws = dict(
    wordSizeLimit=15,
    ncols=4,
    Ktop=10)

###############################################################################
# Read text dataset from file

dataset_path = os.path.join(bnpy.DATASET_PATH, 'we8there', 'raw')
dataset = bnpy.data.BagOfWordsData.read_npz(
    os.path.join(dataset_path, 'dataset.npz'),
    vocabfile=os.path.join(dataset_path, 'x_csc_colnames.txt'))

# Filter out documents with less than 20 words
doc_ids = np.flatnonzero(
    dataset.getDocTypeCountMatrix().sum(axis=1) >= 20)
dataset = dataset.make_subset(docMask=doc_ids, doTrackFullSize=False)

###############################################################################
#
# Make a simple plot of the raw data
bnpy.viz.PrintTopics.plotCompsFromWordCounts(
    dataset.getDocTypeCountMatrix()[:10],
    vocabList=dataset.vocabList,
    prefix='doc',
    **top_word_kws)

###############################################################################
#
# Train with K=1 cluster
# ----------------------
#
# This is a simple baseline.

trained_model, info_dict = bnpy.run(
    dataset, 'DPMixtureModel', 'Mult', 'VB',
    output_path='/tmp/we8there/helloworld-model=dp_mix+mult-K=1/',
    nLap=1000, convergeThr=0.0001, nTask=1,
    K=1, initname='bregmankmeans+lam1+iter1',
    gamma0=50.0, lam=0.1)

bnpy.viz.PrintTopics.plotCompsFromHModel(
    trained_model,
    vocabList=dataset.vocabList,
    **top_word_kws)

###############################################################################
#
# Train with K=3 clusters
# -----------------------
#
# Take the best of 10 initializations

trained_model, info_dict = bnpy.run(
    dataset, 'DPMixtureModel', 'Mult', 'VB',
    output_path='/tmp/we8there/helloworld-model=dp_mix+mult-K=3/',
    nLap=1000, convergeThr=0.0001, nTask=10,
    K=3, initname='bregmankmeans+lam1+iter1',
    gamma0=50.0, lam=0.1)

bnpy.viz.PrintTopics.plotCompsFromHModel(
    trained_model,
    vocabList=dataset.vocabList,
    **top_word_kws)

###############################################################################
#
# Train with K=10 clusters
# ------------------------
#
# Take the best of 10 initializations

trained_model, info_dict = bnpy.run(
    dataset, 'DPMixtureModel', 'Mult', 'VB',
    output_path='/tmp/we8there/helloworld-model=dp_mix+mult-K=10/',
    nLap=1000, convergeThr=0.0001, nTask=10,
    K=10, initname='bregmankmeans+lam1+iter1',
    gamma0=50.0, lam=0.1)

bnpy.viz.PrintTopics.plotCompsFromHModel(
    trained_model,
    vocabList=dataset.vocabList,
    **top_word_kws)

###############################################################################
#
# Train with K=30 clusters
# ------------------------
#
# Take the best of 10 initializations

trained_model, info_dict = bnpy.run(
    dataset, 'DPMixtureModel', 'Mult', 'VB',
    output_path='/tmp/we8there/helloworld-model=dp_mix+mult-K=30/',
    nLap=1000, convergeThr=0.0001, nTask=10,
    K=30, initname='bregmankmeans+lam1+iter1',
    gamma0=50.0, lam=0.1)

bnpy.viz.PrintTopics.plotCompsFromHModel(
    trained_model,
    vocabList=dataset.vocabList,
    **top_word_kws)


"""
Various general utility functions.

"""
import scipy as sp
from scipy import stats
import pickle
import gzip
import os
from itertools import takewhile
from itertools import repeat
import sys
import re

# LDpred currently ignores the Y and MT chromosomes.
ok_chromosomes = set(range(1, 24))
chromosomes_list = ['chrom_%d' % (chrom) for chrom in ok_chromosomes]

chrom_name_map = {'X':23,'chr_X':23,'chrom_X':23}
for chrom in ok_chromosomes:
    chrom_name_map['%d' % (chrom)]=chrom
    chrom_name_map['chrom_%d' % (chrom)]=chrom
    chrom_name_map['chr_%d' % (chrom)]=chrom

def get_chrom_num(chrom):
    return chrom_name_map.get(re.sub("chr", "", chrom),0)

#Various auxiliary variables
ambig_nts = set([('A', 'T'), ('T', 'A'), ('G', 'C'), ('C', 'G')])
opp_strand_dict = {'A': 'T', 'G': 'C', 'T': 'A', 'C': 'G'}

valid_nts = set(['A', 'T', 'C', 'G'])

# LDpred currently ignores the Y and MT chromosomes.
valid_chromosomes = ['%d' % (x) for x in range(1, 24)]
valid_chromosomes.append('X')

chromosomes_list = ['chrom_%s' % (chrom) for chrom in valid_chromosomes]

#Conversion sizes for strings (necessary for using h5py and python 3)
fids_dtype = '|S64'
iids_dtype = '|S64'
sids_dtype = "|S30"
nts_dtype = "|S1"

sids_u_dtype = '<U30'
nts_u_dtype = '<U1'

my_path = os.path.dirname(os.path.abspath(__file__))
hm3_file = os.path.join(my_path, 'reference','hm3_sids.txt.gz')
lrld_file = os.path.join(my_path, 'reference','long-range-ld-price-2008hg38.txt')

def check_chromosomes(missing_chromosomes):
        if len(missing_chromosomes) > 0:
            print('Ignored chromosomes:', ','.join(list(missing_chromosomes)))
            print('Please note that only data on chromosomes 1-23, and X is parsed.')

def calc_auc(y_true, y_hat, show_plot=False):
    """
    Calculate the Area Under the Curve (AUC) for a predicted and observed case-control phenotype.
    """
    y_true = sp.copy(y_true)
    if len(sp.unique(y_true)) == 2:
        y_min = y_true.min()
        y_max = y_true.max()
        if y_min != 0 or y_max != 1:
            print('Transforming back to a dichotomous trait')
            y_true[y_true == y_min] = 0
            y_true[y_true == y_max] = 1

    else:
        print('Warning: Calculating AUC for a quantitative phenotype.')
        y_mean = sp.mean(y_true)
        zero_filter = y_true <= y_mean
        one_filter = y_true > y_mean
        y_true[zero_filter] = 0
        y_true[one_filter] = 1

    num_cases = sp.sum(y_true == 1)
    num_controls = sp.sum(y_true == 0)
    assert num_cases + num_controls == len(y_true), 'The phenotype is not defined as expected. It is not binary (0 1 case-control status).'
    print('%d cases, %d controls' % (num_cases, num_controls))

    num_indivs = float(len(y_true))
    tot_num_pos = float(sp.sum(y_true))
    tot_num_neg = float(num_indivs - tot_num_pos)

    l = y_hat.tolist()
    l.sort(reverse=True)
    roc_x = []
    roc_y = []
    auc = 0.0
    prev_fpr = 0.0
    for thres in l:
        thres_filter = y_hat >= thres
        y_t = y_true[thres_filter]
        n = len(y_t)
        tp = sp.sum(y_t)
        fp = n - tp

        fpr = fp / tot_num_neg
        tpr = tp / tot_num_pos
        roc_x.append(fpr)
        roc_y.append(tpr)
        delta_fpr = fpr - prev_fpr
        auc += tpr * delta_fpr
        prev_fpr = fpr
    print('AUC: %0.4f' % auc)
    if show_plot:
        import pylab
        pylab.plot(roc_x, roc_y)
        pylab.show()
    return auc

def obs_h2_to_liab(R2_osb,K=0.01,P=0.5):
    """
    Transformation from observed to liability scale.

    Lee et al. AJHG 2011 conversion?

    For heritability only
    """
    t = stats.norm.ppf(1-K)
    z = stats.norm.pdf(t)
    c = P*(1-P)*z**2/(K**2*(1-K)**2)
    R2_liab = R2_osb/c
    return R2_liab

def obs_r2_to_liab(R2_osb,K=0.01,P=0.5):
    """
    Lee et al., Gen Epi 2012 conversion

    For R2 only

    """
    t = stats.norm.ppf(K)
    z = stats.norm.pdf(t)
    m = z/K
    C = (K*(1-K))**2/((z**2)*(P*(1-P)))
    d =  m*((P-K)/(1-K))
    theta =d**2 - d*t
    R2_liab_cc =  (R2_osb*C)/(1+(R2_osb*C*theta))
    return R2_liab_cc

def load_hapmap_SNPs():
    f = gzip.open(hm3_file, 'r')
    hm3_sids = pickle.load(f)
    f.close()
    return hm3_sids

def load_lrld_dict():
    #Load Price et al. AJHG 2008 long range LD table.
    d = {}
    for chrom in ok_chromosomes:
        d[chrom] = {'reg_dict':{}}
    with open(lrld_file, 'r') as f:
        for line in f:
            l = line.split()
            d[chrom_name_map[l[0]]][l[3]] = {'start_pos':int(l[1]), 'end_pos':int(l[2])}
    return d

def is_in_lrld(chrom, pos, lrld_dict):
    if len(lrld_dict[chrom]['reg_dict'])==0:
        return False
    else:
        for lrld_reg in lrld_dict[chrom]['reg_dict']:
            if lrld_reg['start_pos'] < pos < lrld_reg['end_pos']:
                return True
        else:
            return False

def get_snp_lrld_status(chromosome, positions, lrld_dict):
    snp_lrld = sp.zeros(len(positions))
    for snp_i in range(len(positions)):
        snp_lrld[snp_i] = is_in_lrld(chromosome, positions[snp_i], lrld_dict)
    return snp_lrld

def is_gz(name):
    return name.lower().endswith(('.gz', '.gzip'))

def count_lines(filename):
    if sys.version_info >= (3,0):
        return count_lines_fast(filename)
    else:
        return count_lines_slow(filename)

def count_lines_fast(filename):
    opener = open
    if is_gz(filename):
        opener = gzip.open
    try:
        with opener(filename, 'rb') as f:
            bufgen = takewhile(lambda x: x, (f.raw.read(1024*1024) for _ in repeat(None)))
            num_lines =sum( buf.count(b'\n') for buf in bufgen )
    except Exception:
        num_lines = -1
    return num_lines

def count_lines_slow(filename):
    opener = open
    if is_gz(filename):
        opener = gzip.open
    try:
        with opener(filename, 'rb') as f:
            num_lines = sum(1 for line in f)
    except Exception:
        num_lines=-1
    return num_lines


import plotly.graph_objs as go
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.figure_factory as ff

import pandas as pd
import numpy as np

import statsmodels.formula.api as smf

#get the orders data
# from olistdash.order import Order
# orders = Order().get_training_data(with_distance_seller_customer=True)

orders=pd.read_csv('data/orders_training_data.csv')

features = [
    "wait_time",
    "delay_vs_expected",
    "number_of_products",
    "number_of_sellers",
    "price",
    "freight_value",
    "distance_seller_customer",
]
orders_standardized = orders.copy()
for f in features:
    mu = orders[f].mean()
    sigma = orders[f].std()
    orders_standardized[f] = orders[f].map(lambda x: (x - mu) / sigma)
formula = "review_score ~ " + ' + '.join(features)
model4 = smf.ols(formula=formula, data=orders_standardized).fit()
model_df = pd.DataFrame(model4.params[1:].sort_values()).reset_index()
model_df.columns = ['features', 'correlation']
model_df

predicted_review_score = model4.predict(orders_standardized[features])
residuals = predicted_review_score - orders_standardized.review_score

def heatmap1():
    # fig = go.Heatmap(orders.corr())
    #     )
    # )
    fig = px.imshow(
        orders.corr(),
        # template='simple_white',
    )
    return fig

def correlation_bars():
    fig = px.bar(
        model_df,
        y='features',
        x='correlation',
        orientation='h',
        # template='simple_white'
        )
    fig.update_layout(
        margin={
            "r": 20,
            "t": 30,
            "b": 60,
            "l": 30,
        },
        height=300
    )
    fig.update_traces(
        width=0.4,
        # marker_line=dict(width=3)
    )
    fig.update_yaxes(title=None)

    return fig

# TABLES STATSMODEL
def model_summary_tab_0():
    return pd.read_html(
        model4.summary().tables[0].as_html(),
        header=0,
        index_col=0
        )[0].reset_index()

def model_summary_tab_1():
    return pd.read_html(
        model4.summary().tables[1].as_html(),
        header=0,
        index_col=0
        )[0].reset_index()

def model_summary_tab_2():
    return pd.read_html(
        model4.summary().tables[2].as_html(),
        header=0,
        index_col=0
        )[0].reset_index()

# PERFORMANCE
def residuals_mean():
    return residuals.mean()

def rmse_function():
    return (residuals.map(lambda x: x**2).sum() / len(residuals))**0.5

def performance_card():
    fig = go.Figure()
    fig.add_trace(
        go.Indicator(
            mode = "number",
            value = round(residuals_mean(),6),
            title = {"text": "Computed Residuals
Residuals Mean"},
            # delta = {'reference': 400, 'relative': True},
            domain = {
                'x': [0, 1],
                'y': [0.6, 1]
            }
        )
    )
    fig.add_trace(
        go.Indicator(
            mode = "number",
            value = rmse_function(),
            title = {"text": "Computed associated RMSE"},
            # delta = {'reference': 400, 'relative': True},
            domain = {
                'x': [0, 1],
                'y': [0, 0.4]
            }
        )
    )
    return fig

def model_performance():
    fig = ff.create_distplot(
        [residuals],
        group_labels=['distplot'],
        bin_size=.2,
        show_rug=False,
        histnorm='probability',
    )
    fig.update_layout(
        showlegend=False,
        title='Residuals Density Plot',
        # margin={
        #     # "r": 30,
        #     "t": 30,
        #     # "b": 30,
        #     "l": 30,
        # }
    )
    fig.update_yaxes(
        title='Density'
    )
    return fig

def predicted_vs_actual():
    group_labels=['predicted value','real value']
    colors = ['rgb(0, 0, 100)', "#DE3562"]
    # Create distplot with custom bin_size
    fig = ff.create_distplot(
        [
            predicted_review_score,
            orders.review_score
        ],
        group_labels,
        show_hist=False,
        bin_size=.2,
        show_rug=False,
        colors=colors,
        histnorm='probability',
    )
    fig.update_layout(
        xaxis={
        # "autorange": True,
            "range": [
                "1",
                "5",
            ],
        }
    )
    return fig


# -*- coding: utf-8 -*-
import sys
from preprocess import Channel
from workflow.cf_workflow import run as user_cf
from workflow.lfm_workflow import run as lfm
from workflow.lfm_workflow import predict as lfm_predict
from workflow.prank_workflow import run as prank
import pandas as pd
import pymysql
from sqlalchemy import create_engine

def manage():
    #arg = sys.argv[1]
    arg = "prank"
    if arg == 'preprocess':
        Channel().process()
    elif arg == 'cf':
        user_cf()
    elif arg == 'lfm':
        lfm()
    elif arg == 'prank':
        prank()
    else:
        print('Args must in ["preprocess", "cf", "lfm"，"prank"].')
    sys.exit()

def predict():
    arg = sys.argv[1]
    cars = lfm_predict(int(arg))

    # db
    db = pymysql.connect("localhost", "root", "", "rental")
    cursor = db.cursor()
    try:
        cursor.execute("DELETE FROM rt_lfm_recommendation WHERE rt_lfm_recommendation.user_id = "+str(arg))
        db.commit()
    except:
        db.rollback()
    cursor.close()
    db.close()

    engine = create_engine(
        "mysql+pymysql://{}:{}@{}/{}?charset={}".format('root', '', '127.0.0.1:3306', 'rental', 'utf8'))
    con = engine.connect()
    df = pd.DataFrame(cars)
    df.insert(0, 'user_id', arg)
    df.columns = ['user_id', 'car_id', 'rate']
    df.to_sql("rt_lfm_recommendation", con, if_exists='append', index=False)
    con.close()

    return cars is not None

if __name__ == '__main__':
    predict()


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pathlib import Path
import numpy as np

class DataLoader:
    def __init__(self):
        pass

    @staticmethod
    def html(dirnames):
        dirnames = [name for name in dirnames if len(name) > 0]
        htmls = []
        for dirname in dirnames:
            for subdir in Path(dirname).glob("*"):
                print("Loading %s..." % str(subdir))
                doc_type = "javadoc" if "javadoc" in subdir.parts[-1] else "html"
                for fn in Path(subdir).glob("*"):
                    try:
                        with Path(fn).open("r", encoding="utf-8") as f:
                            html = f.read().strip()
                        source = str(Path(dirname).parts[-2])
                        htmls.append((doc_type, source, html))
                    except Exception:
                        pass
        return htmls

    @staticmethod
    def code(dirnames):
        dirnames = [name for name in dirnames if len(name) > 0]
        codes = []
        for dirname in dirnames:
            print("Loading %s..." % str(dirname))
            for fn in Path(dirname).rglob("*.*"):
                if fn.is_file():
                    try:
                        with Path(fn).open("r", encoding="utf-8") as f:
                            code = f.read().strip()
                        index = str(fn).find(dirname)
                        if index > -1:
                            index += len(dirname)
                        short_fn = str(fn)[index:] if index > -1 else str(fn)
                        short_fn = short_fn.lstrip("/\\")
                        if fn.suffix == ".py":
                            codes.append(("python", short_fn, code))
                        elif fn.suffix == ".java":
                            codes.append(("java", short_fn, code))
                    except Exception:
                        continue
        return codes


import multiprocessing
import os

import gunicorn.app.base
from brochure.brochure_application import BrochureApplication
from brochure.commands.command_types import CommandType
from brochure_wsgi.brochure_wsgi_application import BrochureWSGIApplication
from brochure_wsgi.http_user_interface import HTTPUserInterfaceProvider
from brochure_wsgi.path_command_provider import GetPathCommandProvider
from brochure_wsgi.value_fetchers.environment_contact_method_fetcher import environment_contact_method_fetcher
from brochure_wsgi.value_fetchers.environment_cover_section_fetcher import environment_cover_section_fetcher
from brochure_wsgi.value_fetchers.environment_enterprise_fetcher import environment_enterprise_fetcher
from gunicorn.six import iteritems
from werkzeug.routing import Map, Rule

from cf_domain_redirect_preprocessor import get_cf_domain_redirect_preprocessor
from cf_favicon_preprocessor import get_cf_favicon_preprocessor
from cf_upgrade_to_ssl_preprocessor import get_cf_upgrade_to_ssl_preprocessor

class GunicornApplication(gunicorn.app.base.BaseApplication):
    def __init__(self, application, options=None):
        self.options = options or {}
        self.application = application
        super().__init__()

    def init(self, parser, opts, args):
        pass

    def load_config(self):
        config = dict([(key, value) for key, value in iteritems(self.options)
                       if key in self.cfg.settings and value is not None])
        for key, value in iteritems(config):
            self.cfg.set(key.lower(), value)

    def load(self):
        return self.application

if __name__ == "__main__":
    option_dictionary = {
        "bind": '%s:%s' % ('0.0.0.0', os.environ.get("PORT", "8000")),
        "workers": (multiprocessing.cpu_count() * 2) + 1,
    }
    brochure_application_command_map = Map()
    brochure_application_command_map.add(Rule("/", endpoint=lambda: CommandType.SHOW_COVER))
    get_path_command_provider = GetPathCommandProvider(url_map=brochure_application_command_map)

    domain_application = BrochureApplication(contact_method_fetcher=environment_contact_method_fetcher,
                                             cover_section_fetcher=environment_cover_section_fetcher,
                                             enterprise_fetcher=environment_enterprise_fetcher)
    user_interface_provider = HTTPUserInterfaceProvider()

    command_preprocessors = None
    favicon_preprocessor = get_cf_favicon_preprocessor()
    if os.environ.get("DEBUG", False):
        command_preprocessors = (favicon_preprocessor,)
    else:
        domain_redirect_preprocessor = get_cf_domain_redirect_preprocessor()
        upgrade_to_ssl_preprocessor = get_cf_upgrade_to_ssl_preprocessor()
        command_preprocessors = (favicon_preprocessor, domain_redirect_preprocessor, upgrade_to_ssl_preprocessor)

    brochure_wsgi_application = BrochureWSGIApplication(domain_application=domain_application,
                                                        user_interface_provider=user_interface_provider,
                                                        get_path_command_provider=get_path_command_provider,
                                                        command_preprocessors=command_preprocessors)
    GunicornApplication(application=brochure_wsgi_application,
                        options=option_dictionary).run()


from math import ceil, degrees, radians, atan2, cos, sin

from lib.console import Console

from .writable import Writable

import numpy as np
from PIL import Image, ImageDraw

from affine6p import estimate

def get_size(coords):
    left = min(x for x, _ in coords)
    top = min(y for _, y in coords)
    right = max(x for x, _ in coords)
    bottom = max(y for _, y in coords)

    return right - left or 1, bottom - top or 1

class Shape(Writable):
    SHAAPE_END_COMMAND_TAG = 0

    SHAAPE_DRAW_BITMAP_COMMAND_TAGS = (4, 17, 22)
    SHAPE_DRAW_COLOR_FILL_COMMAND_TAG = 6

    def __init__(self) -> None:
        super().__init__()

        self.bitmaps: list = []

    def load(self, swf, tag: int):
        id = swf.reader.read_ushort()

        bitmaps_count = swf.reader.read_ushort()
        self.bitmaps = [_class() for _class in [ShapeDrawBitmapCommand] * bitmaps_count]

        points_count = 4 * bitmaps_count
        if tag == 18:
            points_count = swf.reader.read_ushort()

        bitmaps_loaded = 0
        while True:
            bitmap_tag = swf.reader.read_uchar()
            bitmap_tag_length = swf.reader.read_int()

            if bitmap_tag == Shape.SHAAPE_END_COMMAND_TAG:
                break

            if bitmap_tag in Shape.SHAAPE_DRAW_BITMAP_COMMAND_TAGS:
                self.bitmaps[bitmaps_loaded].load(swf, bitmap_tag)
                bitmaps_loaded += 1
                continue

            elif tag == Shape.SHAPE_DRAW_COLOR_FILL_COMMAND_TAG:
                Console.error("Tag ShapeDrawColorFillCommand is unsupported! Aborting...")
                raise TypeError()

            Console.warning(
                f"Shape {self.id} has unknown command tag {bitmap_tag} with length {bitmap_tag_length}! Skipping...")
            swf.reader.skip(bitmap_tag_length)

        return id

    def save(self, swf, id: int):
        super().save()

        self.write_ushort(id)
        self.write_ushort(len(self.bitmaps))

        points_count = 0
        max_rects_count = 0
        for bitmap in self.bitmaps:
            points_count += len(bitmap.xy_coords)
            if bitmap.max_rects:
                max_rects_count += 1

        tag = 2 if max_rects_count == len(self.bitmaps) else 18

        # allocator?
        if tag == 18:
            self.write_ushort(points_count)

        for bitmap in self.bitmaps:
            tag_bitmap, buffer = bitmap.save(swf)

            self.write_uchar(tag_bitmap)
            self.write_int(len(buffer))
            self.write(buffer)

        self.write(bytes(5))  # end tag for bitmap tags array

        return tag, self.buffer

    def __eq__(a, b):
        if type(a) == type(b):
            if a.bitmaps == b.bitmaps:
                return True
        return False

class ShapeDrawBitmapCommand(Writable):
    def __init__(self) -> None:
        self.texture_index: int = -1
        self.uv_coords: list = []
        self.xy_coords: list = []

        self.max_rects: bool = False

    def load(self, swf, tag: int):
        self.texture_index = swf.reader.read_uchar()

        self.max_rects = tag == 4
        points_count = 4 if self.max_rects else swf.reader.read_uchar()

        for i in range(points_count):
            x = swf.reader.read_twip()
            y = swf.reader.read_twip()
            self.xy_coords.append([x, y])

        for i in range(points_count):
            w = swf.reader.read_ushort()
            h = swf.reader.read_ushort()

            if tag == 22:
                w = w / 0xFFFF * swf.textures[self.texture_index].width
                h = h / 0xFFFF * swf.textures[self.texture_index].height

            u, v = [ceil(i) for i in [w, h]]

            self.uv_coords.append([u, v])
    def save(self, swf):
        super().save()

        tag = 4 if self.max_rects else 22
        points_count = 4 if self.max_rects else len(self.xy_coords)

        self.write_uchar(self.texture_index)

        if not self.max_rects:
            self.write_uchar(points_count)

        if (swf.textures[self.texture_index].mag_filter, swf.textures[self.texture_index].min_filter) == (
                "GL_NEAREST", "GL_NEAREST") and not self.max_rects:
            tag = 17

        for coord in self.xy_coords[:points_count]:
            x, y = coord

            self.write_twip(x)
            self.write_twip(y)

        for coord in self.uv_coords[:points_count]:
            u, v = coord

            if tag == 22:
                u *= 0xFFFF / swf.textures[self.texture_index].width
                v *= 0xFFFF / swf.textures[self.texture_index].height

            self.write_ushort(int(u))
            self.write_ushort(int(v))

        return tag, self.buffer

    def get_image(self, swf) -> Image:
        texture = swf.textures[self.texture_index]
        image = texture.get_image()

        w, h = self.get_size(self.uv_coords)
        if w == 0:
            w = 1
        if h == 0:
            h = 1

        if w + h == 2:
            x, y = self.uv_coords[-1]
            return Image.new(texture.image.mode, (1, 1), texture.image.getpixel((x, y)))

        mask = Image.new("L", (texture.width, texture.height), 0)

        color = 255
        ImageDraw.Draw(mask).polygon([(x, y) for x, y in self.uv_coords], fill=color)

        left = min(x for x, _ in self.uv_coords)
        top = min(y for _, y in self.uv_coords)
        right = max(x for x, _ in self.uv_coords)
        bottom = max(y for _, y in self.uv_coords)

        if w == 1:
            right += 1
        if h == 1:
            bottom += 1

        bbox = left, top, right, bottom

        sprite = Image.new(image.mode, (w, h))
        sprite.paste(image.crop(bbox), (0, 0), mask.crop(bbox))

        return sprite

    def get_matrix(self, custom_uv_coords: list = None, use_nearest: bool = False):
        uv_coords = custom_uv_coords or self.uv_coords

        rotation = 0
        mirroring = False
        if use_nearest:
            rotation, mirroring = self.get_rotation(use_nearest)

            rad = radians(rotation)

            uv_coords = [
                np.array(
                    (
                        (np.cos(rad), -np.sin(rad)),
                        (np.sin(rad), np.cos(rad))
                    )
                ).dot(point).tolist() for point in self.uv_coords
            ]

            uv_coords = [[round(x), round(y)] for x, y in uv_coords]

            if mirroring:
                uv_coords = [[-x, y] for x, y, in uv_coords]

        sprite_box = []

        for idx in range(len(uv_coords)):
            if idx == 0:
                sprite_box.append([0, 0])
            else:
                x_distance = uv_coords[idx][0] - uv_coords[idx - 1][0]
                y_distance = uv_coords[idx][1] - uv_coords[idx - 1][1]

                sprite_box.append([round(sprite_box[idx - 1][0] + x_distance, 3),
                                   round(sprite_box[idx - 1][1] + y_distance, 3)])

            if sprite_box[idx][0] < 0:
                sprite_box = [[x - sprite_box[idx][0], y] for x, y in sprite_box]

            if sprite_box[idx][1] < 0:
                sprite_box = [[x, y - sprite_box[idx][1]] for x, y in sprite_box]

        w, h = self.get_size(uv_coords)
        if w == 0 or h == 0:
            sprite_box = self.get_right_uv(False, sprite_box)

        transform = estimate(sprite_box, self.xy_coords)

        return transform, sprite_box, rotation, mirroring
    @staticmethod
    def scale_around(point, center, scale):
        c_x, c_y = center
        x, y = point
        sx, sy = scale
        return [round(((x - c_x) * sx)), round(((y - c_y) * sy))]
    @staticmethod
    def move_by_angle(point, angle, distance):
        x, y = point

        x += distance * sin(angle)
        y += distance * cos(angle)

        return [round(x) or 0, round(y) or 0]
    @staticmethod
    def find_angle(p1, p2):
        x1, y1 = p1
        x2, y2 = p2
        dX = x2 - x1
        dY = y2 - y1
        rads = atan2(-dY, dX)
        return degrees(rads)
    def get_right_uv(self, inside: bool, custom: list = None):
        coords = custom if custom is not None else self.uv_coords

        res = coords.copy()
        w, h = ShapeDrawBitmapCommand.get_size(coords)

        if not inside and w == 0 or h == 0:
            unique_points = [list(x) for x in set(tuple(x) for x in coords)]
            for index, point in enumerate(unique_points):
                if coords[0] == coords[1]:
                    point_idx = index + 1
                else:
                    point_idx = 3 - (list(reversed(res)).index(point))

                res[point_idx] = [res[point_idx][0] + (1 if w == 0 else 0),
                                  res[point_idx][1] + (1 if h == 0 else 0)]

            return res
        else:
            if len(coords) <= 4:
                w_m = (w + 2) if inside else (w - 2 if w > 2 else 0)
                h_m = (h + 2) if inside else (h - 2 if h > 2 else 0)

                c_x, c_y = [sum([x for x, _ in coords]) / len(coords), sum([y for _, y in coords]) / len(coords)]

                return [[round((w_m / w) * (x - c_x) + c_x), round((h_m / h) * (y - c_y) + c_y)] for x, y in coords]

            for i, point in enumerate(coords):
                if i == 0:
                    last = len(coords) - 1
                else:
                    last = i - 1

                angle = radians(self.find_angle(coords[last], coords[i]) - 45)

                res[i] = self.move_by_angle(coords[i], angle, -1 if inside else 1)

            return res
    def get_translation(self, centroid: bool = False):
        if centroid:
            x_coords = [x for x, _ in self.xy_coords]
            y_coords = [y for y, _ in self.xy_coords]

            size = len(self.xy_coords)

            x = sum(x_coords) / size
            y = sum(y_coords) / size

            return x, y

        left = min(x for x, _ in self.xy_coords)
        top = min(y for _, y in self.xy_coords)

        return left, top

    def get_rotation(self, nearest: bool = False):
        def is_clockwise(points):
            points_sum = 0
            for x in range(len(points)):
                x1, y1 = points[(x + 1) % len(points)]
                x2, y2 = points[x]
                points_sum += (x1 - x2) * (y1 + y2)
            return points_sum < 0

        uv_cw = is_clockwise(self.uv_coords)
        xy_cw = is_clockwise(self.xy_coords)

        mirroring = not (uv_cw == xy_cw)

        dx = self.xy_coords[1][0] - self.xy_coords[0][0]
        dy = self.xy_coords[1][1] - self.xy_coords[0][1]
        du = self.uv_coords[1][0] - self.uv_coords[0][0]
        dv = self.uv_coords[1][1] - self.uv_coords[0][1]

        angle_xy = degrees(atan2(dy, dx) + 360) % 360
        angle_uv = degrees(atan2(dv, du) + 360) % 360

        angle = (angle_xy - angle_uv + 360) % 360

        if mirroring:
            angle -= 180

        if nearest:
            angle = round(angle / 90) * 90

        return angle, mirroring

    @staticmethod
    def get_size(coords):
        left = min(coord[0] for coord in coords)
        top = min(coord[1] for coord in coords)
        right = max(coord[0] for coord in coords)
        bottom = max(coord[1] for coord in coords)

        return right - left, bottom - top

    def get_scale(self):
        uv_x, uv_y = self.get_size(self.uv_coords)
        xy_x, xy_y = self.get_size(self.xy_coords)

        return uv_x / xy_x, uv_y / xy_y

    def __eq__(a, b):
        if a.max_rects == b.max_rects\
                and a.uv_coords == b.uv_coords\
                and a.xy_coords == b.xy_coords\
                and a.texture_index == b.texture_index:
            return True
        return False


#!/usr/bin/env python3
from datetime import datetime
from psutil import disk_usage, sensors_battery
from psutil._common import bytes2human
from socket import gethostname, gethostbyname
from subprocess import check_output
from sys import stdout
from time import sleep

def write(data):
    stdout.write("%s\n" % data)
    stdout.flush()

def refresh():
    disk = bytes2human(disk_usage("/").free)
    ip = gethostbyname(gethostname())
    try:
        ssid = check_output("iwgetid -r", shell=True).strip().decode("utf-8")
        ssid = "(%s)" % ssid
    except Exception:
        ssid = "None"
    bluetooth = check_output(
        "systemctl status bluetooth | grep Status",
        shell=True).strip().decode("utf-8")
    battery = int(sensors_battery().percent)
    status = "Charging" if sensors_battery().power_plugged else "Discharging"
    date = datetime.now().strftime("%h %d %A %I:%M")
    format = "Space: %s | Internet: %s %s | Bluetooth %s | Battery: %s%% %s | Date: %s"
    write(format % (disk, ip, ssid, bluetooth, battery, status, date))

if __name__ == "__main__":
    refresh()


import unittest
from sdk_test_case import SdkTestCase
from test_project import create_test_project

import flywheel

class SubjectsTestCases(SdkTestCase):
    def setUp(self):
        self.group_id, self.project_id = create_test_project()

    def tearDown(self):
        self.fw.delete_project(self.project_id)
        self.fw.delete_group(self.group_id)

    def test_subjects(self):
        fw = self.fw

        subject_code = self.rand_string_lower()
        subject = flywheel.Subject(
            project=self.project_id,
            firstname=self.rand_string(),
            lastname=self.rand_string(),
            code=subject_code,
            sex='other',
            info={'some-subject-key': 37}
        )

        # Add
        subject_id = fw.add_subject(subject)
        self.assertNotEmpty(subject_id)

        # Get
        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.id, subject_id)
        self.assertEqual(r_subject.code, subject_code)
        self.assertIn('some-subject-key', r_subject.info)
        self.assertEqual(r_subject.info['some-subject-key'], 37)
        self.assertTimestampBeforeNow(r_subject.created)
        self.assertGreaterEqual(r_subject.modified, r_subject.created)

        # Generic Get is equivalent
        self.assertEqual(fw.get(subject_id).to_dict(), r_subject.to_dict())

        # Get All
        subjects = fw.get_all_subjects()
        self.assertNotEmpty(subjects)

        self.sanitize_for_collection(r_subject)
        self.assertIn(r_subject, subjects)

        # # Get from parent
        # subjects = fw.get_project_subjects(self.project_id)
        # self.assertIn(r_subject, subjects)

        # Modify
        new_sex = 'male'
        r_subject.update(sex=new_sex)

        changed_subject = fw.get_subject(subject_id)
        self.assertEqual(changed_subject.sex, new_sex)
        self.assertEqual(changed_subject.created, r_subject.created)
        self.assertGreater(changed_subject.modified, r_subject.modified)

        # Notes, Tags
        message = 'This is a note'
        r_subject.add_note(message)

        tag = 'example-tag'
        r_subject.add_tag(tag)

        # Replace Info
        fw.replace_subject_info(subject_id, { 'foo': 3, 'bar': 'qaz' })

        # Set Info
        fw.set_subject_info(subject_id, { 'foo': 42, 'hello': 'world' })

        # Check
        r_subject = fw.get_subject(subject_id)

        self.assertEqual(len(r_subject.notes), 1)
        self.assertEqual(r_subject.notes[0].text, message)

        self.assertEqual(len(r_subject.tags), 1)
        self.assertEqual(r_subject.tags[0], tag)

        self.assertEqual(r_subject.info['foo'], 42)
        self.assertEqual(r_subject.info['bar'], 'qaz')
        self.assertEqual(r_subject.info['hello'], 'world')

        # Delete info fields
        fw.delete_subject_info_fields(subject_id, ['foo', 'bar'])

        r_subject = fw.get_subject(subject_id)
        self.assertNotIn('foo', r_subject.info)
        self.assertNotIn('bar', r_subject.info)
        self.assertEqual(r_subject.info['hello'], 'world')

        # Add session
        r_session = r_subject.add_session(label='Session 1')
        self.assertEqual(r_session.project, self.project_id)
        self.assertEqual(r_session.subject.id, subject_id)

        # Delete
        fw.delete_subject(subject_id)

        subjects = fw.get_all_subjects()
        self.sanitize_for_collection(r_subject)
        self.assertNotIn(r_subject, subjects)

    def test_subject_files(self):
        fw = self.fw

        subject = flywheel.Subject(code=self.rand_string(), project=self.project_id)
        subject_id = fw.add_subject(subject)

        # Upload a file
        poem = 'The best lack all conviction, while the worst'
        fw.upload_file_to_subject(subject_id, flywheel.FileSpec('yeats.txt', poem))

        # Check that the file was added to the subject
        r_subject = fw.get_subject(subject_id)
        self.assertEqual(len(r_subject.files), 1)
        self.assertEqual(r_subject.files[0].name, 'yeats.txt')
        self.assertEqual(r_subject.files[0].size, 45)
        self.assertEqual(r_subject.files[0].mimetype, 'text/plain')

        # Download the file and check content
        self.assertDownloadFileTextEquals(fw.download_file_from_subject_as_data, subject_id, 'yeats.txt', poem)

        # Test unauthorized download with ticket for the file
        self.assertDownloadFileTextEqualsWithTicket(fw.get_subject_download_url, subject_id, 'yeats.txt', poem)

        # Test file attributes
        self.assertEqual(r_subject.files[0].modality, None)
        self.assertEmpty(r_subject.files[0].classification)
        self.assertEqual(r_subject.files[0].type, 'text')

        resp = r_subject.files[0].update(type='type', modality='modality')

        # Check that no jobs were triggered, and attrs were modified
        self.assertEqual(resp.jobs_spawned, 0)

        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].modality, "modality")
        self.assertEmpty(r_subject.files[0].classification)
        self.assertEqual(r_subject.files[0].type, 'type')

        # Test classifications
        resp = fw.replace_subject_file_classification(subject_id, 'yeats.txt', {
            'Custom': ['measurement1', 'measurement2'],
        })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].classification, {
            'Custom': ['measurement1', 'measurement2']
        });

        resp = fw.modify_subject_file_classification(subject_id, 'yeats.txt', {
            'add': {
                'Custom': ['HelloWorld'],
            },
            'delete': {
                'Custom': ['measurement2']
            }
        })
        self.assertEqual(resp.modified, 1)
        self.assertEqual(resp.jobs_spawned, 0)

        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].classification, {
            'Custom': ['measurement1', 'HelloWorld'],
        });

        # Test file info
        self.assertEmpty(r_subject.files[0].info)
        fw.replace_subject_file_info(subject_id, 'yeats.txt', {
            'a': 1,
            'b': 2,
            'c': 3,
            'd': 4
        })

        fw.set_subject_file_info(subject_id, 'yeats.txt', {
            'c': 5
        })

        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].info['a'], 1)
        self.assertEqual(r_subject.files[0].info['b'], 2)
        self.assertEqual(r_subject.files[0].info['c'], 5)
        self.assertEqual(r_subject.files[0].info['d'], 4)

        fw.delete_subject_file_info_fields(subject_id, 'yeats.txt', ['c', 'd'])
        r_subject = fw.get_subject(subject_id)
        self.assertEqual(r_subject.files[0].info['a'], 1)
        self.assertEqual(r_subject.files[0].info['b'], 2)
        self.assertNotIn('c', r_subject.files[0].info)
        self.assertNotIn('d', r_subject.files[0].info)

        fw.replace_subject_file_info(subject_id, 'yeats.txt', {})
        r_subject = fw.get_subject(subject_id)
        self.assertEmpty(r_subject.files[0].info)

        # Delete file
        fw.delete_subject_file(subject_id, 'yeats.txt')
        r_subject = fw.get_subject(subject_id)
        self.assertEmpty(r_subject.files)

        # Delete subject
        fw.delete_subject(subject_id)

    def test_subject_errors(self):
        fw = self.fw

        # Try to create subject without project id
        try:
            subject = flywheel.Subject(code=self.rand_string())
            subject_id = fw.add_subject(subject)
            self.fail('Expected ApiException creating invalid subject!')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 422)

        # Try to get a subject that doesn't exist
        try:
            fw.get_subject('DOES_NOT_EXIST')
            self.fail('Expected ApiException retrieving invalid subject!')
        except flywheel.ApiException as e:
            self.assertEqual(e.status, 404)

    def test_subject_analysis(self):
        fw = self.fw

        subject = flywheel.Subject(project=self.project_id, code=self.rand_string())

        # Add
        subject_id = fw.add_subject(subject)
        self.assertNotEmpty(subject_id)

        poem = 'When a vast image out of Spiritus Mundi'
        fw.upload_file_to_subject(subject_id, flywheel.FileSpec('yeats.txt', poem))

        file_ref = flywheel.FileReference(
            id=subject_id,
            type='subject',
            name='yeats.txt'
        )

        analysis = flywheel.AnalysisInput(label=self.rand_string(), description=self.rand_string(), inputs=[file_ref])

        # Add
        analysis_id = fw.add_subject_analysis(subject_id, analysis)
        self.assertNotEmpty(analysis_id)

        # Get the list of analyses in the subject
        analyses = fw.get_subject_analyses(subject_id)
        self.assertEqual(len(analyses), 1)

        r_analysis = analyses[0]

        self.assertEqual(r_analysis.id, analysis_id)
        self.assertEmpty(r_analysis.job)

        self.assertTimestampBeforeNow(r_analysis.created)
        self.assertGreaterEqual(r_analysis.modified, r_analysis.created)

        self.assertEqual(len(r_analysis.inputs), 1)
        self.assertEqual(r_analysis.inputs[0].name, 'yeats.txt')

    def sanitize_for_collection(self, subject, info_exists=True):
        # workaround: all-container endpoints skip some fields,
        # single-container does not. this sets up the equality check
        subject.info = {}
        subject.info_exists = info_exists
        subject.analyses = None

        subject.sex = None
        subject.firstname = None
        subject.lastname = None
        subject.info = {}
        subject.info_exists = info_exists

def create_test_subject():
    group_id, project_id = create_test_project()
    return group_id, project_id, SdkTestCase.fw.add_subject({
        'project': project_id,
        'code': SdkTestCase.rand_string_lower(),
        'firstname': SdkTestCase.rand_string(),
        'lastname': SdkTestCase.rand_string(),
        'sex': 'other',
        'age': 57
    })