import logging
import os

import numpy as np
import tensorflow as tf
# pylint: disable=E0611,E0401
import tensorflow.keras.backend as K
# pylint: disable=E0611,E0401
from tensorflow.keras import layers, regularizers
# pylint: disable=E0611,E0401
from tensorflow.keras.layers import (
    BatchNormalization,
    Conv2D,
    Dense,
    Dropout,
    Input,
    Lambda,
    Reshape,
)
# pylint: disable=E0611,E0401
from tensorflow.keras.models import Model
# pylint: disable=E0611,E0401
from tensorflow.keras.optimizers import Adam

from deep_speaker.constants import NUM_FBANKS, SAMPLE_RATE, NUM_FRAMES
from deep_speaker.triplet_loss import deep_speaker_loss

logger = logging.getLogger(__name__)

@tf.function
def tf_normalize(data, ndims, eps=0, adjusted=False):
    data = tf.convert_to_tensor(data, name='data')

    reduce_dims = [-i - 1 for i in range(ndims)]
    # pylint: disable=E1123,E1120
    data = tf.cast(data, dtype=tf.dtypes.float32)
    data_num = tf.reduce_prod(data.shape[-ndims:])
    data_mean = tf.reduce_mean(data, axis=reduce_dims, keepdims=True)

    # Apply a minimum normalization that protects us against uniform images.
    stddev = tf.math.reduce_std(data, axis=reduce_dims, keepdims=True)
    adjusted_stddev = stddev
    if adjusted:
        min_stddev = tf.math.rsqrt(tf.cast(data_num, tf.dtypes.float32))
        eps = tf.maximum(eps, min_stddev)
    if eps > 0:
        adjusted_stddev = tf.maximum(adjusted_stddev, eps)

    return (data - data_mean) / adjusted_stddev

@tf.function
def tf_fbank(samples):
    """
    Compute Mel-filterbank energy features from an audio signal.
    See python_speech_features.fbank
    """
    frame_length = int(0.025 * SAMPLE_RATE)
    frame_step = int(0.01 * SAMPLE_RATE)
    fft_length = 512
    fft_bins = fft_length // 2 + 1

    pre_emphasis = samples[:, 1:] - 0.97 * samples[:, :-1]

    # Original implementation from python_speech_features
    # frames = tf.expand_dims(sigproc.framesig(preemphasis[0], frame_length,
    # frame_step, winfunc=lambda x: np.ones((x,))), 0)
    # powspec = sigproc.powspec(frames, fft_length)

    # Tensorflow impl #1, using manually-split frames and rfft
    # spec = tf.abs(tf.signal.rfft(frames, [fft_length]))
    # powspec = tf.square(spec) / fft_length

    # Tensorflow impl #2, using stft to handle framing automatically
    # (There is a one-off mismatch on the number of frames on the resulting tensor, but I guess this is ok)
    spec = tf.abs(tf.signal.stft(pre_emphasis, frame_length, frame_step, fft_length, window_fn=tf.ones))
    powspec = tf.square(spec) / fft_length

    # Matrix to transform spectrum to mel-frequencies

    # Original implementation from python_speech_features
    # linear_to_mel_weight_matrix = get_filterbanks(NUM_FBANKS, fft_length,
    # SAMPLE_RATE, 0, SAMPLE_RATE/2).astype(np.float32).T

    linear_to_mel_weight_matrix = tf.signal.linear_to_mel_weight_matrix(
        num_mel_bins=NUM_FBANKS,
        num_spectrogram_bins=fft_bins,
        sample_rate=SAMPLE_RATE,
        lower_edge_hertz=0,
        upper_edge_hertz=SAMPLE_RATE / 2,
    )

    feat = tf.matmul(powspec, linear_to_mel_weight_matrix)
    # feat = tf.where(feat == 0, np.finfo(np.float32).eps, feat)
    return feat

class DeepSpeakerModel:

    # I thought it was 3 but maybe energy is added at a 4th dimension.
    # would be better to have 4 dimensions:
    # MFCC, DIFF(MFCC), DIFF(DIFF(MFCC)), ENERGIES (probably tiled across the frequency domain).
    # this seems to help match the parameter counts.
    def __init__(
            self,
            batch_input_shape=(None, NUM_FRAMES, NUM_FBANKS, 1),
            include_softmax=False,
            num_speakers_softmax=None,
            pcm_input=False
    ):
        if pcm_input:
            batch_input_shape = None
        self.include_softmax = include_softmax
        if self.include_softmax:
            assert num_speakers_softmax > 0
        self.clipped_relu_count = 0

        # http://cs231n.github.io/convolutional-networks/
        # conv weights
        # #params = ks * ks * nb_filters * num_channels_input

        # Conv128-s
        # 5*5*128*128/2+128
        # ks*ks*nb_filters*channels/strides+bias(=nb_filters)

        # take 100 ms -> 4 frames.
        # if signal is 3 seconds, then take 100ms per 100ms and average out this network.
        # 8*8 = 64 features.

        # used to share all the layers across the inputs

        # num_frames = K.shape() - do it dynamically after.

        if pcm_input:
            batch_input_shape = batch_input_shape or (None, None)  # Batch-size, num-samples
            inputs = Input(batch_shape=batch_input_shape, name='raw_inputs')
            x = inputs
            x = Lambda(tf_fbank)(x)
            x = Lambda(lambda x_: tf_normalize(x_, 1, 1e-12))(x)
            x = Lambda(lambda x_: tf.expand_dims(x_, axis=-1))(x)
        else:
            batch_input_shape = batch_input_shape or (None, None, NUM_FBANKS, 1)
            inputs = Input(batch_shape=batch_input_shape, name='input')
            x = inputs

        x = self.cnn_component(x)

        x = Reshape((-1, 2048))(x)
        # Temporal average layer. axis=1 is time.
        x = Lambda(lambda y: K.mean(y, axis=1), name='average')(x)
        if include_softmax:
            logger.info('Including a Dropout layer to reduce overfitting.')
            # used for softmax because the dataset we pre-train on might be too small. easy to overfit.
            x = Dropout(0.5)(x)
        x = Dense(512, name='affine')(x)
        if include_softmax:
            # Those weights are just when we train on softmax.
            x = Dense(num_speakers_softmax, activation='softmax')(x)
        else:
            # Does not contain any weights.
            x = Lambda(lambda y: K.l2_normalize(y, axis=1), name='ln')(x)
        self.m = Model(inputs, x, name='ResCNN')

    def keras_model(self):
        return self.m

    def get_weights(self):
        w = self.m.get_weights()
        if self.include_softmax:
            w.pop()  # last 2 are the W_softmax and b_softmax.
            w.pop()
        return w

    def clipped_relu(self, inputs):
        relu = Lambda(lambda y: K.minimum(K.maximum(y, 0), 20), name=f'clipped_relu_{self.clipped_relu_count}')(inputs)
        self.clipped_relu_count += 1
        return relu

    def identity_block(self, input_tensor, kernel_size, filters, stage, block):
        conv_name_base = f'res{stage}_{block}_branch'

        x = Conv2D(filters,
                   kernel_size=kernel_size,
                   strides=1,
                   activation=None,
                   padding='same',
                   kernel_initializer='glorot_uniform',
                   kernel_regularizer=regularizers.l2(l=0.0001),
                   name=conv_name_base + '_2a')(input_tensor)
        x = BatchNormalization(name=conv_name_base + '_2a_bn')(x)
        x = self.clipped_relu(x)

        x = Conv2D(
            filters,
            kernel_size=kernel_size,
            strides=1,
            activation=None,
            padding='same',
            kernel_initializer='glorot_uniform',
            kernel_regularizer=regularizers.l2(l=0.0001),
            name=conv_name_base + '_2b',
        )(x)
        x = BatchNormalization(name=conv_name_base + '_2b_bn')(x)

        x = self.clipped_relu(x)

        x = layers.add([x, input_tensor])
        x = self.clipped_relu(x)
        return x

    def conv_and_res_block(self, inp, filters, stage):
        conv_name = 'conv{}-s'.format(filters)
        # TODO: why kernel_regularizer?
        o = Conv2D(filters,
                   kernel_size=5,
                   strides=2,
                   activation=None,
                   padding='same',
                   kernel_initializer='glorot_uniform',
                   kernel_regularizer=regularizers.l2(l=0.0001), name=conv_name)(inp)
        o = BatchNormalization(name=conv_name + '_bn')(o)
        o = self.clipped_relu(o)
        for i in range(3):
            o = self.identity_block(o, kernel_size=3, filters=filters, stage=stage, block=i)
        return o

    def cnn_component(self, inp):
        x = self.conv_and_res_block(inp, 64, stage=1)
        x = self.conv_and_res_block(x, 128, stage=2)
        x = self.conv_and_res_block(x, 256, stage=3)
        x = self.conv_and_res_block(x, 512, stage=4)
        return x

    def set_weights(self, w):
        for layer, layer_w in zip(self.m.layers, w):
            layer.set_weights(layer_w)
            logger.info(f'Setting weights for [{layer.name}]...')

def main():
    # Looks correct to me.
    # I have 37K but paper reports 41K. which is not too far.
    dsm = DeepSpeakerModel()
    dsm.m.summary()

    # I suspect num frames to be 32.
    # Then fbank=64, then total would be 32*64 = 2048.
    # plot_model(dsm.m, to_file='model.png', dpi=300, show_shapes=True, expand_nested=True)

def _train():
    # x = np.random.uniform(size=(6, 32, 64, 4))  # 6 is multiple of 3.
    # y_softmax = np.random.uniform(size=(6, 100))
    # dsm = DeepSpeakerModel(batch_input_shape=(None, 32, 64, 4), include_softmax=True, num_speakers_softmax=100)
    # dsm.m.compile(optimizer=Adam(lr=0.01), loss='categorical_crossentropy')
    # print(dsm.m.predict(x).shape)
    # print(dsm.m.evaluate(x, y_softmax))
    # w = dsm.get_weights()
    dsm = DeepSpeakerModel(batch_input_shape=(None, 32, 64, 4), include_softmax=False)
    # dsm.m.set_weights(w)
    dsm.m.compile(optimizer=Adam(lr=0.01), loss=deep_speaker_loss)

    # it works!!!!!!!!!!!!!!!!!!!!
    # unit_batch_size = 20
    # anchor = np.ones(shape=(unit_batch_size, 32, 64, 4))
    # positive = np.array(anchor)
    # negative = np.ones(shape=(unit_batch_size, 32, 64, 4)) * (-1)
    # batch = np.vstack((anchor, positive, negative))
    # x = batch
    # y = np.zeros(shape=(len(batch), 512))  # not important.
    # print('Starting to fit...')
    # while True:
    #     print(dsm.m.train_on_batch(x, y))

    # should not work... and it does not work!
    unit_batch_size = 20
    negative = np.ones(shape=(unit_batch_size, 32, 64, 4)) * (-1)
    batch = np.vstack((negative, negative, negative))
    x = batch
    y = np.zeros(shape=(len(batch), 512))  # not important.
    print('Starting to fit...')
    while True:
        print(dsm.m.train_on_batch(x, y))

def _test_checkpoint_compatibility():
    dsm = DeepSpeakerModel(batch_input_shape=(None, 32, 64, 4), include_softmax=True, num_speakers_softmax=10)
    dsm.m.save_weights('test.h5')
    dsm = DeepSpeakerModel(batch_input_shape=(None, 32, 64, 4), include_softmax=False)
    dsm.m.load_weights('test.h5', by_name=True)
    os.remove('test.h5')

if __name__ == '__main__':
    _test_checkpoint_compatibility()


# 散点图1
from pyecharts import Scatter
v1 = [10,20,30,40,50,60]
v2 = [10,20,30,40,50,60]

scatter =Scatter("散点图示例")
scatter.add("A",v1,v2)
scatter.add("B",v1[::-1],v2) #v1[::-1] 倒序

scatter.render("scatter01.html")

# 散点图2
v1 = [10,20,30,40,50,60]
v2 = [10,20,30,40,50,60]

scatter =Scatter("散点图示例")
scatter.add("A",v1,v2)
scatter.add("B",v1[::-1],v2,
is_visualmap =True,visual_type ="size",
visual_range_size=[20,80])#散点可见

scatter.render("scatter02.html")


from flask import Blueprint
from flask import request, jsonify

import client
from apiauth import require_apikey

personsroute = Blueprint('persons', __name__)

persons = client.db.collection('persons')

@personsroute.route('/persons', methods=['POST'])
@require_apikey
def createperson():

	try:
		id = request.json['id']
		persons.document(id).set(request.json)
		return jsonify({"success": True}), 200
	except Exception as e:
		return f"An Error Occurred: {e}"

@personsroute.route('/persons', methods=['GET'])
@require_apikey
def readperson():

	try:
		all_persons = [doc.to_dict() for doc in persons.stream()]
		jsonresult = jsonify({"persons" : all_persons}), 200
		return jsonresult
	except Exception as e:
		return f"An Error Occurred: {e}"

@personsroute.route('/persons/<id>', methods=['GET'])
@require_apikey
def readoneperson(id):

	try:
		person = persons.document(id).get()
		return jsonify(person.to_dict()), 200
	except Exception as e:
		return f"An Error Occurred: {e}"

@personsroute.route('/persons/<id>', methods=['PUT'])
@require_apikey
def updateperson(id):

	try:
		id = request.json['id']
		persons.document(id).update(request.json)
		return jsonify({"success": True}), 200
	except Exception as e:
		return f"An Error Occurred: {e}"

@personsroute.route('/persons/<id>', methods=['DELETE'])
@require_apikey
def deleteperson(id):

	try:
		persons.document(id).delete()
		return jsonify({"success": True}), 200
	except Exception as e:
		return f"An Error Occurred: {e}"


import tensorflow as tf
import numpy as np

_scaler = None
_X_test = None
_y_test = None
_X_raw = None

def _set_scaler(path):
    global _scaler, _X_test, _y_test, _X_raw
    from src.preprocess import load, process

    data_train, data_cv, data_test, data_raw_test = load(path)
    (X_train, y_train), (X_cv, y_cv),(X_test, y_test), scaler = process(data_train, data_cv, data_test)

    _scaler = scaler
    _X_test = X_test
    _y_test = data_test[:, -1]
    _X_raw = data_raw_test

def predict(data, path):
    with tf.Session() as sess:
        saver = tf.train.import_meta_graph(path)
        saver.restore(sess, path[:-5])

        graph = sess.graph
        X = graph.get_tensor_by_name('Placeholder:0')
        out = graph.get_tensor_by_name('transpose:0')

        result=sess.run(out, feed_dict={X:data})

        print(data.shape)
        print(np.transpose(result).shape)

        return _scaler.inverse_transform(np.concatenate((data, np.transpose(result)), axis=1))[:, -1]

def create_path(suffix, start, end, ratio, is_modified):
    path = f'./Data/fa_data_{suffix}_{start}_{end}_{str(ratio)}'
    if is_modified:
        path = f'{path}_mod'
    path = f'{path}.npy'

    return path

if __name__ == "__main__":
    suffix = 'all'
    start = 2012
    end = 2019
    ratio = [5.0, 3.0, 2.0]
    is_modified = True

    path = create_path(suffix, start, end, ratio, is_modified)

    collect_all = False
    _set_scaler(path)

    if collect_all:

        data = np.load(path, allow_pickle=True)
        _X_raw = data
        _y_test = data[:, -1]
        idx = [x for x in range(data.shape[1])]
        idx.remove(1)
        data = _scaler.transform(data[:, idx])
        _X_test = data[:, :-1]

    path = './checkpoints/2048/2048-99.meta'
    names = _X_raw[:, 1]
    price = (predict(_X_test, path))
    price = price

    header = ['season', 'name', 'age']
    pos = ['SP', 'RP', '1B', '2B', '3B', 'SS', 'RF', 'CF', 'LF', 'C', 'DH', 'OF', 'P']
    position = []

    for raw in _X_raw:
        for i, p in enumerate(raw[len(header):len(header) + len(pos)]):
            if p == 1:
                position.append(pos[i])
                break
    position = np.reshape(np.asarray(position), (len(position), 1))
    print(position)

    result = np.concatenate((np.reshape(names, (len(names), 1)), np.reshape(price, (len(price), 1)), position, np.reshape(_y_test, (len(_y_test), 1))), axis=1)
    print(result)

    import matplotlib.pyplot as plt

    plt.ion()
    fig = plt.figure()
    ax1 = fig.add_subplot(111)
    ax1.plot(_y_test, 'r')
    ax1.plot(result[:, 1], 'g')
    plt.waitforbuttonpress()

    save_path = './Data/result.csv'
    if collect_all:
        save_path = './Data/result_all.csv'

    with open('./Data/result_all.csv', 'w') as f:
        for r in result:
            f.write(f'{r[0]}, {r[1]/1000000}, {r[3]/1000000}, {r[2]}\n')
            # name, predicted, actual, position


from math import tan, asin, sin, acos
from time import time
st = time()

vec_subtraction = lambda a, b: [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
vec_addition = lambda a, b: [a[0] + b[0], a[1] + b[1], a[2] + b[2]]
vec_multiplication_by_const = lambda a, b: [a[0]*b, a[1]*b, a[2]*b]
scalar = lambda a, b: a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
mult_matr3_vec3 = lambda m, v: [m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2], m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2], m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2]]
vec_abs = lambda vec3: sum(map(lambda x: x**2, vec3))**0.5
vec_multiplication = lambda a, b: [a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0]]
plosk_by_point_and_norm = lambda m, n, p: n[0]*(p[0] - m[0]) + n[1]*(p[1] - m[1]) + n[2]*(p[2] - m[2])
dist_point_plane = lambda po, pl: po[0]*pl[0] + po[1]*pl[1] + po[2]*pl[2] + pl[3]
get_d = lambda p1, p2: ((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2 + (p1[2] - p2[2])**2)**0.5
check_in_figure = lambda point, edges: all([dist_point_plane(point, edge) <= 0 for edge in edges])
center_figure = lambda vertexes: (round(sum([x for x, y, z in vertexes])/len(vertexes), 3),
                                  round(sum([y for x, y, z in vertexes])/len(vertexes), 3),
                                  round(sum([z for x, y, z in vertexes])/len(vertexes), 3))

def make_ed(ver):
    le = vec_abs(ver)
    if le != 0:
        return ver[0] / le, ver[1] / le, ver[2] / le
    return [0, 0, 0]

def calculate(file):
    # считываем точки
    count_vertices = int(file.readline())
    vertices = []
    for _ in range(count_vertices):
        vertices.append(tuple(map(float, file.readline().split())))

    # ищем цент фигуры
    center = center_figure(vertices)
    # print(' '.join(tuple(map(lambda x: str(round(x, 5)).ljust(7, ' '), center))))

    # хз зачем
    file.readline()

    # считываем грани
    count_edge = int(file.readline())
    edges = []
    for _ in range(count_edge):
        arr = list(map(int, file.readline().split()))[1:]
        p0 = vertices[arr[0]]
        p1 = vertices[arr[1]]
        p2 = (0, 0, 0)
        for ver_id in arr[2:]:
            p2 = vertices[ver_id]
            if round(get_d(p0, p2) + get_d(p1, p2) - get_d(p0, p1), 6) * round(
                    get_d(p0, p2) + get_d(p0, p1) - get_d(p1, p2), 6) * round(
                get_d(p0, p1) + get_d(p1, p2) - get_d(p0, p2), 6) != 0:
                break
        # print(p0, p1, p2,)
        # составляем уравнение плоскости для каждой грани
        p1 = vec_subtraction(p0, p1)
        p2 = vec_subtraction(p0, p2)
        a, b, c = (p1[1] * p2[2] - p1[2] * p2[1]), -(p1[0] * p2[2] - p1[2] * p2[0]), (p1[0] * p2[1] - p1[1] * p2[0])
        a, b, c = make_ed((a, b, c))
        d = -p0[0] * a - p0[1] * b - p0[2] * c
        # print(center)
        # print(dist_point_plane(center, (a, b, c, d)))
        if int(dist_point_plane(center, (a, b, c, d))) > 0:
            a, b, c, d = -a, -b, -c, -d
        # print(a, b, c)
        edges.append([a, b, c, d, arr])

    # хз зачем
    file.readline()

    # считываем данные цилиндра
    cylinder_point = tuple(map(float, file.readline().split()))
    cylinder_vec = make_ed(tuple(map(float, file.readline().split())))
    cylinder_radius = float(file.readline())
    # d = vec_abs((u, v, w))
    # cylinder_vec = u/d, v/d, w/d
    # print(' '.join(tuple(map(lambda x: str(round(x, 5)).ljust(7, ' '), cylinder_point))), ' '.join(tuple(map(lambda x: str(round(x, 5)).ljust(7, ' '), cylinder_vec))), str(round(cylinder_radius, 5)).ljust(7, ' '), sep='\n')

    # тест функции точка в фигуре
    # в кубе: top, back, left, up, right, down
    # print("Тест точки в фигуре")
    # print('left', 'right', 'back', 'up  ', 'top ', 'down', sep='\t')
    # print(center)
    # print(check_in_figure(center, edges), sep='\t')
    # for x in range(-1, 2):
    #     for y in range(-1, 2):
    #         for z in range(-1, 2):
    #             print(check_in_figure((x, y, z), edges), sep='\t')
    # print(check_in_figure((-1, -1, -1.1), edges), sep='\t')
    # print(check_in_figure((1, 1, 1), edges), sep='\t')

    # находим и проверяем все точки пересечения с плоскостями цилиндра
    inside, outside = 0, 0
    result = []
    for edge in edges:
        ang = scalar(edge[:4], cylinder_vec)
        if ang == 0 and cylinder_radius > abs(plosk_by_point_and_norm(vertices[edge[4][0]], edge[:4], cylinder_point)):
            # if cylinder_radius > plosk_by_point_and_norm(vertices[edge[4][0]], edge[:4], cylinder_point):
            # print(vertices[edge[4][0]], edge[:4], cylinder_point)
            # input()
            # print(edge, plosk_by_point_and_norm(vertices[edge[4][0]], edge[:4], cylinder_point))
            # print(abs(plosk_by_point_and_norm(vertices[edge[4][0]], edge[:4], cylinder_point)))
            # print("Не влазим!")
            return "0"
        elif ang != 0:
            t = edge[0] * cylinder_vec[0] + edge[1] * cylinder_vec[1] + edge[2] * cylinder_vec[2]
            oth = edge[0] * cylinder_point[0] + edge[1] * cylinder_point[1] + edge[2] * cylinder_point[2] + edge[3]
            # print(edge)
            # print(t, oth, ang)
            t = -oth / t
            # print(t)
            cross_point = t * cylinder_vec[0] + cylinder_point[0], t * cylinder_vec[1] + cylinder_point[1], t * cylinder_vec[2] + cylinder_point[2]
            if abs(ang) != 1:
                # тк не перпендикулярно, можем спроецировать прямую в грань и проверить, что точка лежит в фигуре
                otcl = -edge[0] * cylinder_point[0] + -edge[1] * cylinder_point[1] + -edge[2] * cylinder_point[2] - edge[3]
                point = [edge[0] * otcl + cylinder_point[0], edge[1] * otcl + cylinder_point[1], edge[2] * otcl + cylinder_point[2]]
                direction = make_ed(vec_subtraction(point, cross_point))
                if plosk_by_point_and_norm(cylinder_point, cylinder_vec, cross_point) < 0:
                    ang = -ang
                check_point = vec_addition(vec_multiplication_by_const(direction, cylinder_radius / ang), cross_point)
                # print("Эта штука не перпендикулярна, надо делать проекцию и проверять, что результат в фигуре (на границе)")
                # print(cross_point, abs(degrees(acos(ang))-90), ang)
                # print(subtr([-a * otcl + x0, -b * otcl + y0, -c * otcl + z0], point), point)
                # вторая точка
                # print(edge[:4], point)
                # print(otcl)
                # print(edge[0] * cross_point[0] + edge[1] * cross_point[1] + edge[2] * cross_point[2] + edge[3])
                # print(edge[0] * point[0] + edge[1] * point[1] + edge[2] * point[2] + edge[3])
                # print(cross_point, point)
                # print(vec_subtraction(point, cross_point))
                # print(cross_point, edge[:3])
                # print(cross_point, '???')
                # print(scalar(cylinder_vec, edge[:3]))
                # print('out' if scalar(cylinder_vec, edge[:3]) > 0 else 'in')
                # print(cylinder_radius / ang, ang)
                # print(direction, ang)
                # print(vec_multiplication_by_const(direction, cylinder_radius / ang))
                # print(edge[:3])
                # print(check_point, plosk_by_point_and_norm(cylinder_point, cylinder_vec, check_point))
                # for edge in edges:
                #     print(edge, check_point)
                #     print(dist_point_plane(check_point, edge))
                # print(plosk_by_point_and_norm(cylinder_point, cylinder_vec, check_point), check_in_figure(check_point, edges))
                if check_in_figure(check_point, edges):
                    # print(check_point)
                    t = round(plosk_by_point_and_norm(cylinder_point, cylinder_vec, check_point), 5)
                    if cylinder_radius / tan(asin(scalar(cylinder_vec, edge[:3]))) > 0:
                        outside = t
                    else:
                        inside = t
            else:
                # print("Эта штука перпендикулярна, надо проверять, что круг влазит в грань")
                good = True
                for index in range(len(edge[4])):
                    # p1 = cross_point
                    # v1 = cylinder_vec
                    # p2 = vertices[edge[4][0]]
                    # v2 = make_ed(vec_subtraction(vertices[edge[4][index]], vertices[edge[4][(index + 1) % len(edge[4])]]))
                    # norm = make_ed(vec_multiplication(v1, v2))
                    # print(vertices[edge[4][index]][1:], vertices[edge[4][(index + 1) % len(edge[4])]][1:])
                    # print(cylinder_point[1:])
                    # print(v1, v2)
                    # print(vertices[edge[4][index]], norm)
                    # print(abs(plosk_by_point_and_norm(cross_point, make_ed(vec_multiplication(cylinder_vec, make_ed(vec_subtraction(vertices[edge[4][index]], vertices[edge[4][(index + 1) % len(edge[4])]])))), vertices[edge[4][index]])))
                    if cylinder_radius > abs(plosk_by_point_and_norm(cross_point, make_ed(vec_multiplication(cylinder_vec, make_ed(vec_subtraction(vertices[edge[4][index]], vertices[edge[4][(index + 1) % len(edge[4])]])))), vertices[edge[4][index]])):
                        good = False
                        break
                    # print()
                if not good:
                    # print("Радиус НЕ влез!")
                    pass
                else:
                    x, y, z = cross_point
                    if cylinder_vec[0] != 0:
                        t = (x - cylinder_point[0]) / cylinder_vec[0]
                        # print(1, t)
                    elif cylinder_vec[1] != 0:
                        t = (y - cylinder_point[1]) / cylinder_vec[1]
                        # print(2, t)
                    else:
                        t = (z - cylinder_point[2]) / cylinder_vec[2]
                    if t not in result:
                        result.append(round(t, 5))

    # проверка, что есть точки и вывод итогового ответа
    if len(result) == 2:
        # print(result)
        return '1 ' + ' '.join(map(str, sorted(result)))
    elif len(result) == 1:
        return '1 ' + ' '.join(map(str, sorted([result[0], (inside if inside else outside)])))
    elif len(result) == 0:
        if inside < outside:
            return f'1 {inside} {outside}'
        else:
            return '0'
    else:
        return '0'

if __name__ == '__main__':
    with open("inputs/input.txt", "r") as input_file:
        with open("output.txt", "w") as output_file:
            output_file.write(calculate(input_file))


import json

from flask import Blueprint, request, jsonify
import requests as r

lines_app = Blueprint('lines', __name__)
LIST_URL = 'http://127.0.0.1:8000/api/lines/'
DETAIL_URL = LIST_URL + '{}/'

@lines_app.route('', methods=['GET'])
def list():
    req = r.get(LIST_URL, headers=request.headers)
    data = req.json()
    return jsonify(data)

# @lines_app.route('/<int:line_id>/', methods=['GET'])
@lines_app.route('/<int:line_id>', methods=['GET'])
def detail(line_id):
    req = r.get(DETAIL_URL.format(line_id), headers={'authorization': request.headers['authorization']})
    data = req.json()
    return jsonify(data)

@lines_app.route('/', methods=['POST'])
def new_line():
    data = request.json
    req = r.post(LIST_URL, data=json.dumps(data), headers={'content-type': 'application/json', 'authorization': request.headers['authorization']})
    data = req.json()
    return jsonify(data), 201

# @lines_app.route('/<int:line_id>/', methods=['PUT'])
@lines_app.route('/<int:line_id>', methods=['PUT'])
def update_line(line_id):
    data = request.json
    data.pop('id')
    data.pop('calls_to_center')
    data.pop('date_joined')
    req = r.get(DETAIL_URL.format(line_id), headers={'authorization': request.headers['authorization']})
    db_line = req.json()
    db_line.update(data)
    req = r.put(DETAIL_URL.format(line_id), data=json.dumps(db_line), headers={'content-type': 'application/json', 'authorization': request.headers['authorization']})
    data = req.json()
    return jsonify(data)

# @lines_app.route('/<int:line_id>/', methods=['DELETE'])
@lines_app.route('/<int:line_id>', methods=['DELETE'])
def delete_line(line_id):
    r.delete(DETAIL_URL.format(line_id), headers=request.headers)
    return '', 204


from secrets import randbelow
from time import time
import numpy as np
from matplotlib import pyplot as plt
import cv2

# ======================== INPUT IMAGE ========================
def input_img(image_name: str):
    # Retorna as dimencoes da imagem e um objeto que é a sua imagem(img)
    image = cv2.imread(image_name)
    print("Dimensões da imagem: " + str(image.shape))
    altura, largura, canais = image.shape
    print(f'Largura: {largura}')
    print(f'Altura: {altura}')
    print(f'Canais de cores: {canais}')
    return image, altura, largura, canais

# ======================== SHOW IMAGE ========================
def show_image(image):
    # Mostra Uma imagem
    my_dpi = 96
    plt.figure(figsize=(15/1087*1200, 15/1087*1200), dpi=my_dpi, frameon = False)
    plt.axis('off')
    plt.imshow(image)
    #plt.savefig('ada_file.jpg', format="jpg", dpi=my_dpi, bbox_inches='tight', pad_inches=0)
    plt.show()

# ======================== IMAGE BUILDER ========================
def image_builder(altura: int, largura: int, canais: int, intarray: list):
    # Retorna uma imagem com o conteudo intarray
    return np.ndarray(shape=(altura, largura, canais), dtype=int, buffer=np.array(list(intarray)))

# ======================== CRIPTOGRAFAR IMAGEM ========================
def criptografar(image, altura: int, largura: int, canais: int, operacao: str):
    # ^ XOR
    # & AND
    # | OR
    t = time()
    op = {
        'AND': lambda a, b: a & b,
        'OR': lambda a, b: a | b,
        'XOR': lambda a, b: a ^ b
    }
    ENC = []
    PWD = []
    for y in range(0, altura):
        for x in range(0, largura):
            for z in range(canais):
                mini_chave = randbelow(256)  # 8 bits -> 2**8 = 256
                PWD.append(mini_chave)
                ENC.append(op[operacao](int(image[y][x][z]), mini_chave))

    print('Tempo de criptografia:', time() - t, 'sec')

    return ENC


class Employee:
    def __init__(self,  full_name='', position=None, zp=0, N=0):
        self.full_name = full_name.split()[0].strip() + '\n' + full_name.split()[-1].strip()
        self.position = position
        self.zp = zp*N

class ITEmployee(Employee):
    def __init__(self, *args, **kwargs):
        Employee.__init__(self, *args, **kwargs)
        self.skills = []
        self.experience = 0

    def add_skills(self, new_skills):
        self.skills.append(new_skills)

    def find_experience(self):
        if self.experience <=2:
            result = str('Invalid value')
        elif self.experience < 3:
            result = str('Junior')
        elif 3 <= self.experience <= 6:
            result = str('Middle')
        else:
            result = str('Senior')
        return result

a=ITEmployee('Юля Кравчук', 'Middle', 100500, 12)
a.experience=6
a1=a.find_experience()
a.add_skills(['QATest', 'AutoTests'])
a.add_skills('Python')
print(a.full_name, a.zp, a1, a.skills, sep='\n')


class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        mx = amount + 1
        dp = [mx] * mx
        dp[0] = 0

        for a in range(1, mx):
            for c in coins:
                if a - c >= 0:
                    dp[a] = min(dp[a], 1 + dp[a - c])

        return dp[amount] if dp[amount] != mx else -1


import sys, argparse
import youtube_dl

# Coded by Suleiman Alothman @sulealothman

parser = argparse.ArgumentParser(
	description="Script name : Download-Youtube, Ver. : 0.1, Author : SuleAlOthman",
	usage=""" Example #1 : python3 download-youtube.py -l https://www.youtube.com/watch?v=XXXXXXXXXXX \r\n
	Example #2 : python3 download-youtube.py -f links.txt \r\n
	Example #3 : python3 download-youtube.py -f links.txt -e mp4 \r\n""")
parser.add_argument('-f', '--file',type=str,help='Text file for links')
parser.add_argument('-l', '--link',type=str,help='Video Url')
parser.add_argument('-e', '--extension',nargs='?',default="mp3",type=str,help='extension file : mp3 or mp4')
args = parser.parse_args()

def youtubeDownload(url,ext="mp3"):
	if ext == "mp3":
		ydl_opts = {
			'format': 'bestaudio/best',
			'postprocessors': [{
				'key' : 'FFmpegExtractAudio',
				'preferredcodec': 'mp3',
				'preferredquality': '192',
				}],
		}
	else:
		ydl_opts = {
			'format' : 'bestvideo',
			'postprocessors' : [{
				'key' : 'FFmpegVideoConvertor',
				'preferedformat' : 'mp4',
				}]
		}

	with youtube_dl.YoutubeDL(ydl_opts) as ydl:
		ydl.download([url])

if __name__ == "__main__":

	if(args.file != None):
		path = args.file
		try:
			linksFile = open(path, "r")
			for link in linksFile:
				try:
					youtubeDownload(link, args.extension.strip())
				except:
					print(link + " : is incorrupt")
		except:
			print("Not found the file")
		print("\r\n- #   Finished downloading ..")
		sys.exit()
	elif(args.link != None):
		url = args.link
		try:
			youtubeDownload(url, args.extension.strip())
		except:
			print(url + " incurrept link")
	else:
		url = input("Enter youtube url : ")
		try:
			youtubeDownload(url, args.extension.strip())
		except:
			print(url + "incurrept link")

print("\r\n- #   Finished downloading ..")


import json
import os
import PyPDF2

from braces.views import AjaxResponseMixin, JSONResponseMixin
from django.conf import settings
from django.contrib import messages
from django.core.urlresolvers import reverse
from django.http import HttpResponse
from django.shortcuts import redirect, render, get_object_or_404
from django.views.generic import View, TemplateView
# from django.views.generic.edit import CreateView
from wand.image import Image

from maps.forms import BookForm, MapAttributeForm, PartForm
from maps.models import MapAttribute, ImagePart, Part, PartFile, Motorcycle

class HomeView(TemplateView):
    template_name = "home.html"

class ImageMapView(View):
    # template_name = "index.htm"

    def get(self, request, *args, **kwargs):
        map_attrs = MapAttribute.objects.all()
        ctx = {
            'map_attrs': map_attrs,
        }
        return render(request, "index.htm", ctx)

    def post(self, request, *args, **kwargs):

        image_coords = request.POST['img_coords'].replace('\n', '')
        list_shp_coords = image_coords.split('\r')

        for shape_cord in list_shp_coords:
            if shape_cord.startswith('shape'):
                print(shape_cord.replace("shape- ", ""))
            else:
                print(shape_cord.replace("coords- ", ""))

        return render(request, "index.htm", {})

class UploadBook(View):

    def get(self, request, *args, **kwargs):
        form = BookForm()
        images = PartFile.objects.all()

        ctx = {
            "form": form,
            "images": images,
        }
        return render(request, "maps/show_images.html", ctx)

    def post(self, request, *args, **kwargs):

        form = BookForm(request.POST, request.FILES)
        if form.is_valid():
            book = form.save()

            full_filepath = os.path.join(settings.MEDIA_ROOT, "books", str(book.pk))
            full_filepath_jpg = os.path.join(full_filepath, "jpg")

            os.makedirs(full_filepath_jpg, exist_ok=True)

            # TODO: move to celery task
            inputpdf = PyPDF2.PdfFileReader(open(book.file.file.name, "rb"))

            # Separate pdf pages
            for i in range(inputpdf.numPages):
                # TODO: rewrite with in-memory files
                output = PyPDF2.PdfFileWriter()
                output.addPage(inputpdf.getPage(i))
                file_write = os.path.join(full_filepath, "%s-%s.pdf" % (str(book.pk), i))
                media_url = os.path.join("books", str(book.pk), "jpg", "%s-%s.jpg" % (str(book.pk), i + 1))
                with open(file_write, "wb") as outputStream:
                    output.write(outputStream)
                # Converting one page into JPG
                img_path = os.path.join(full_filepath_jpg, "%s-%s.jpg" % (str(book.pk), i + 1))
                with Image(filename=file_write+"[0]", resolution=600) as img:
                    img.save(filename=img_path)
                    image_part = ImagePart.objects.create(part_file=book, page=i+1)
                    image_part.image.name = media_url
                    image_part.save()

                try:
                    os.remove(file_write)
                except OSError:
                    pass

            return redirect(reverse('upload_book'))
        else:
            messages.error(request, "Form is invalid")

        images = PartFile.objects.all()
        ctx = {
            "form": form,
            "images": images,
        }
        return render(request, "maps/show_images.html", ctx)

class AddPartsView(View):

    def get(self, request, *args, **kwargs):

        pk = kwargs['id']
        image = PartFile.objects.get(pk=pk)
        parts = Part.objects.all()

        form_part = PartForm()
        ctx = {
            "image": image,
            "parts": parts,
            "form_part": form_part,
        }
        return render(request, "maps/add_parts.html", ctx)

    def post(self, request, *args, **kwargs):

        pk = kwargs['id']
        img = request.POST.get('image')
        parts = request.POST.getlist('parts[]')
        form_part = PartForm(request.POST)

        if parts:
            imgs = PartFile.objects.get(pk=img)
            for part in parts:
                img_part = Part.objects.get(pk=part)
                image_part = ImagePart(image=imgs, part=img_part)
                image_part.save()

        elif form_part.is_valid():
            form_part.save()
        else:
            messages.error(request, "Form is Invaid")

        return redirect(reverse('add_part', kwargs={'id': pk}))

class MapCreate(View):

    def get(self, request, *args, **kwargs):

        form = MapAttributeForm()
        map_attrs = MapAttribute.objects.all()

        ctx = {
            "form": form,
            "map_attrs": map_attrs,
        }
        return render(request, "maps/mapattribute_form.html", ctx)

    def post(self, request, *args, **kwargs):

        form = MapAttributeForm(request.POST)
        map_attrs = MapAttribute.objects.all()

        ctx = {
            "form": form,
            "map_attrs": map_attrs,
        }
        if form.is_valid():
            form.save()
            return render(request, "maps/mapattribute_form.html", ctx)
        else:
            messages.error(request, "Form is Invaid")

        return redirect(reverse('map_create'))

# class PartCreate(CreateView):
#     model = Part
#     fields = ['part']
#     success_url = '/images/'

class BookPageView(JSONResponseMixin, AjaxResponseMixin, View):
    def process_pages(self, book_id, page_id):
        image = ImagePart.objects.filter(part_file__pk=book_id, page=page_id).first()
        prev = ImagePart.objects.filter(part_file__pk=book_id, page=page_id-1).first()
        next_ = ImagePart.objects.filter(part_file__pk=book_id, page=page_id+1).first()
        res = {'image': image, 'page': page_id, 'next': None, 'prev': None}
        if prev:
            res['prev'] = prev
        if next_:
            res['next'] = next_
        return res

    def get(self, request, *args, **kwargs):
        book = PartFile.objects.get(pk=kwargs['book_id'])
        page_id = int(kwargs.get('page_id', 1))
        ctx = {'book': book}
        ctx.update(self.process_pages(kwargs['book_id'], page_id=page_id))

        return render(request, "maps/book.html", ctx)

    def post_ajax(self, request, *args, **kwargs):
        res = self.process_pages(kwargs.get('book_id'), int(kwargs.get('page_id')))
        ctx = {
            'image': res['image'].image.url,
            'prev': res['prev'].image.url if res['prev'] else None,
            'next': res['next'].image.url if res['next'] else None,
            'page': res['page']
        }
        return HttpResponse(json.dumps(ctx), content_type="application/json")

class MotorcycleView(View):
    def get(self, request, *args, **kwargs):
        moto = get_object_or_404(Motorcycle, pk=kwargs['moto_id'])
        ctx = {"motorcycle": moto}
        return render(request, "maps/motorcycle.html", ctx)


from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from os import path
import os
from flask_login import LoginManager
#from celery import Celery

db = SQLAlchemy()
DB_NAME = "database.db"
ALLOWED_EXTENSIONS = {'fastq'}

def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'hjshjhdjahdfgdsfdss kjshkjdhjs'
    app.config['SQLALCHEMY_DATABASE_URI'] = f'sqlite:///{DB_NAME}'
    UPLOAD_FOLDER  ='./uploads'
    app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
    db.init_app(app)

    #app.config['CELERY_BROKER_URL'] = 'redis://localhost:6379/0'
    #app.config['CELERY_RESULT_BACKEND'] = 'redis://localhost:6379/0'
    #celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL'])
    #celery.conf.update(app.config)

    from .views import views
    from .auth import auth

    app.register_blueprint(views, url_prefix='/')
    app.register_blueprint(auth, url_prefix='/')

    from .models import User, Upload

    with app.app_context():
        db.create_all()

    login_manager = LoginManager()
    login_manager.login_view = 'auth.login'
    login_manager.init_app(app)

    @login_manager.user_loader
    def load_user(id):
        return User.query.get(int(id))

    return app

def create_database(app):
    if not path.exists('website/' + DB_NAME):
        db.create_all(app=app)
        print('База данных создана')


import io
import sys

_INPUT = """\
6
AtCoder
Aa
atcoder
Perfect
"""

sys.stdin = io.StringIO(_INPUT)
case_no=int(input())
for __ in range(case_no):
  S=input()
  c,s=0,0
  for i in range(len(S)):
    if S[i].upper()==S[i]:
      c=1
    if S[i].lower()==S[i]:
      s=1
  if c==1 and s==1 and len(set(S))==len(S):
    print('Yes')
  else: print('No')


overallCategory = "x"
txt = "welcome [to the jungle]"

def main():
	f = open("flowCategories.txt", "r")
	global writeFile
	writeFile = open("separatedByCategories.txt", "w")
	for x in f:
  		parseCategory(x)

def parseCategory(txt):
	x = txt.split('[')
	phrase = x[0]
	category = x[1].split(']')[0]
	global overallCategory
	global writeFile
	if(overallCategory != category):
		overallCategory = category
		writeFile.write("\n\n[" + category + "]\n\n")
	writeFile.write(phrase + "\n")

main()


from settings import *
import random
import pygame
def invert(a):
    k = ''
    for i in range(len(a)):
        if a[i] == "1":
            k += "1"
        else:
            k += '0'
    return k
def transcript(a):
    k = ''
    for i in range(len(a)):
        if a[i] == "True":
            k += "1"
        else:
            k += "0"
    return k

def start_point_generate(n, m):
    return (0,0)

def finish_point_generate(start, n, m):
    #конец лабиринта"
    return n - 1 - start[0], m - 1 - start[1]
def transition_choice(x, y, rm):
    #Выбор пути"
    choice_list = []
    if x > 0:
        if not rm[x - 1][y]:
            choice_list.append((x - 1, y))
    if x < len(rm) - 1:
        if not rm[x + 1][y]:
            choice_list.append((x + 1, y))
    if y > 0:
        if not rm[x][y - 1]:
            choice_list.append((x, y - 1))
    if y < len(rm[0]) - 1:
        if not rm[x][y + 1]:
            choice_list.append((x, y + 1))
    if choice_list:
        nx, ny = random.choice(choice_list)
        if x == nx:
            if ny > y:
                tx, ty = x * 2, ny * 2 - 1
            else:
                tx, ty = x * 2, ny * 2 + 1
        else:
            if nx > x:
                tx, ty = nx * 2 - 1, y * 2
            else:
                tx, ty = nx * 2 + 1, y * 2
        return nx, ny, tx, ty
    else:
        return -1, -1, -1, -1

def create_labyrinth(n = 5, m = 5):
    "Генерация лабиринта"
    reach_matrix = []
    for i in range(n):  # создаём матрицу достижимости ячеек
        reach_matrix.append([])
        for j in range(m):
            reach_matrix[i].append(False)
    transition_matrix = []
    for i in range(n * 2 - 1):  # заполнение матрицы переходов
        transition_matrix.append([])
        for j in range(m * 2 - 1):
            if i % 2 == 0 and j % 2 == 0:
                transition_matrix[i].append(True)
            else:
                transition_matrix[i].append(False)
    start = start_point_generate(n, m)
    finish = finish_point_generate(start, n, m)
    list_transition = [start]
    x, y = start
    reach_matrix[x][y] = True
    x, y, tx, ty = transition_choice(x, y, reach_matrix)
    for i in range(1, m * n):
        while not (x >= 0 and y >= 0):
            x, y = list_transition[-1]
            list_transition.pop()
            x, y, tx, ty = transition_choice(x, y, reach_matrix)
        reach_matrix[x][y] = True
        list_transition.append((x, y))
        transition_matrix[tx][ty] = True
        x, y, tx, ty = transition_choice(x, y, reach_matrix)
    return transition_matrix, start, finish  # возвращаем матрицу проходов,начальную и конечную точку
nn = 13
mm = nn -1

mapp = list(create_labyrinth(nn, mm))

startpos = mapp[-2]
endpos = mapp[-1]
mapp.pop()
mapp.pop()
s = mapp[0]
MAPP = []
for i in range(len(s)):
    stroka = s[i]
    k = ""
    for j in range(len(stroka)):
        if stroka[j] == True:
            k += "0"
        else:
            k += "1"
    MAPP.append(k)
boardedmap = ["1"*(nn*2-1)]
for i in range(mm * 2 + 1):
    boardedmap.append("1"+MAPP[i] + "1")
boardedmap.append("1"*(nn*2-1))
#текстовая карта прямоугольников на карте
text_map = boardedmap

game_map = set()
mini_map = set()
collision_walls = []

for i, row in enumerate(text_map):
    for j, obst in enumerate(row) :
        if obst == '1':
            game_map.add((j * PIX, i * PIX))
            mini_map.add((j * MINIMAP_PIX, i * MINIMAP_PIX))
            collision_walls.append(pygame.Rect(j * PIX, i * PIX, PIX, PIX))
print(endpos)


import pandas
import datetime

import config
import database

def get_key_1(date, common_key, payment_amount, status):
    key = list()
    for i in range(len(date)):
        key_temp = '_'.join([str(date[i].date()), str(common_key[i]), str(float(payment_amount[i])), str(status[i])])
        key.append(key_temp)
    return key

def get_key_2(date, common_key, status):
    key = list()
    for i in range(len(date)):
        key_temp = '_'.join([str(date[i].date()), str(common_key[i]), str(status[i])])
        key.append(key_temp)
    return key

def read_kaspi(file_name):
    file_path = config.attachment_dir + '/' + file_name
    file = pandas.read_excel(file_path, skiprows=0, skipfooter=0)
    date = file['Дата транзакции']
    order_id = file['Номер бронирования']
    payment_amount_temp = file['Сумма']
    payment_type = config.kaspi_name
    payment_reference = file['Номер Транзакции']
    status = list()
    payment_amount = list()
    for payment_sum in payment_amount_temp:
        temp = float(payment_sum)
        payment_amount.append(abs(temp))
        if temp > 0:
            status.append(config.status_payment)
        else:
            status.append(config.status_refund)
    key_1 = get_key_1(date, order_id, payment_amount, status)
    key_2 = get_key_2(date, order_id, status)
    return date, order_id, payment_amount, payment_type, payment_reference, status, key_1, key_2
def read_rps(file_name):
    file_path = config.attachment_dir + '/' + file_name
    file = pandas.read_excel(file_path, skiprows=1, skipfooter=1)
    date = file['Дата']
    order_id = file['Номер брони']
    payment_amount = file['Сумма платежа']
    payment_type = config.rps_name
    payment_reference = file['# Кассовой операции']
    status_temp = file['Код результата']
    status = list()
    succeed = list()
    for code in status_temp:
        if int(code) == 0:
            status.append(config.status_payment)
        else:
            status.append(config.status_refund)
        succeed.append('1')
    key_1 = get_key_1(date, order_id, payment_amount, status)
    key_2 = get_key_2(date, order_id, status)
    return date, order_id, payment_amount, payment_type, payment_reference, status, key_1, key_2
def read_processing(file_name):
    file_path = config.attachment_dir + '/' + file_name
    file = pandas.read_excel(file_path, skiprows=4, skipfooter=0)
    date = file['AlmDate']
    order_id = file['Order ID']
    payment_amount = file['Tran_amoun']
    payment_type = config.processing_name
    payment_reference = file['RRN(Bank)']
    types = file['Type']
    succeed = file['Resp']
    for i in range(len(succeed)):
        if succeed[i] == 'Decline':
            payment_amount.at[i] = 0

    status = list()
    for type in types:
        if str(type) == 'A':
            status.append(config.status_payment)
        elif str(type) == 'F':
            status.append(config.status_refund)

    key_1 = get_key_1(date, order_id, payment_amount, status)
    key_2 = get_key_2(date, order_id, status)
    return date, order_id, payment_amount, payment_type, payment_reference, status, key_1, key_2
def read_qazkom(file_name):
    file_path = config.attachment_dir + '/' + file_name
    file = pandas.read_html(file_path)
    # concatenate all the tables that contain needed information
    total_table = list()
    tables = file[4:]
    for table in tables:
        names = table.iloc[0].values.tolist()
        table = pandas.DataFrame.from_records(data=table.values[1:], columns=names)
        total_table.append(table)
    file = pandas.concat(total_table, ignore_index=True)
    date = file['Post Date']
    date = pandas.to_datetime(date)
    order_id = file['A Code']
    payment_amount_temp = file['Settl.Amount']
    payment_type = config.qazkom_name
    payment_reference = file['Ret Ref Number']
    status = list()
    succeed = list()
    payment_amount = list()
    for payment_sum in payment_amount_temp:
        temp = float(payment_sum)
        payment_amount.append(abs(temp))
        if temp > 0:
            status.append(config.status_payment)
        else:
            status.append(config.status_refund)
        succeed.append('1')
    key_1 = get_key_1(date, order_id, payment_amount, status)
    key_2 = get_key_2(date, order_id, status)
    return date, order_id, payment_amount, payment_type, payment_reference, status, key_1, key_2

def files_into_database(file_names):
    for file_name in file_names:
        payment_type = ''

        # kaspi
        if file_name.count(config.kaspi_name) != 0:
            date, order_id, payment_amount, payment_type, payment_reference, status, key_1, key_2 = read_kaspi(file_name)
        # rps
        if file_name.count(config.rps_name) != 0:
            date, order_id, payment_amount, payment_type, payment_reference, status, key_1, key_2 = read_rps(file_name)
        # processing
        if file_name.count(config.processing_name) != 0:
            date, order_id, payment_amount, payment_type, payment_reference, status, key_1, key_2 = read_processing(file_name)
        # qazkom
        if file_name.count(config.qazkom_name) != 0:
            date, order_id, payment_amount, payment_type, payment_reference, status, key_2, key_2 = read_qazkom(file_name)

        if payment_type:
            date_created = datetime.datetime.now()
            database.update_payment_trans_table(date, date_created, order_id, payment_amount,
                   payment_type, payment_reference, status, key_1, key_2)


import rospy
import serial
import string
import math
import sys

#from time import time
from sensor_msgs.msg import Imu
from tf.transformations import quaternion_from_euler
from dynamic_reconfigure.server import Server
from razor_imu_9dof.cfg import imuConfig

PAUSE_LOGGING       =  b' '    #  Space - Pause SD/UART logging
DISABLE_TIME        =  b't'    #  Disable time log (milliseconds)
DISABLE_COMPASS     =  b'm'    #  Disable Compass
ENABLE_QUAT         =  b'Q'
ENABLE_EULER        =  b'E'

# Covariance estimation:
ORIENT_COVARIANCE = [
0.005 , 0 , 0,
0, 0.005, 0,
0, 0, 0.005
]

ANGL_VEL_COVARIANCE = [
0.02, 0 , 0,
0 , 0.02, 0,
0 , 0 , 0.02
]

LIN_ACCEL_COVARIANCE = [
0.04 , 0 , 0,
0 , 0.04, 0,
0 , 0 , 0.04
]

imu_yaw_calibration = 0.
# Callback for dynamic reconfigure requests
def reconfig_callback(config, level):
    global imu_yaw_calibration
    rospy.loginfo("""Reconfigure request for yaw_calibration: %d""" %(config['yaw_calibration']))
    imu_yaw_calibration = config['yaw_calibration']
    rospy.loginfo("Set imu_yaw_calibration to %d" % (imu_yaw_calibration))
    return config

# ####################### ROS SET UP #########################
rospy.init_node("razor_node")
srv = Server(imuConfig, reconfig_callback)     # define dynamic_reconfigure callback
pub = rospy.Publisher('imu', Imu, queue_size=1) #We only care about the most recent measurement, i.e. queue_size=1

# ################### SERIAL PORT SET UP ######################
default_port='/dev/ttyACM1'
# Check your COM port and baud rate
rospy.loginfo("Opening %s...", default_port)
try:
    ser = serial.Serial(port=default_port, baudrate=115200, timeout=1)
except serial.serialutil.SerialException:
    rospy.logerr("IMU not found at port "+port + ". Did you specify the correct port in the launch file?")
    #exit
    sys.exit(0)

# ################### INIT & CALIBRATION ######################

#accelerometer
accel_x_min = rospy.get_param('~accel_x_min', -250.0)
accel_x_max = rospy.get_param('~accel_x_max', 250.0)
accel_y_min = rospy.get_param('~accel_y_min', -250.0)
accel_y_max = rospy.get_param('~accel_y_max', 250.0)
accel_z_min = rospy.get_param('~accel_z_min', -250.0)
accel_z_max = rospy.get_param('~accel_z_max', 250.0)
# gyroscope
gyro_average_offset_x = rospy.get_param('~gyro_average_offset_x', 0.0)
gyro_average_offset_y = rospy.get_param('~gyro_average_offset_y', 0.0)
gyro_average_offset_z = rospy.get_param('~gyro_average_offset_z', 0.0)
# magnetometer
magn_x_min = rospy.get_param('~magn_x_min', -600.0)
magn_x_max = rospy.get_param('~magn_x_max', 600.0)
magn_y_min = rospy.get_param('~magn_y_min', -600.0)
magn_y_max = rospy.get_param('~magn_y_max', 600.0)
magn_z_min = rospy.get_param('~magn_z_min', -600.0)
magn_z_max = rospy.get_param('~magn_z_max', 600.0)

calibration_magn_use_extended = rospy.get_param('~calibration_magn_use_extended', False)
magn_ellipsoid_center = rospy.get_param('~magn_ellipsoid_center', [0, 0, 0])
magn_ellipsoid_transform = rospy.get_param('~magn_ellipsoid_transform', [[0, 0, 0], [0, 0, 0], [0, 0, 0]])
imu_yaw_calibration = rospy.get_param('~imu_yaw_calibration', 0.0)

#@TODO : Calibration

roll=0
pitch=0
yaw=0
seq=0
degrees2rad = math.pi/180.0

rospy.loginfo("Giving the razor IMU board 3 seconds to boot...")
rospy.sleep(3) # Sleep for 5 seconds to wait for the board to boot

#################################
### IMU Board Configuration #####
#################################
ser.write(DISABLE_TIME)
ser.write(DISABLE_COMPASS)
ser.write(ENABLE_EULER)
ser.write(ENABLE_QUAT)

imuMsg = Imu()
# Orientation covariance estimation
imuMsg.orientation_covariance = ORIENT_COVARIANCE
imuMsg.angular_velocity_covariance = ANGL_VEL_COVARIANCE
imuMsg.linear_acceleration_covariance = LIN_ACCEL_COVARIANCE

# @TODO : bug when disable and enable TIME

sample = ser.readline()
print("IMU Format:<accelX>, <accelY>, <accelZ>, <gyroX>, <gyroY>, <gyroZ>, <quatW>, <quatX>, <quatY>, <quatZ>, <pitch>, <roll>, <yaw>")
print("Sample Data: " +  sample)

while not rospy.is_shutdown():
    line = ser.readline()
    measurement = string.split(line,",")    # Fields split
    if len(measurement) > 2:
#@TODO: CORRECT IMU MEASUREMENT
# Unceted/Kalman filter? robot_localization package

        # Followed REP-103 ROS
        # http://www.ros.org/reps/rep-0103.html

	# Linear Acceleration
        imuMsg.linear_acceleration.x = float(measurement[0])
        imuMsg.linear_acceleration.y = float(measurement[1])
        imuMsg.linear_acceleration.z = -float(measurement[2])   # Gravity force should pull down

        # Angular Velocity
        imuMsg.angular_velocity.x = float(measurement[3])
        imuMsg.angular_velocity.y = float(measurement[4])
        imuMsg.angular_velocity.z = float(measurement[5])

        # Euler angle
        pitch = float(measurement[9])*degrees2rad
        roll  = float(measurement[10])*degrees2rad
        yaw   = float(measurement[11])*degrees2rad

        # Quaterion
        imuMsg.orientation.w = float(measurement[6])
        imuMsg.orientation.x = float(measurement[7])
        imuMsg.orientation.y = float(measurement[8])
        imuMsg.orientation.z = float(measurement[9])

# 	q = quaternion_from_euler(yaw, pitch, roll, 'rzyx')
#        imuMsg.orientation.w = q[0]
#        imuMsg.orientation.x = q[1]
#        imuMsg.orientation.y = q[2]
#        imuMsg.orientation.z = q[3]
        imuMsg.header.stamp= rospy.Time.now()
        imuMsg.header.frame_id = 'base_imu_link'
        imuMsg.header.seq = seq
        seq = seq + 1
        pub.publish(imuMsg)

ser.close()


#!/usr/bin/env python3
import click
from krunner.conf import update_config_value
from krunner.utils import logger
from krunner import __version__
from krunner.utils.errors import ParamsError
from testcase import TestSuiteBase

logo = """
    __ __ ____
   / //_// __ \__  ______  ____  ___  _____
  / ,<  / /_/ / / / / __ \/ __ \/ _ \/ ___/
 / /| |/ _, _/ /_/ / / / / / / /  __/ /
/_/ |_/_/ |_|\__,_/_/ /_/_/ /_/\___/_/ """

logger.info(f"{logo}  {__version__} \n")

@click.command()
@click.option('-t', '--test_type', default='', type=click.Choice(['android', 'ios']), help='test type, android/ios')
@click.option('-n', '--pkg_name', default='', type=str, help='package_name for android; bundleid for ios')
@click.option('-p', '--pkg_path', default='', type=str, help='package_download_url or local_package_path')
@click.option('-s', '--serialno', type=str, multiple=True, help='the android device serial number or ios device udid')
@click.option('-H', '--host', default='127.0.0.1', type=str,
              help='the android remote adb server host, [default=127.0.0.1]')
@click.option('-P', '--port', default=5037, type=int, help='the android remote adb server port, [default=5037]')
@click.option('-w', '--wda_path', default='', type=str, help='wda xcode project path')
@click.option('--wda_proxy_url', default='', type=str, help='the wda iproxy url, used it to connect wda server')
@click.option('--test_package', type=str, multiple=True,
              help='run tests from test_package, eg: --test_package testcase.ios')
@click.option('--test_module', type=str, multiple=True,
              help='run tests from test_module, eg: --test_module testcase.ios.test_demo')
@click.option('--test_class', type=str, multiple=True,
              help='run tests from module.TestClass, eg: --test_class testcase.ios.test_demo.TestDemo')
@click.option('--test_method', type=str, multiple=True,
              help='run specified test method, eg: --test_method testcase.ios.test_demo.TestDemo.test_example')
@click.option('--run_times', type=int, default=1, help='testcases execute times')
@click.option('--install/--no-install', default=False, help='need to reinstall the app')
@click.option('--execute_id', type=int, help='the task execute id')
@click.option('--re_apk_url', type=str, help='reinstalling apk url')
def main(test_type, pkg_name, pkg_path, serialno, install, host, port, wda_path, wda_proxy_url,
         test_package, test_module, test_class, test_method, run_times, execute_id, re_apk_url):
    if not test_type:
        raise ParamsError('the param: test_type must be set, usage: --test_type xxx')
    if not pkg_name:
        raise ParamsError('the param: pkg_name must be set, usage: --pkg_name xxx')
    if install and not pkg_path:
        raise ParamsError('if you set install , you must set pkg_path, usage: --pkg_path xxx --install')
    if not serialno:
        raise ParamsError('the param: serialno must be set, usage: -s xxx')
    if not test_package and not test_module and not test_class and not test_method:
        raise ParamsError(f'one of the params: test_package or test_module or test_class or test_method must be set')

    update_config_value('test_type', value=test_type)
    update_config_value('pkg_name', value=pkg_name)
    update_config_value('pkg_path', value=pkg_path)
    update_config_value('serialno', value=list(serialno))
    update_config_value('android', 'adb_server_host', value=host)
    update_config_value('android', 'adb_server_port', value=port)
    update_config_value('ios', 'wda_path', value=wda_path)
    update_config_value('ios', 'wda_proxy_url', value=wda_proxy_url)
    update_config_value('ios', 'need_launch_wda', value=False) if wda_proxy_url else update_config_value('ios',
                                                                                'need_launch_wda',
                                                                                value=True)
    update_config_value('execute_id', value=execute_id)
    update_config_value('re_apk_url', value=re_apk_url)

    testsuite = TestSuiteBase(test_package=list(test_package), test_module=list(test_module),
                              test_class=list(test_class),
                              test_method=list(test_method), run_times=run_times, install=install)
    testsuite.run_test()

if __name__ == '__main__':
    main()


def knapsack(profits, weights, capacity):

  dp = [[0 for _ in range(capacity+1)] for _  in range(len(weights)+1)]

  for i in range(1, len(weights)+1):
    for j in range(1, capacity+1):
      if weights[i-1] <= j:
        dp[i][j] = max(dp[i-1][j], dp[i-1][j-weights[i-1]]+profits[i-1])
      else:
        dp[i][j] = dp[i-1][j]

  return dp[-1][-1]

profits = [1, 6, 10, 16]
weights = [1, 2, 3, 5]
capacity = 7

print(knapsack(profits, weights, capacity))


import sys

MaxValue = -1000000000
MinValue = 1000000000

def dfs(nums, plus, minus, mul, div, sum, cnt, n):
    if cnt == n:
        global MaxValue
        global MinValue
        MaxValue = max(MaxValue, sum)
        MinValue = min(MinValue, sum)

    if plus > 0:
        dfs(nums, plus-1, minus, mul, div, sum+nums[cnt], cnt+1, n)
    if minus > 0:
        dfs(nums, plus, minus-1, mul, div, sum-nums[cnt], cnt+1, n)
    if mul > 0:
        dfs(nums, plus, minus, mul-1, div, sum*nums[cnt], cnt+1, n)
    if div > 0:
        dfs(nums, plus, minus, mul, div-1, int(sum /nums[cnt]), cnt+1, n)

if __name__ == '__main__':
    n = int(input())
    nums = list(map(int, sys.stdin.readline().rstrip().rsplit()))
    opers = list(map(int, sys.stdin.readline().rstrip().rsplit()))

    dfs(nums,
        plus=opers[0],
        minus=opers[1],
        mul=opers[2],
        div=opers[3],
        sum=nums[0],
        cnt=1,
        n=n
        )

    print(MaxValue)
    print(MinValue)


import telebot
from telebot import types
import pandas as pd
import math
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)

bot = telebot.TeleBot('***')
df = pd.read_csv('Final_joined.csv')

def haversine(lat1, lon1, lat2, lon2):
    lat1 = math.radians(lat1)
    lon1 = math.radians(lon1)
    lat2 = math.radians(lat2)
    lon2 = math.radians(lon2)
    dlat = lat2 - lat1
    dlon = lon2 - lon1
    a = math.sin(dlat / 2) ** 2 + math.cos(lat1) * math.cos(lat2) * math.sin(dlon / 2) ** 2
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
    distance = 6371.01 * c  # Earth's radius in kilometers
    return distance

def calc_distances(current_lat, current_lon, places_df, lat_column, lon_column, name_column):
    nearest_place = None
    places_df['distance'] = None
    for index, row in places_df.iterrows():
        place_name = row[name_column]
        place_lat = row[lat_column]
        place_lon = row[lon_column]
        distance = haversine(current_lat, current_lon, place_lat, place_lon)
        places_df.loc[index, 'distance'] = distance
    return places_df

users = {}

@bot.message_handler(commands=['start'])
def start(message):
    user_id = message.chat.id

    # Отправляем инструкцию по использованию бота
    instructions = "Давайте начнем!\nИнструкция по использованию бота.\n\n" \
                   "1. Команда для начала поиска - /poisk\n" \
                   "2. Отправьте мне ваше местоположение, чтобы я мог найти ближайшие заправки.\n" \
                   "3. Выберите ваш регион.\n" \
                   "4. Выберите вид топлива.\n" \
                   "5. Я покажу вам ближайшие заправки и их геопозиции.\n"
    bot.send_message(user_id, instructions)
    logger.info(f'User {user_id} started interaction with the bot')

@bot.message_handler(commands=['guide'])
def guide(message):
    user_id = message.chat.id

    # Отправляем инструкцию по использованию бота
    instructions = "Как пользоваться ботом?\n\n" \
                   "1. Команда для начала поиска - /poisk\n" \
                   "2. Отправьте мне ваше местоположение, чтобы я мог найти ближайшие заправки.\n" \
                   "3. Выберите ваш регион.\n" \
                   "4. Выберите вид топлива.\n" \
                   "5. Я покажу вам ближайшие заправки и их геопозиции.\n"
    bot.send_message(user_id, instructions)
    logger.info(f'User {user_id} started interaction with the bot')

@bot.message_handler(commands=['poisk'])
def poisk(message):
    user_id = message.chat.id
    if user_id not in users:
        users[user_id] = {
            'lat': None,
            'long': None,
            'region': None,
            'fuel': None,
            'fuel_type': None,
            'zapravka': None,
            'page': 0
        }
        logger.info(f'New user registered with user_id={user_id}')

    markup = types.ReplyKeyboardMarkup(resize_keyboard=True)
    location_button = types.KeyboardButton("Отправить местоположение", request_location=True)
    markup.add(location_button)

    bot.send_message(user_id, "Чтобы найти ближайшие заправки, нажмите кнопку ниже:", reply_markup=markup)
    logger.info(f'User {user_id} started interaction with the bot')

@bot.callback_query_handler(func=lambda call: call.data == "send_location")
def send_location(call):
    user_id = call.message.chat.id
    bot.send_message(user_id, "Отправьте ваше местоположение, чтобы найти ближайшие заправки.",
                     reply_markup=types.ReplyKeyboardRemove(selective=True))
    bot.send_location(user_id, latitude=0.0, longitude=0.0)  # Это пример координат

@bot.message_handler(content_types=['location'])
def handle_location(message):
    user_id = message.chat.id
    users[user_id]['lat'] = message.location.latitude
    users[user_id]['long'] = message.location.longitude
    region_buttons = [
        telebot.types.InlineKeyboardButton(title, callback_data=title)
        for title in df['REGION'].unique()
    ]
    markup = telebot.types.InlineKeyboardMarkup()
    markup.add(*region_buttons)
    bot.send_message(user_id, 'Выберите ваш регион:', reply_markup=markup)
    logger.info(f'User {user_id} sent their location')

@bot.callback_query_handler(func=lambda call: call.data in df['NEFTEPRODUKT_VID'].unique())
def choose_fuel_type(call):
    user_id = call.message.chat.id
    users[user_id]['fuel_type'] = call.data
    df_filter = df[
        (df['NEFTEPRODUKT_NAME'] == users[user_id]['fuel']) &
        (df['NEFTEPRODUKT_VID'] == users[user_id]['fuel_type']) &
        (df['REGION'] == users[user_id]['region']) &
        (df['PROC'] > 0.30)
    ]
    new_df = calc_distances(users[user_id]['lat'], users[user_id]['long'], df_filter, 'Latitude', 'Longitude', 'AZS')
    new_df = new_df[['AZS', 'Address', 'Latitude', 'Longitude', 'distance']].sort_values('distance', ascending=True)
    users[user_id]['zapravka'] = new_df.to_dict('records')
    users[user_id]['page'] = 0

    send_next_page(user_id)

def send_next_page(user_id):
    start_idx = users[user_id]['page'] * 5
    end_idx = start_idx + 5
    zapravki = users[user_id]['zapravka'][start_idx:end_idx]

    output = f"Ваш выбор: {users[user_id]['fuel_type']} {users[user_id]['fuel']}\n\nБлижайшие заправки:\n"

    for x in zapravki:
        output += f"{x['AZS']}\n{x['Address']}\nДистанция в км: {round(x['distance'], 1)}\n\n"

    markup = telebot.types.InlineKeyboardMarkup()
    if end_idx < len(users[user_id]['zapravka']):
        markup.add(telebot.types.InlineKeyboardButton(text="Показать следующие 5 заправок", callback_data="next_page"))

    for x in zapravki:
        bot.send_venue(user_id, x['Latitude'], x['Longitude'], x['AZS'], x['Address'])

    bot.send_message(user_id, output, parse_mode='Markdown', reply_markup=markup)

@bot.callback_query_handler(func=lambda call: call.data == "next_page")
def show_next_page(call):
    user_id = call.message.chat.id
    users[user_id]['page'] += 1
    send_next_page(user_id)

@bot.callback_query_handler(func=lambda call: call.data in df[df['REGION'] == users[call.message.chat.id]['region']]['NEFTEPRODUKT_NAME'].unique())
def choose_fuel(call):
    user_id = call.message.chat.id  # Получаем user_id из call.message
    users[user_id]['fuel'] = call.data
    fuel_buttons = [
        telebot.types.InlineKeyboardButton(title, callback_data=title)
        for title in df[(df['REGION'] == users[user_id]['region']) & (df['NEFTEPRODUKT_NAME'] == users[user_id]['fuel'])]['NEFTEPRODUKT_VID'].unique()
    ]
    markup = telebot.types.InlineKeyboardMarkup()
    markup.add(*fuel_buttons)
    bot.edit_message_text('Выберите вид топлива: \n 📛 Продажа топлива регулируется АЗС!', user_id, call.message.message_id, reply_markup=markup)
    logger.info(f'User {user_id} chose fuel: {call.data}')

@bot.callback_query_handler(func=lambda call: call.data in df['REGION'].unique())
def choose_region(call):
    user_id = call.message.chat.id
    users[user_id]['region'] = call.data
    fuel_buttons = [
        telebot.types.InlineKeyboardButton(title, callback_data=title)
        for title in df[df['REGION'] == users[user_id]['region']]['NEFTEPRODUKT_NAME'].unique()
    ]
    markup = telebot.types.InlineKeyboardMarkup()
    markup.add(*fuel_buttons)
    bot.edit_message_text('Выберите вид топлива: \n 📛 Продажа топлива регулируется АЗС!', user_id, call.message.message_id, reply_markup=markup)
    logger.info(f'User {user_id} chose region: {call.data}')

bot.polling()


def solution(q, r, code):
    answer = ''
    for i in range(len(code)) :
        if i % q == r :
            answer += code[i]
    return answer

#한 수 배우는 코드
'''

def solution(q, r, code):
    return code[r::q]

-- 코드 댓글

봐도 이해가 잘 안되긴함..

문자열 code의 index를 q로 나누면 q-1까지의 나머지가 q간격으로 반복되니 target 나머지가 곧 시작 index가 되고 그걸 code의 끝까지 q간격으로 반환하는거나 다름없습니다.
index = x * q + r 임을 알 수 있고, 우리가 필요한 index는 [0q+r, 1q+r, 2q+r... xq+r]입니다. 즉 [r, q+r, 2q+r... xq+r]임을 알 수있고, r로 시작해서 q씩 커지는 index만 가져오면 됩니다.

'''


import boto3
import logging
import traceback

logging.getLogger('botocore').setLevel(logging.CRITICAL)

from pathlib import Path
from botocore.config import Config
from botocore.exceptions import ClientError

from config.settings import B2_APPKEY_RW, B2_BUCKET_IMAGES, B2_ENDPOINT, B2_KEYID_RW

# Return a boto3 resource object for B2 service
def get_b2_resource(endpoint, key_id, application_key):
    return boto3.resource(service_name='s3',
                        endpoint_url=endpoint,     # Backblaze endpoint
                        aws_access_key_id=key_id,  # Backblaze keyID
                        aws_secret_access_key=application_key,  # Backblaze applicationKey
                        config=Config(signature_version='s3v4'))

def get_b2_client(endpoint, keyID, applicationKey):
        b2_client = boto3.client(service_name='s3',
                                 endpoint_url=endpoint,                # Backblaze endpoint
                                 aws_access_key_id=keyID,              # Backblaze keyID
                                 aws_secret_access_key=applicationKey) # Backblaze applicationKey
        return b2_client

def get_client():
    return get_b2_client(B2_ENDPOINT, B2_KEYID_RW, B2_APPKEY_RW)

def get_image_bucket():
    return get_b2_resource(B2_ENDPOINT, B2_KEYID_RW, B2_APPKEY_RW).Bucket(B2_BUCKET_IMAGES)

def upload_image(fileobj, file_name, extra_args=None):
    get_image_bucket().upload_fileobj(
        fileobj,
        file_name,
        ExtraArgs=extra_args
    )

# Upload specified file into the specified bucket
def upload_file(b2, fileobj, bucket, b2_path, extra_args=None):
    b2.Bucket(bucket).upload_fileobj(
        fileobj,
        b2_path,
        ExtraArgs=extra_args
    )

def download_file(b2, bucket, directory, local_name, key_name):
    file_path = directory + '/' + local_name
    try:
        b2.Bucket(bucket).download_file(key_name, file_path)
    except ClientError as ce:
        print('error', ce)

if __name__=='__main__':
    import os
    import environ
    from pathlib import Path
    # Build paths inside the project like this: BASE_DIR / 'subdir'.
    BASE_DIR = Path(__file__).resolve().parent.parent
    # Take environment variables from .env file
    env = environ.Env()
    environ.Env.read_env(os.path.join(BASE_DIR, '.env'))

    # # Possible override of settings to test
    # B2_KEYID_RW=''
    # B2_APPKEY_RW=''
    # B2_ENDPOINT=''
    # B2_BUCKET_IMAGES=''

    b2 = get_b2_resource(B2_ENDPOINT, B2_KEYID_RW, B2_APPKEY_RW)
    c = get_b2_client(B2_ENDPOINT, B2_KEYID_RW, B2_APPKEY_RW)

    import IPython
    IPython.embed()


from discord.ext import commands
import discord
import random
import gifs
import main

@commands.command(
    brief=f"{main.prefix}hug nickogólnydiscorda - przytulasz wybranego użytkownika gifem"
  )
async def hug(ctx, user: discord.Member):

    embed = discord.Embed(
        title = "",
        description = f"{ctx.author.mention} przytula {user.mention}!",
      #mention to oznaczenie/ping
        color = ctx.author.color
    )

    randomgif = random.choice(gifs.hug)
    embed.set_image(url = randomgif)
    await ctx.send(embed = embed)

async def setup(bot):
  bot.add_command(hug)


import os
from sklearn.metrics import accuracy_score
from tqdm import tqdm

import torch
from torchvision import datasets, transforms
from dataset import TrainDataset
from torch.optim.lr_scheduler import MultiStepLR
import os
import nni
from nni.compression.pytorch.pruning import AutoCompressPruner, FPGMPruner
from nni.compression.pytorch.utils import count_flops_params
from nni.compression.pytorch import ModelSpeedup
from torchvision.models.mobilenetv2 import *
from torchvision.models.mobilenetv3 import *
from lenet import LeNet
import pandas as pd

device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

COLOR = 'G'
SIZE = 32
PATH = "D:\HUST\CH-Motor_Research\Testbench data\Data_augument\IMF1"

train_set = TrainDataset(PATH, COLOR, SIZE, 'train')
train_loader = torch.utils.data.DataLoader(train_set, batch_size=128, shuffle=True)
test_set = TrainDataset(PATH, COLOR, SIZE, 'test')
test_loader = torch.utils.data.DataLoader(test_set, batch_size=128, shuffle=True)

criterion = torch.nn.CrossEntropyLoss()

epoch = 0

def trainer(model, optimizer, criterion):
    print('[LOG]: trainer')
    global epoch
    model.train()
    total_loss = 0
    total_size = 0
    for data, target in tqdm(iterable=train_loader, desc='Total Epoch {}'.format(epoch)):
        data, target = data.to(device), target.to(device)
        optimizer.zero_grad()
        output = model(data)
        loss = criterion(output, target)
        total_loss += loss.item()*data.size(0)
        loss.backward()
        optimizer.step()
        total_size += data.size(0)
    epoch = epoch + 1
    return total_loss/total_size

def finetuner(model):
    print('[LOG]: finetuner')
    optimizer = torch.optim.SGD(model.parameters(), lr=0.002, momentum=0.9, weight_decay=5e-4)
    criterion = torch.nn.CrossEntropyLoss()
    for i in range(10):
        trainer(model, optimizer, criterion)

def evaluator(model):
    print('[LOG]: evaluator')
    model.eval()
    correct = 0
    with torch.no_grad():
        for data, target in tqdm(iterable=test_loader, desc='Test'):
            data, target = data.to(device), target.to(device)
            output = model(data)
            pred = output.argmax(dim=1, keepdim=True)
            correct += pred.eq(target.view_as(pred)).sum().item()
    acc = 100 * correct / len(test_loader.dataset)
    print('Accuracy: {}%\n'.format(acc))
    return acc

if __name__ == '__main__':
    model = mobilenet_v3_small(n_class=10, width_mult=0.05).to(device)

    model.load_state_dict(torch.load('D:\HUST\CH-Motor_Research\Code\IBFD_MobileNetV3_AutoCompress\epochs\\22061012\epoch_22061012_78.pth'))
    config_list = [{'op_types': ['Linear', 'Conv2d'], 'total_sparsity': 0.1}]

    # make sure you have used nni.trace to wrap the optimizer class before initialize
    traced_optimizer = nni.trace(torch.optim.SGD)(model.parameters(), lr=0.002, momentum=0.9, weight_decay=5e-4)
    admm_params = {
        'trainer': trainer,
        'traced_optimizer': traced_optimizer,
        'criterion': criterion,
        'iterations': 5,
        'training_epochs': 5
    }
    sa_params = {
        'evaluator': evaluator
    }
    pruner = AutoCompressPruner(model, config_list, 1, admm_params, sa_params, keep_intermediate_result=True)
    print('[LOG]: compress')
    pruner.compress()
    _, model, masks, _, _ = pruner.get_best_result()
    evaluator(model)


""" Core definition of a Molecule Document """
from typing import Any, Dict, List, Mapping, Union

from pydantic import Field

from pymatgen.core.structure import Molecule
from pymatgen.analysis.molecule_matcher import MoleculeMatcher

from emmet.core.mpid import MPID
from emmet.core.settings import EmmetSettings
from emmet.core.material import MoleculeDoc as CoreMoleculeDoc
from emmet.core.material import PropertyOrigin
from emmet.core.structure import MoleculeMetadata
from emmet.core.qchem.calc_types import CalcType, LevelOfTheory, TaskType
from emmet.core.qchem.task import TaskDocument

__author__ = "Evan Spotte-Smith <ewcspottesmith@lbl.gov>"

SETTINGS = EmmetSettings()

def evaluate_lot(
    lot: Union[LevelOfTheory, str],
    funct_scores: Dict[str, int] = SETTINGS.QCHEM_FUNCTIONAL_QUALITY_SCORES,
    basis_scores: Dict[str, int] = SETTINGS.QCHEM_BASIS_QUALITY_SCORES,
    solvent_scores: Dict[str, int] = SETTINGS.QCHEM_SOLVENT_MODEL_QUALITY_SCORES,
):
    """
    Score the various components of a level of theory (functional, basis set,
    and solvent model), where a lower score is better than a higher score.

    :param lot: Level of theory to be evaluated
    :param funct_scores: Scores for various density functionals
    :param basis_scores: Scores for various basis sets
    :param solvent_scores: Scores for various implicit solvent models
    :return:
    """

    if isinstance(lot, LevelOfTheory):
        lot_comp = lot.value.split("/")
    else:
        lot_comp = lot.split("/")

    return (
        -1 * funct_scores.get(lot_comp[0], 0),
        -1 * basis_scores.get(lot_comp[1], 0),
        -1 * solvent_scores.get(lot_comp[2].split("(")[0], 0),
    )

def evaluate_task(
    task: TaskDocument,
    funct_scores: Dict[str, int] = SETTINGS.QCHEM_FUNCTIONAL_QUALITY_SCORES,
    basis_scores: Dict[str, int] = SETTINGS.QCHEM_BASIS_QUALITY_SCORES,
    solvent_scores: Dict[str, int] = SETTINGS.QCHEM_SOLVENT_MODEL_QUALITY_SCORES,
    task_quality_scores: Dict[str, int] = SETTINGS.QCHEM_TASK_QUALITY_SCORES,
):
    """
    Helper function to order optimization calcs by
    - Level of theory
    - Electronic energy

    Note that lower scores indicate a higher quality.

    :param task: Task to be evaluated
    :param funct_scores: Scores for various density functionals
    :param basis_scores: Scores for various basis sets
    :param solvent_scores: Scores for various implicit solvent models
    :param task_quality_scores: Scores for various task types
    :return:
    """

    lot = task.level_of_theory

    lot_eval = evaluate_lot(
        lot,
        funct_scores=funct_scores,
        basis_scores=basis_scores,
        solvent_scores=solvent_scores,
    )

    return (
        -1 * int(task.is_valid),
        sum(lot_eval),
        -1 * task_quality_scores.get(task.task_type.value, 0),
        task.output.final_energy,
    )

class MoleculeDoc(CoreMoleculeDoc, MoleculeMetadata):

    calc_types: Mapping[str, CalcType] = Field(  # type: ignore
        None,
        description="Calculation types for all the calculations that make up this molecule",
    )
    task_types: Mapping[str, TaskType] = Field(
        None,
        description="Task types for all the calculations that make up this molecule",
    )
    levels_of_theory: Mapping[str, LevelOfTheory] = Field(
        None,
        description="Levels of theory types for all the calculations that make up this material",
    )

    origins: List[PropertyOrigin] = Field(
        None,
        description="List of property origins for tracking the provenance of properties",
    )

    entries: List[Dict[str, Any]] = Field(
        None,
        description="Dictionary representations of all task documents for this molecule",
    )

    best_entries: Mapping[LevelOfTheory, Dict[str, Any]] = Field(
        None,
        description="Mapping for tracking the best entries at each level of theory for Q-Chem calculations",
    )

    similar_molecules: List[MPID] = Field(
        None,
        description="List of MPIDs with of molecules similar (by e.g. structure) to this one",
    )

    @classmethod
    def from_tasks(
        cls,
        task_group: List[TaskDocument],
    ) -> "MoleculeDoc":

        """
        Converts a group of tasks into one molecule document

        Args:
            task_group: List of task document
        """
        if len(task_group) == 0:
            raise Exception("Must have more than one task in the group.")

        entries = [t.entry for t in task_group]

        # Metadata
        last_updated = max(task.last_updated for task in task_group)
        created_at = min(task.last_updated for task in task_group)
        task_ids = list({task.task_id for task in task_group})

        deprecated_tasks = {task.task_id for task in task_group if not task.is_valid}
        levels_of_theory = {task.task_id: task.level_of_theory for task in task_group}
        task_types = {task.task_id: task.task_type for task in task_group}
        calc_types = {task.task_id: task.calc_type for task in task_group}

        mols = [task.output.initial_molecule for task in task_group]

        # If we're dealing with single-atoms, process is much different
        if all([len(m) == 1 for m in mols]):
            sorted_tasks = sorted(task_group, key=evaluate_task)

            molecule_id = sorted_tasks[0].task_id

            molecule = sorted_tasks[0].output.initial_molecule

            # Initial molecules. No geometry should change for a single atom
            initial_molecules = [molecule]

            # Deprecated
            deprecated = all(task.task_id in deprecated_tasks for task in task_group)

            # Origins
            origins = [
                PropertyOrigin(
                    name="molecule",
                    task_id=molecule_id,
                    last_updated=sorted_tasks[0].last_updated,
                )
            ]

            # entries
            best_entries = {}
            all_lots = set(levels_of_theory.values())
            for lot in all_lots:
                relevant_calcs = sorted(
                    [doc for doc in task_group if doc.level_of_theory == lot and doc.is_valid],
                    key=evaluate_task,
                )

                if len(relevant_calcs) > 0:
                    best_task_doc = relevant_calcs[0]
                    entry = best_task_doc.entry
                    entry["task_id"] = entry["entry_id"]
                    entry["entry_id"] = molecule_id
                    best_entries[lot] = entry

        else:
            geometry_optimizations = [
                task
                for task in task_group
                if task.task_type
                in [TaskType.Geometry_Optimization, TaskType.Frequency_Flattening_Geometry_Optimization]  # noqa: E501
            ]

            # Molecule ID
            possible_mol_ids = [task.task_id for task in geometry_optimizations]

            molecule_id = min(possible_mol_ids)

            best_molecule_calc = sorted(geometry_optimizations, key=evaluate_task)[0]
            molecule = best_molecule_calc.output.optimized_molecule

            # Initial molecules
            initial_molecules = list()
            for task in task_group:
                if isinstance(task.orig["molecule"], Molecule):
                    initial_molecules.append(task.orig["molecule"])
                else:
                    initial_molecules.append(Molecule.from_dict(task.orig["molecule"]))

            mm = MoleculeMatcher()
            initial_molecules = [group[0] for group in mm.group_molecules(initial_molecules)]

            # Deprecated
            deprecated = all(task.task_id in deprecated_tasks for task in geometry_optimizations)
            deprecated = deprecated or best_molecule_calc.task_id in deprecated_tasks

            # Origins
            origins = [
                PropertyOrigin(
                    name="molecule",
                    task_id=best_molecule_calc.task_id,
                    last_updated=best_molecule_calc.last_updated,
                )
            ]

            # entries
            best_entries = {}
            all_lots = set(levels_of_theory.values())
            for lot in all_lots:
                relevant_calcs = sorted(
                    [doc for doc in geometry_optimizations if doc.level_of_theory == lot and doc.is_valid],
                    key=evaluate_task,
                )

                if len(relevant_calcs) > 0:
                    best_task_doc = relevant_calcs[0]
                    entry = best_task_doc.entry
                    best_entries[lot] = entry

        for entry in entries:
            entry["entry_id"] = molecule_id

        return cls.from_molecule(
            molecule=molecule,
            molecule_id=molecule_id,
            initial_molecules=initial_molecules,
            last_updated=last_updated,
            created_at=created_at,
            task_ids=task_ids,
            calc_types=calc_types,
            levels_of_theory=levels_of_theory,
            task_types=task_types,
            deprecated=deprecated,
            deprecated_tasks=deprecated_tasks,
            origins=origins,
            entries=entries,
            best_entries=best_entries,
        )

    @classmethod
    def construct_deprecated_molecule(
        cls,
        task_group: List[TaskDocument],
    ) -> "MoleculeDoc":
        """
        Converts a group of tasks into a deprecated molecule document

        Args:
            task_group: List of task document
        """
        if len(task_group) == 0:
            raise Exception("Must have more than one task in the group.")

        # Metadata
        last_updated = max(task.last_updated for task in task_group)
        created_at = min(task.last_updated for task in task_group)
        task_ids = list({task.task_id for task in task_group})

        deprecated_tasks = {task.task_id for task in task_group}
        levels_of_theory = {task.task_id: task.level_of_theory for task in task_group}
        task_types = {task.task_id: task.task_type for task in task_group}
        calc_types = {task.task_id: task.calc_type for task in task_group}

        # Molecule ID
        molecule_id = min([task.task_id for task in task_group])

        # Choose any random structure for metadata
        molecule = task_group[0].output.initial_molecule

        # Deprecated
        deprecated = True

        return cls.from_molecule(
            molecule=molecule,
            molecule_id=molecule_id,
            last_updated=last_updated,
            created_at=created_at,
            task_ids=task_ids,
            calc_types=calc_types,
            levels_of_theory=levels_of_theory,
            task_types=task_types,
            deprecated=deprecated,
            deprecated_tasks=deprecated_tasks,
        )

def best_lot(
    mol_doc: MoleculeDoc,
    funct_scores: Dict[str, int] = SETTINGS.QCHEM_FUNCTIONAL_QUALITY_SCORES,
    basis_scores: Dict[str, int] = SETTINGS.QCHEM_BASIS_QUALITY_SCORES,
    solvent_scores: Dict[str, int] = SETTINGS.QCHEM_SOLVENT_MODEL_QUALITY_SCORES,
) -> LevelOfTheory:
    """

    Return the best level of theory used within a MoleculeDoc

    :param mol_doc: MoleculeDoc
    :param funct_scores: Scores for various density functionals
    :param basis_scores: Scores for various basis sets
    :param solvent_scores: Scores for various implicit solvent models

    :return: LevelOfTheory
    """

    sorted_lots = sorted(
        mol_doc.best_entries.keys(),
        key=lambda x: evaluate_lot(x, funct_scores, basis_scores, solvent_scores),
    )

    return sorted_lots[0]


"""unittests for analytics.filters.email"""

import builtins
import pdb
from pprint import pprint
import unittest

from tahoe.tests.identity.test_backend import setUpBackend, tearDownBackend

if __name__ != 'analytics.tests.filters.test_email':
    import sys, os
    J = os.path.join
    sys.path = ['..', J('..','..'), J('..','..','..')] + sys.path
    del sys, os

from filters import set_filter_backend, Email

def make_test_data():
    with open('email.txt', 'r') as fp:
        builtins.email_str = fp.read()

    builtins.orgid = 'ABC123'
    builtins.timezone = 'US/Pacific'

def delete_test_data():
    del builtins.email_str, builtins.orgid, builtins.timezone

def setUpModule():
    builtins._backend = setUpBackend()
    set_filter_backend(_backend)

def tearDownModule():
    tearDownBackend(_backend)
    del builtins._backend

class EmailTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        _backend.drop()
        make_test_data()

    @classmethod
    def tearDownClass(cls):
        delete_test_data()

    def test_01(self):
        e = Email()
        raw_ref = e.parse(email_str, orgid, timezone)
        e = _backend.find_one({'itype':'event'})

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


# -*- coding: utf-8 -*-
import itasca as it
from ..customDecorators import *
from ..model.abstractSubUtility import AbstractSubUtility
from boltRing import BoltRing
from .. import globalContainer as gc

__all__ = ['BoltUtility']

class BoltUtility(AbstractSubUtility):
    """
    FLAC3D 6.0 锚杆实用工具。
    锚杆由BoltUtil的实例管理，并向下分为BoltRing——>BoltGroup。
    """

    def __init__(self, model=None):
        super(BoltUtility, self).__init__(model)

    def newBoltRing(self, y_Bound_Global, spacing, id='default'):
        if id == 'default':
            id = 900
        boltRing = BoltRing(y_Bound_Global, spacing, id, self)
        self.addRing(boltRing)
        return boltRing

    @staticmethod
    def applyBolt_ByLine(beginPos, endPos, n_Seg, eid):
        it.command(
            'structure cable create by-line {positionPhrase} segments {_nseg} id {id}'.format(
                positionPhrase='{x0} {y0} {z0} {x1} {y1} {z1}'.format(
                    x0=beginPos[0], y0=beginPos[1], z0=beginPos[2],
                    x1=endPos[0], y1=endPos[1], z1=endPos[2]
                ),
                _nseg=n_Seg,
                id=eid
            )
        )

    @y_Bound_Detect('y_Bound')
    def applyBolt_YRange(self, y_Bound, groups='All'):
        for b_r in self.rings:
            b_r.applyBolt_YRange_Ring(y_Bound, groups)

    @n_Step_Detect
    def applyBolt_Step(self, n_Step, groups='All'):
        for b_r in self.rings:
            b_r.applyBolt_YRange_Ring(self.modelUtil.excaUtil.y_BoundList[n_Step], groups)


import numpy as np
import copy

def prepare_etalon(S1, S2, n1, n2):
    s1 = copy.deepcopy(S1)
    s2 = copy.deepcopy(S2)
    distance, summary_dist = calc_dist(n1, n2, s1, s2)

    max_val, max_index, min_val, min_index = find_min_max(distance, summary_dist)
    # Сформировать множество объектов U
    u = create_array_etalon(n1, s1, s2, max_index, min_index, min_val)

    s1 = dif_two_array(s1, u)
    # пока выборка не закончена,повторяем алгоритм
    while np.size(s1) != 0:
        distance, summary_dist = calc_dist(np.size(s1, 0), n2, s1, s2)
        max_val, max_index, min_val, min_index = find_min_max(distance, summary_dist)
        u2 = create_array_etalon(n1=np.size(s1, 0), s1=s1, s2=s2, max_index=max_index,
                                 min_index=min_index, min_val=min_val)

        for row in range(0, np.size(u, 0) - np.size(u2, 0)):
            u2 = np.vstack((u2, [0, 0]))
        for row in range(0, np.size(u2, 0) - np.size(u, 0)):
            u = np.vstack((u, np.zeros((1, u.shape[1]))))
        u_end = np.concatenate((u, u2), axis=1)
        u = u_end
        s1 = dif_two_array(s1, u_end[:, u_end.shape[1] - 2:u_end.shape[1]])
    return u

def calc_dist(n1, n2, s1, s2):
    distance = np.zeros(shape=(n1, n2))
    summary_dist = np.zeros(shape=(n1, 1))
    for i in range(0, n1):
        for j in range(0, n2):
            distance[i, j] = np.math.sqrt((s1[i, 0] - s2[j, 0]) ** 2 +
                                          (s1[i, 1] - s2[j, 1]) ** 2)
        summary_dist[i] = sum(distance[i])
    return distance, summary_dist

def find_min_max(distance, summary_distance):
    max_val = np.amax(summary_distance)  # центр 1-го эталона класса
    max_index = np.argmax(summary_distance)
    min_val = np.amin(distance[max_index, :])  # центр конкурирующего
    min_index = np.argmin(distance[max_index, :])
    return max_val, max_index, min_val, min_index

def create_array_etalon(n1, s1, s2, max_index, min_index, min_val):
    u = np.zeros([1, 2])
    for i in range(0, n1):
        rroj = np.math.sqrt((s1[max_index, 0] - s1[i, 0]) ** 2 +
                            (s1[max_index, 1] - s1[i, 1]) ** 2)
        rroc = np.math.sqrt((s2[min_index, 0] - s1[i, 0]) ** 2 +
                            (s2[min_index, 1] - s1[i, 1]) ** 2)
        if rroj < rroc and rroj <= min_val:
            a = s1[i, :].reshape((1, 2))
            u = np.concatenate((u, a))
    u = np.delete(u, 0, 0)
    return u

def etalon(u):
    leng = 0
    l = []
    for i in range(0, np.size(u, 1), 2):
        for j in range(0, np.size(u, 0)):
            if u[j, i] != 0.0 and u[j, i] != 0.0:
                leng = leng + 1
        l = np.append(l, leng)
        leng = 0
    x0 = []
    y0 = []
    for i in range(0, np.size(u, 1), 2):
        x0 = np.append(x0, np.sum(u[:, i] / l[int(i / 2 + 0.5)]))
        y0 = np.append(y0, np.sum(u[:, i + 1] / l[int(i / 2 + 0.5)]))
    return x0, y0, l

def control_element(M, Sig, z):
    c_e = []
    while np.size(c_e) != z:
        c = M + Sig * np.random.randn(1, 1)
        c_e = np.append(c_e, c)
    return c_e

def clean_etalon(L, X, Y):
    index_list = []
    i = 0
    for v in L:
        if v == 0 or v == 0.0:
            index_list.append(i)
        i += 1
    l = np.delete(L, index_list)
    x = np.delete(X, index_list)
    y = np.delete(Y, index_list)
    return l, x, y

def FRis_function(X01, Y01, X02, Y02, c_x, c_y, disp_1, disp_2):
    control_res1 = []
    control_res2 = []
    for i in range(0, X01.shape[0]):
        val_1 = np.math.sqrt(
            (X01[i] - c_x) ** 2 + (Y01[i] - c_y) ** 2
        )
        control_res1 = np.append(control_res1, val_1)
    for j in range(0, X02.shape[0]):
        val_2 = np.math.sqrt(
            (X02[j] - c_x) ** 2 + (Y02[j] - c_y) ** 2
        )
        control_res2 = np.append(control_res2, val_2)
    min_c1 = np.amin(control_res1)
    min_c2 = np.amin(control_res2)
    # сходство С1 с А в конкуренции с В
    factor_f_1 = (min_c2 - min_c1) / (min_c2 - min_c1)
    # factor_f_1 = (min_c2 * disp_1 - min_c1 * disp_2) / (min_c2 * disp_2 - min_c1 * disp_1)
    # сходство С1 с B  в конкуренции с А
    factor_f_2 = (min_c1 - min_c2) / (min_c1 - min_c2)
    # factor_f_2 = (min_c1 * disp_2 - min_c2 * disp_1) / (min_c1 * disp_2 - min_c2 * disp_1)

    if factor_f_1 > 0:
        return 1
    if factor_f_2 > 0:
        return 2

def dif_two_array(ar1, ar2):
    ret_ar = []
    for i in range(0, ar1.shape[0]):
        for j in range(0, ar2.shape[0]):
            if ar1[i, 0] == ar2[j, 0]:
                ret_ar.append(i)
    ret_ar = np.delete(ar1, ret_ar, axis=0)
    return ret_ar

def is_member(A, B):
    return [np.sum(a == B) for a in A]